4
$\begingroup$

I would like to be able to call a function an unspecified number of times. That is, I would like the generalization of something like:

   Sample[yi_, yf_, yinc_, zi_, zf_, zinc_]:=
          Table[{y, z}, {y, yi, yf, yinc}, {z, zi, zf, zinc}]

to $n$ variables, all with their own respective initial, finial and incremental values, and so I'd be calling on Table $n$ times. Is something like this even possible?

$\endgroup$
5
$\begingroup$

Something like :

sample[ranges_] := Table[Evaluate[ranges[[All, 1]]], Evaluate[Sequence @@ ranges]]

used like :

sample[{{x, 0, 3, 1}, {y, -2, 2, 1}}]
$\endgroup$
  • 2
    $\begingroup$ Or you can use ranges__ and avoid Sequence and Evaluate. $\endgroup$ – Szabolcs Mar 22 '12 at 14:20
  • $\begingroup$ I would use ranges:{{_Symbol, _?NumericQ, _?NumericQ, _?NumericQ} ..} or ranges:{_Symbol, _?NumericQ, _?NumericQ, _?NumericQ} .. which forces the user to give the correct form for the iterators. Personally, I'd use the second form of ranges as it is called like Table: sample[{x,0,3,1},{y,-2,2,1}]. Also, you'd remove the Sequence @@ shortening the code. $\endgroup$ – rcollyer Mar 22 '12 at 14:25
  • $\begingroup$ @Szabolcs Your solution is better, please feel free to edit my answer. $\endgroup$ – b.gates.you.know.what Mar 22 '12 at 14:31
  • $\begingroup$ Protecting the user by specifying the argument types is good. Note, however, that it precludes constructs in which the endpoints of some ranges depend on the values in the current range, such as {x, 0, 3, 1}, {y, 0, x, 1}. $\endgroup$ – whuber Mar 22 '12 at 15:00
  • $\begingroup$ @whuber that's true. Then remove the ?NumericQ from them which will allow the additional constructs. $\endgroup$ – rcollyer Mar 22 '12 at 15:17
2
$\begingroup$

Going by the suggested syntax in your question you might find use in this:

sample[params__] := Range @@@ Partition[{params}, 3]

This does no type checking and assumes that your params list is in threes.
I kept it simple for ease of reading.

Example:

tbl = sample[3, 12, 2, 5, 1, -1]
{{3, 5, 7, 9, 11}, {5, 4, 3, 2, 1}}

On this output could use Outer:

Outer[ff, ##] & @@ tbl
{{ff[3, 5], ff[3, 4], ff[3, 3], ff[3, 2], ff[3, 1]},
 {ff[5, 5], ff[5, 4], ff[5, 3], ff[5, 2], ff[5, 1]},
 {ff[7, 5], ff[7, 4], ff[7, 3], ff[7, 2], ff[7, 1]},
 {ff[9, 5], ff[9, 4], ff[9, 3], ff[9, 2], ff[9, 1]},
 {ff[11, 5], ff[11, 4], ff[11, 3], ff[11, 2], ff[11, 1]}}

If you allow for more flexible syntax, you might use:

Outer[ff, ##] & @@ Range @@@ {{3, 12, 2}, {5, 1, -1}, {3}}
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.