Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Is there a "Mathematica Way", like Map or Apply to compute the following double sum?

$\sum_{i=1}^{N_1}\sum_{j=1}^{N_2} m_i n_j \, f(\tau_{i} \gamma_{j})$

I have already stored the lists $m,n,\tau,\gamma$.

$m$ and $\tau$ are of length $N_1$ and $n$ and $\gamma$ of length $N_2$. So my approach was to use something like

Outer[f, τ, γ]

for the function map, and then

Total[Total[Outer[f, τ, γ]]]

but how do Ι multiply mand n into the sum?

EDIT: Undo Edit, figured out the bug in my code

share|improve this question
    
I guess the time to beat is Sum[m[[i]] n[[j]] f[tau[[i]], gamma[[j]]], {i, 1, n1}, {j, 1, n2}] –  ssch Feb 5 '13 at 16:34
    
If f is simple enough then Compile will likely give the best possible performance. But it's not "Mathematica-like". –  Szabolcs Feb 5 '13 at 16:41
    
You could likewise do an Outer[Times,m,n] and then Dot that with your first Outer result. I don't know how that will be speedwise though. –  Daniel Lichtblau Feb 5 '13 at 16:45
    
Does Table/ParallelTable count as Mathematica-like? –  RunnyKine Feb 5 '13 at 16:50
1  
Actually I missed the need for Flatten. This variant works. AbsoluteTiming[Flatten[Outer[Times, m, n]].Flatten[ Outer[f, t, gamma]]] –  Daniel Lichtblau Feb 5 '13 at 20:36

2 Answers 2

up vote 7 down vote accepted

If your elements are in lists the fastest way is to use array operations. In the present case of an outer product one index, let's say "i", will not be expanded, on the other you want to thread.

To operate on a list the function needs the attribute Listable. The Times function, as many other internal ones, is already listable, that is

Times[{1,2,3},x] = {x, 2x, 3x}

You want to do the same with your function "f", e.g.

ClearAll[f]
SetAttributes[f, Listable]

f[{1,2,3},x] = {f[1, x], f[2, x], f[3, x]}

For the threading part you can use MapThread to "slide" through the list, e.g.

MapThread[#1 f[#2] &, {{a,b,c},{1,2,3}}] = {a f[1], b f[2], c f[3]}

Finally your code will look like this

ClearAll[f]
SetAttributes[f, Listable]
f[x_, y_] := x y
{m, n, t, g} = RandomReal[1, {4, 1000}];

Total@Total@MapThread[m #1 f[t #2] &, {n, g}]

A note about speed: usually threaded operation are much faster than element ones

In[27]:= 
Total@Total@MapThread[m #1 f[t, #2] &, {n, g}] // AbsoluteTiming
Total@Total[Outer[Times, m, n] Outer[f[#1, #2] &, t, g]] // AbsoluteTiming
Sum[m[[i]] n[[j]] f[t[[i]], g[[j]]], {i, 1, 1000}, {j, 1, 1000}] // AbsoluteTiming
ParallelSum[m[[i]] n[[j]] f[t[[i]], g[[j]]], {i, 1, 1000}, {j, 1, 1000}] // AbsoluteTiming

Out[27]= {0.797645, 62806.3}

Out[28]= {1.554886, 62806.3}

Out[29]= {2.933898, 62806.3}

Out[30]= {0.828527, 62806.3}

Thus always try to use them when possible.

share|improve this answer
    
I think it should be Total@Total@MapThread[m #1 f[t, #2] &, {n, g}], otherwise it didn't work for me –  rainer Feb 6 '13 at 11:33
1  
You are aware of the second argument of Total[], I presume? Total[(* stuff *), 2] works nicely in particular... –  J. M. Feb 7 '13 at 3:29

How about using Table or ParallelTable like this:

Total[ParallelTable[m[[i]] n[[j]] f[τ[[i]] γ[[j]]], {i, 1, N1}, {j, 1, N2}]]
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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