16
$\begingroup$
    footandkneestates = 
     Compile[{{t1, _Real}, {tb, _Real}, {tc, _Real}, {kneephase121, \
    _Real}, {kneephase122, _Real}, {kneephase31, _Real}, {kneephase32, \
   _Real}, {footphase11, _Real}, {footphase12, _Real}, {footphase21, \
   _Real}, {footphase22, _Real}, {footphase31, _Real}, {footphase32, \
   _Real}, {tfprevious, _Real}, {tfnext, _Real}, {\[CapitalDelta]t, \
   _Real}}, Which[
       tfprevious <= t1 < tfprevious + tb \[CapitalDelta]t, {kneephase121,
         kneephase122, footphase11, footphase12}, 
           tfprevious + tb \[CapitalDelta]t <= t1 < 
        tfprevious + tc \[CapitalDelta]t, {kneephase121, kneephase122, 
       footphase21, footphase22}, 
       tfprevious + tc \[CapitalDelta]t <= t1 < tfnext, {kneephase31, 
        kneephase32, footphase31, footphase32}]]

I have this function, which only accepts reals and when i give this set of numbers,

{0.1, 0.4, 0.8, -0.564822, 0.592935, -0.264433, 0.471983, -0.336753, \
0.14798, -0.0964996, 0.768075, 0.722187, 0.691703, 0, 0.403326, \
0.403326}

as the function arguments it proceeds witn an uncompiled evaluation, this is the input:

footandkneestates[0.1, 0.4, 0.8, -0.564822, 0.592935, -0.264433, 0.471983, -0.336753, \
    0.14798, -0.0964996, 0.768075, 0.722187, 0.691703, 0, 0.403326, \
    0.403326]

and this is the output:

CompiledFunction:Compiled expression {-0.564822,0.592935,-0.336753,0.14798} should be a machine-size real number.
CompiledFunction:Could not complete external evaluation at instruction 1; proceeding \
with uncompiled evaluation
{-0.564822, 0.592935, -0.336753, 0.14798}

Can anyone help me out why cant i used the compiled version of this function with the dataset i provided? Thanks

$\endgroup$
24
$\begingroup$

It is important to Compile that it has always the same return type, no matter what happens at runtime. Note that Which returns Null as default value. Since the return value of the function is meant to be a 4-vector in some cases, we have to assign also a 4-vector (e.g., {0., 0., 0., 0.}) as default return value of Which. So this should work:

footandkneestates = 
 Compile[{{t1, _Real}, {tb, _Real}, {tc, _Real}, {kneephase121, _Real}, {kneephase122, _Real}, {kneephase31, _Real}, {kneephase32, _Real}, {footphase11, _Real}, {footphase12, _Real}, {footphase21, _Real}, {footphase22, _Real}, {footphase31, _Real}, {footphase32, _Real}, {tfprevious, _Real}, {tfnext, _Real}, {\[CapitalDelta]t, _Real}},
  Which[
   tfprevious <= t1 < tfprevious + tb \[CapitalDelta]t,
   {kneephase121, kneephase122, footphase11, footphase12},
   tfprevious + tb \[CapitalDelta]t <= t1 < tfprevious + tc \[CapitalDelta]t,
   {kneephase121, kneephase122, footphase21, footphase22},
   tfprevious + tc \[CapitalDelta]t <= t1 < tfnext,
   {kneephase31, kneephase32, footphase31, footphase32},
   True,
   {0., 0., 0., 0.}
   ]
  ]

Admittedly, the error messages have not been very helpful in finding out what is going on...

$\endgroup$
  • $\begingroup$ This solved the problem. Thank you very much, didnt know a default value had to be put into Which. $\endgroup$ – Nuno Teixeira Nov 20 at 12:14
  • $\begingroup$ @NunoTeixeira You're welcome. Glad to hear that! Indeed, Whichdoes not need any explicit default in general. Here it is only about the fact that Compile has to generate a C-function (or rather a C++-program). And in these languages, the output type of a function has to be known at compile time. $\endgroup$ – Henrik Schumacher Nov 20 at 20:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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