4
$\begingroup$

I am new to Mathematica's way of programming. I have a multivariable function, part of whose values are available as a list, and the remaining in another list. To illustrate, I will present my problem with an MRE.

I have a function that is defined as follows:

func[x_,y_,z_,m_,n_]:=(3x+4y+z)/(2m+n)

I have a list of values for x,y,z:

listxyz = {{1,1,1},{1,1,2},{1,1,3},{1,2,1},{1,2,2},{1,2,3},{1,3,1},{1,3,2},{1,3,3},{2,1,1},{2,1,2},{2,1,3},{2,2,1},{2,2,2},{2,2,3},{2,3,1},{2,3,2},{2,3,3},{3,1,1},{3,1,2},{3,1,3},{3,2,1},{3,2,2},{3,2,3},{3,3,1},{3,3,2},{3,3,3}}

and another list of m,n:

listmn = {{1,1},{1,2},{1,3},{2,1},{2,2},{2,3},{3,1},{3,2},{3,3}}

where I want to evaluate this function for all possible combinations of elements from listxyz and listmn.

(Note that this is a minimum reproducible example, and so the lists are smaller and less complicated than my actual case, where I have ~10-15 variables and each list has ~50-60 entries).

If all I had was a function of x,y,z I could use the Apply on func and my list to get the desired answer. How do I do this for my case where there are more terms?

Edit : Added values for the lists for ease of answering, and to clarify the question further

$\endgroup$
6
  • 2
    $\begingroup$ Can you please provide a short example of these two lists? Do you want this function to evaluate only for each pair of elements of the two lists, or for all possible pairs of the two? $\endgroup$
    – Domen
    Jan 25 at 14:41
  • $\begingroup$ I've edited the question, and I've added example lists. I want to evaluate for all possible pairs of elements from these two lists. $\endgroup$
    – haricash
    Jan 25 at 14:50
  • $\begingroup$ listxyz and listmn are different lengths. If they were the same length, we could align them and thread through them. Since they're different lengths, how do you want to combine them? $\endgroup$
    – lericr
    Jan 25 at 15:03
  • $\begingroup$ @lericr I'd like to evaluate it for all possible pairs of elements from listxyz and listmn. So that would mean 27x9=243 outputs $\endgroup$
    – haricash
    Jan 25 at 15:40
  • 1
    $\begingroup$ @haricash, the equivalent is to use Sequence. For example: f[Sequence @@ {1, 2, 3}] gives f[1, 2, 3]. $\endgroup$
    – Domen
    Jan 25 at 16:01

2 Answers 2

5
$\begingroup$

Let's simplify even more to help clarify. If our input lists were the same length, say,

listxyz = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
listmn = {{10, 11}, {12, 13}, {14, 15}};

then we could do something like this:

Apply[f] /@ Join[listxyz, listmn, 2]
(* {f[1, 2, 3, 10, 11], f[4, 5, 6, 12, 13], f[7, 8, 9, 14, 15]} *)

(I used f instead of your func to show the structure of the result.)

Or maybe you want all combinations of pairs across both input lists:

Apply[f]@*Flatten /@ Tuples[{listxyz, listmn}]
(* {f[1, 2, 3, 10, 11], f[1, 2, 3, 12, 13], f[1, 2, 3, 14, 15], 
    f[4, 5, 6, 10, 11], f[4, 5, 6, 12, 13], f[4, 5, 6, 14, 15], 
    f[7, 8, 9, 10, 11], f[7, 8, 9, 12, 13], f[7, 8, 9, 14, 15]} *)
$\endgroup$
2
  • $\begingroup$ Thanks, I want to evaluate the function for all possible pairs of values from both lists. Your answer almost gets there by doing this when len(listxyz) == len(listmn). I am interested to see how one could do this when they are not equal :) $\endgroup$
    – haricash
    Jan 25 at 15:50
  • 1
    $\begingroup$ Yes, I anticipated that and had updated my answer. $\endgroup$
    – lericr
    Jan 25 at 17:00
3
$\begingroup$

First, you can use Outer together with Join to generate all possible combinations:

Outer[Join, listxyz, listmn, 1]

Then, you can use MapApply to map your function. However, as Outer returned a 2D list, you should Catenate it first.

func @@@ Catenate@Outer[Join, listxyz, listmn, 1]

The same approach works also if you have multiple lists. You only have to replace Catenate with a more general Flatten:

func @@@ Flatten[Outer[Join, listr, listxyz, listmn, 1], 2]

You can also give a list with just one element, for example:

func @@@ Flatten[Outer[Join, {{r}}, listxyz, listmn, 1], 2]
$\endgroup$
4
  • $\begingroup$ Thanks! This does exactly what I asked for. If one of the entries had to be a symbolic value, what would I have to do? Say, func[r_,x_,y_,z_,m_,n_]:=(3x+4y+z)/(2m+n)*r where r stays as a symbolic value. $\endgroup$
    – haricash
    Jan 25 at 16:03
  • 1
    $\begingroup$ Please see the last example in the edit. Also note that you will probably get other answers with different approaches. You should take a look at all of them – it will help you learn Mathematica :) $\endgroup$
    – Domen
    Jan 25 at 16:14
  • $\begingroup$ Thanks! For now, I am looking to solve my problem. I am curious how the language works, so I will also explore other answers! $\endgroup$
    – haricash
    Jan 25 at 16:42
  • $\begingroup$ Regarding If one of the entries had to be a symbolic value..., do you mean you want to add a constraint on the first argument that it must be symbolic, or do you just mean that you have another argument list all of whose elements are symbols? Or do you mean that in func the r should always be r, i.e. callers can never override it? $\endgroup$
    – lericr
    Jan 25 at 17:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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