Consider the following compiled function, which takes a $12 \times 5$ array $x_{ij}$ of real numbers and computes the triple sum $$ \sum_{k=1}^5 \sum_{i=1}^{12} \sum_{j=i+1}^{12} x_{ik} x_{jk}. $$
Compile[{{x, _Real, 2}},
Sum[x[[i, k]]*x[[j, k]],
{k, 5}, {i, 12}, {j, i + 1, 12}
]
]
When I attempt to evaluate this, Mathematica 10.1 on Windows throws the following error at me:
Compile::cpintlt: i+1 at position 2 of x[[i+1,5]] should be either a nonzero integer or a vector of nonzero integers; evaluation will use the uncompiled function. >>
It looks like the indices of the Sum[]
are being inserted before the expression is passed to Compile[]
. Why does this happen? Note that if I re-index the sum as
$$ \sum_{k=1}^5 \sum_{i=1}^{12} \sum_{j=1}^{i-1} x_{ik} x_{jk} $$
Mathematica has no problem compiling the resulting function:
Compile[{{x, _Real, 2}},
Sum[x[[i, k]]*x[[j, k]],
{k, 5}, {i, 12}, {j, i-1}
]
]
This compiles just fine. Why does this version work, and not the previous version?
Compile
(of which there are many). $\endgroup$ – Oleksandr R. Sep 28 '15 at 23:45CompiledFunction
. You can try, for exampleSum[x[[i]], {i, 13, 12}]
. $\endgroup$ – David Zhang Sep 29 '15 at 1:20(Sum[(Sum[x[[i, k]], {i, 12}])^2, {k, 5}] - Sum[x[[i, k]]^2, {k, 5}, {i, 12}])/2
or(Total[Total[x]^2 - Total[x^2]])/2
. This follows from expanding the square of the column sums. $\endgroup$ – JimB Sep 29 '15 at 3:43Compile
might be what you need — e.g.Compile[{{x, _Real, 2}}, Sum[x[[i, k]]*x[[j, k]], {k, 5}, {i, 12}, {j, i + 1, 12}], {{i, _Integer}, {j, _Integer}, {k, _Integer}}]
. $\endgroup$ – Stephen Luttrell Sep 29 '15 at 8:08