1
$\begingroup$

I have a function which takes real numbers as inputs:

MyFunc:=[v1_,v2_,v3_,v4_]

and outputs a single real number. Now I want to evaluate MyFunc for many different combinations of input values of v1, v2, v3 and v4.

Let's assume my input values are:

v1 = {1,2.5,3,4}
v2 = {4,2}
v3 = {0.5,1}
v4 = {0.9,0.92,0.94}

Now I want to input each combination of the different values of the variables and input it in MyFunc. Then, for each set of input values I want to store them in a list, along with the output values.

So let's say MyFunc[1,4,0.5,0.9] outputs a value of 0.68, I want to store this in a list: {1,4,0.5,0.9,0.68}, where the first four values or the input values and the last value is the output value.

I know how to do this sequentially:

combinations = Tuples[{v1, v2, v3, v4}]
outputs = Flatten[MyFunc @@@ combinations];

And then I parse combinations and outputs

results = MapThread[Append, {"combinations", "outputs"}];

Now I have set up Mathematica on a server with 32 cores, so I would like to take advantage of this by parallelizing my task. I know how to parallelize things using Table, but it is important that the correct output is appended to the corresponding input values. Since things are happening on different Kernels, I have no clue how to parallelize my job producing the output results I want.

$\endgroup$
  • $\begingroup$ Note also that a very simple trick to "manage" matching input and output in general, is to either make myFunc return exactly that, instead of just a number, or to make a wrapper function myFunc2[v1_,v2_,v3_,v4_] := {v1,v2,v3,v4,myFunc[v1,v2,v3,v4]} and Map or Table that instead. That also saves you from the very costly Append thing you seem to be doing; Append has high complexity in Mathematica so one should avoid using it for long lists. $\endgroup$ – Marius Ladegård Meyer Aug 19 '17 at 13:58
2
$\begingroup$

You may use ParallelMap. Note that Mathematica preserves the order of the items return when using its Parallel* functions so you do not need to manage this. Se the Parallel Computing guide.

With v1, v2, v3, and v4 as defined in the OP.

tups = Tuples[{v1, v2, v3, v4}];

No definition is given for myFunc so I use Plus here.

myFunc = Plus;
LaunchKernels[];
res = ParallelMap[{Sequence @@ ##, myFunc @@ ##} &, tups];

A quick look shows all is well.

res[[1 ;; 4]]
{{1,4,0.5,0.9,6.4},{1,4,0.5,0.92,6.42},
   {1,4,0.5,0.94,6.44},{1,4,1,0.9,6.9}}

LaunchKernels is not strictly needed as ParallelMap will launch but you have so many cores that I used it as a placeholder for any special setup you may have.

Hope this helps.

$\endgroup$
  • $\begingroup$ When I use your approach, I get output results like > {variables_input_values, -921.923 (0.0456039 + 0.797885 (3.08022 (0.0417715 + 0.262132 {0.4, 0.5} ))), so I think the function cannot handle the input in the way you have described above. MyFunc is the function callOR from the Kou model, with the original code taken from columbia.edu/~sk75/webcode.txt. Could you tell me how to adapt the input in order for the function callOR to produce a single output real number? $\endgroup$ – Peter Lawrence Aug 19 '17 at 14:35
  • $\begingroup$ @PeterLawrence How have you loaded the callOR function? myFunc @@ ## replaces the Head of List on each list with myFunc. That is {1,2} becomes myFunc[1, 2]. $\endgroup$ – Edmund Aug 19 '17 at 14:42
  • $\begingroup$ My bad, callOR produced weird results for a certain combination of input values. Everything works great, thanks for you help! $\endgroup$ – Peter Lawrence Aug 19 '17 at 15:22
  • $\begingroup$ @PeterLawrence Have you see FinancialDerivative and the other functions in the Financial Computation guide? $\endgroup$ – Edmund Aug 19 '17 at 15:28
  • 1
    $\begingroup$ @PeterLawrence That sounds like you have missed a comma between items in your list of list in Tuples. $\endgroup$ – Edmund Aug 19 '17 at 16:19

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.