# Alternatives to indexed variables in Compile

According to the excellent answer given here by @Leonid Shifrin: How to compile effectively?,

You can not really use indexed variables in Compile, although it may appear that you can.

Separately, @Szabolcs writes in When to use indexed variables

Indexed variables can be used in symbolic calculations. They're useful when the number of variables used needs to be changed programmatically.

Back to me now - I've recently been learning about indexed variables and getting my head around them. Here I'm generating a formula programmatically. For a simple example, it's a sum of sines,

f[x]=a[1]*Sin[x + b[1]] + a[2]*Sin[x + b[2]] + ...


The number of terms in the function is variable, which is why I'm generating the function programmatically. To generate a function with two terms, I run

sinfunction[a_, b_] := a*Sin[x + b];
variables = {a[#], b[#]} & /@ Range[2];
Total[sinfunction @@@ variables]
**Out=a[1]*Sin[x + b[1]] + a[2]*Sin[x + b[2]]**


Once I've generated a formula with n terms, it stays that size, but I then call the function many times with different parameters, and I'm looking to see if Compile can offer me any advantage. I'd like to be able to compile my function and run various benchmarks to see what happens compared to an uncompiled case.

Obviously for small expressions such as this there probably isn't any benefit to compiling (documentation), but I'm using this as an exercise to improve my knowledge of Mathematica for the future!

This hardcoded effort is impractical and probably somewhat redundant:

complexformula = a[1]*Sin[x + b[1]] + a[2]*Sin[x + b[2]];
complexcompiledFunction = With[{function = complexformula},
Compile[{{a[1], _Real}, {b[1], _Real}, {a[2], _Real}, {b[2], _Real}, {x, _Real}},
function
]
];
complexcompiledFunction[2, 3, 1, 1, 5]
**Out=1.6993**


Are there any alternatives? Or do I need to rethink my approach altogether?

cf = Compile[{{data, _Real, 1}},
Module[{x, a, b},
x = Last@data;
a = data[[1 ;; -2 ;; 2]];
b = data[[2 ;; -2 ;; 2]];
a.Sin[b + x]
]
];
cf@RandomReal[{0, 1}, 10000001] // Timing


{0.374402, 2.10248*10^6}

• That's the hint I needed - it works for my requirements at least, thanks @Chenminqi Jun 24, 2014 at 18:36