How can I define a function that takes a list of reals?

I’m trying to define a function f which takes a list of reals. My purpose is to build a function which I can give a list of reals, integers or strings and have it build an appropriate probability distribution for.

So I’d like to do something like

f[{samples_Real}]:=makeRealDist[samples];
f[{samples_Integer}]:=makeInteger[samples];
f[{samples_String}]:=makeCategoricalDist[samples];

I can easily match on Real/Integer/Strings.
The part I can’t figure out is how to match on a list of Real/Integer/String.

=================

1

 

Almost there! f[{samples__Real}] or f[samples:{__Real}]
– mfvonh
Jun 24 ’14 at 4:02

  

 

That seems about right for what I want, thank you! I was close. However, samples is then treated as a “Squence[samples]”, I was expecting just a list of reals/integers/strings like {1.0, 2.0, 3.0}. I’m obviously missing something in my understanding, any pointers to what that might be? I’m hoping to pass this list on to my makeRealDist function…
– Steven
Jun 24 ’14 at 4:13

  

 

The second option will give you a list.
– mfvonh
Jun 24 ’14 at 4:15

  

 

You can also use Repeated (..), but here BlankSequence (__) is simpler.
– mfvonh
Jun 24 ’14 at 4:20

2

 

Are you sure you want Real? This way 3 will be rejected, but 3. will be accepted. Why not check for NumericQ? but may be you really want Real.
– Nasser
Jun 24 ’14 at 4:26

=================

1 Answer
1

=================

I feel that the basics of this topic are well covered in my answer to:

Can a function be made to accept a variable amount of inputs?

Once you have read that and understand BlankSequence, Repeated, and Pattern you will understand that you could use either of these:

f1[samples : {__Real}] := makeRealDist[samples]
f2[samples : {_Real ..}] := makeRealDist[samples]

If you wish to permit integers, fractions, etc, you can use NumberQ or perhaps even NumericQ.
Viable semantics include:

f3[samples_List] /; VectorQ[samples, NumberQ] := makeRealDist[samples]
f4[samples : {__?NumberQ}] := makeRealDist[samples]

Timings will show that the first forms (f1 and f3) are to be preferred:

SetAttributes[timeAvg, HoldFirst]
timeAvg[func_] := Do[If[# > 0.3, Return[#/5^i]] & @@ Timing@Do[func, {5^i}], {i, 0, 15}]

packed = Range[1, 1000, 0.0001];
timeAvg @ #[packed] & /@ {f1, f2, f3, f4}

{3.67616*10^-7, 0.1404, 5.59104*10^-7, 1.201}

  

 

Blacksequence? That sure soundeth sinister, nay, eldritch even. Goes well with your username, too 😀
– Yves Klett
Jun 24 ’14 at 7:45

  

 

@Yves You mean you don’t mutter dark incantations as you code? :o)
– Mr.Wizard♦
Jun 24 ’14 at 15:41

1

 

Well, more like PEGI 18 obscenities, at times. But they most assuredly do not help with the code as such. Hmm, worth a try. Now where did I put my Necronomicon again? Ah… right next to my NKS special edition and the Laundry files 😀
– Yves Klett
Jun 24 ’14 at 16:03

  

 

f1[samples : {__Real}] := makeRealDist[samples] Reads cleanest to me, and has a benefit of being quite fast. Thank you all who helped.
– Steven
Jun 25 ’14 at 18:57

  

 

@user159805 You are welcome for my part. If you find this answer fully satisfactory please consider Accepting it. Also please consider choosing a more “human” username.
– Mr.Wizard♦
Jun 25 ’14 at 22:25