0
$\begingroup$

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?

$\endgroup$
2
  • $\begingroup$ I'm not sure what Leonid means in that post, but indexed variable can actually be used in Compile to some degree, for example: Needs["CompiledFunctionTools`"] and Compile[x[1], Sin[x[1]]] // CompilePrint. See also mathematica.stackexchange.com/a/148189/1871 $\endgroup$
    – xzczd
    Commented Aug 25, 2023 at 0:16
  • $\begingroup$ Ah, we used to discuss it here: mathematica.stackexchange.com/q/183912/1871 I completely forgot about it. $\endgroup$
    – xzczd
    Commented Aug 26, 2023 at 9:24

1 Answer 1

1
$\begingroup$
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}

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

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.