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.

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?

share|improve this question

1 Answer 1

up vote 1 down vote accepted
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}

share|improve this answer
    
That's the hint I needed - it works for my requirements at least, thanks @Chenminqi –  blochwave Jun 24 at 18:36

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.