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, 2014 at 13:36
  • $\begingroup$ You're absolutely right, I've now edited it. $\endgroup$
    – Rafal
    May 27, 2014 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, 2014 at 22:10

2 Answers 2



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]
  • $\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, 2014 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, 2014 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$ May 27, 2014 at 15:44
  • $\begingroup$ Longest can help here. $\endgroup$ May 27, 2014 at 16:49
  • $\begingroup$ +1 for tester[PatternSequence[a__, b__] /; (Length@{a} == Length@{b})] := "ok" $\endgroup$
    – sinner
    Sep 21, 2016 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]

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.