I have the following function

lFreqPhylo[a_, Q_, b_, p_] :=  Sum[Log[freqFunction[r[[p]][[i]], L[[p]][[i]], a, Q, b, {i, 1, nbranches[[p]]}];

The objects L, r and nbranches are simply lists of data, and the argument p tells the function which dataset to refer to.

I'd like to define a function which sums all of the datasets (here n=2) and uses a different argument a and b for each dataset, so to write it our by hand,

lFreqPhylo[a1, Q, b1, 1] + lFreqPhylo[a2, Q, b2, 2]

To this end, I defined two lists,

A = {a1,a2}


B = {b1,b2}

(This list has more elements but I'm giving the example of 2 elements to keep it simple.) What this means is that I'd need to pass the lists A, B and the index to each list (p in lFreqPhylo) to a new function lFreq. The following approach however failed:

lFreq[A__, B__, Q_] := Sum[lFreqPhylo[A[[p]], Q, B[[p]], p], {p, 1, 2}]; (*Doesn't work!*)

How can I pass the two lists, A and B, to the function lFreqPhylo such that I can (a) use the 'Sum[...]' expression on the right hand side, (b) use the list elements, a1, a2, b1 and b2, as arguments of the function?

Thanks in advance, Rafal

  • $\begingroup$ Kuba, Well, problem is I have two lists and need to pass an index of the list as an argument. So following your advice, having defined two lists, A = {a1,a2}; B = {b1,b2}; I did f1[a_, b_, Q_] := (a b)^2/Q; f2[Q_, a__, b__] := Total[MapThread[f1[#1, #2, Q] &, {A, B}]]; and now it works. But what if I have f1[a_, b_, Q_,i_] := (a b)^2/Q i where i is the index of the element of the list (1 or 2)? How do I define f2 then? $\endgroup$ – Rafal May 27 '14 at 13:36
  • $\begingroup$ You're absolutely right, I've now edited it. $\endgroup$ – Rafal May 27 '14 at 14:09
  • $\begingroup$ Change the LHS of your definition to lFreq[A_, B_, Q_] and it works as expected; no? $\endgroup$ – kglr May 27 '14 at 22:10


The definition you make

lFreq[A__, B__, Q_] := [...]

is not very nice. There is an ambiguity here and Mathematica will not know how many elements to match to A and how many to match to B. We can check this by defining

lFreqTest[A__,B__]:= {A}


lFreqTest[1, 2, 3, 4]



So that we see that Mathematica tries to make B__ as long as possible. There is a terrible way around this

tester[PatternSequence[a__, b__] /; (Length@{a} == Length@{b})] := "ok"

which gives


But this will be very slow. You should look to alternatives.


How about this?

A = {1, 2};
B = {2, 3};
Q = 6;

The actual functions

f1[a_, b_, Q_, i_] := (a b)^2/Q;

lFreq[listA_, listB_, Q_] :=

lFreq[listA_, listB_, Q_] :=
   f1[#1, #2, Q, #3] &
   {listA, listB, Range[Length@listA]}

Now we have

lFreq[A, B, Q]
| improve this answer | |
  • $\begingroup$ Jacob, I have now changed the original question such that it contains all the sub-questions I had. Sorry for the confusion. $\endgroup$ – Rafal May 27 '14 at 14:10
  • $\begingroup$ Thanks Jacob. I've written the following and it seems to work. Do you think this is better or do you think it will be slow too and should I find another way? lFreqPhylo[a_, Q_, b_, p_] := Sum[Log[freqFunction[r[[p]][[i]], L[[p]][[i]], a, Q, b]], {i, 1, nbranches[[p]]}]; lFreqPhylo2[listA_, listB_, Q_] := Total@MapThread[ lFreqPhylo[#1, Q, #2, #3] &, {listA, listB, Range[Length@listA]}]; lFreq[A_, B_, Q_] := Evaluate[lFreqPhylo2[A, B, Q]]; $\endgroup$ – Rafal May 27 '14 at 15:26
  • $\begingroup$ @Rafal that looks quite reasonable. Just so you know, you can write r[[p]][[i]] as r[[p, i]]. Furthermore your definition for lFreq may be a bit tricky. Either Q A and B are already set, and it is misleading to have them as function arguments. Or they are not set, and MapThread will probably fail. Maybe it works if you define this function before you define lFreqPhylo2, A, B and Q. $\endgroup$ – Jacob Akkerboom May 27 '14 at 15:44
  • $\begingroup$ Longest can help here. $\endgroup$ – Alexey Popkov May 27 '14 at 16:49
  • $\begingroup$ +1 for tester[PatternSequence[a__, b__] /; (Length@{a} == Length@{b})] := "ok" $\endgroup$ – sinner Sep 21 '16 at 1:44

What about the following approach:

lFreq[A_List, B_List, Q_]:=Sum[Function[i, lFreqPhylo[A[[i]], Q, B[[i]], i][j], {j, 1, 2}]

This produces the correct output for the given example of 2 elements:

lFreqPhylo[a1, Q, b1, 1] + lFreqPhylo[a2, Q, b2, 2]
| improve this answer | |

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.