18
$\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 with 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 I can't used the compiled version of this function with the dataset I provided?

$\endgroup$

1 Answer 1

27
$\begingroup$

This is a very subtle issue. 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$
2
  • $\begingroup$ This solved the problem. Thank you very much, didnt know a default value had to be put into Which. $\endgroup$ Commented Nov 20, 2019 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$ Commented Nov 20, 2019 at 20:48

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.