## Why can Mathematica not use the compiled code?

16

1

    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

24

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...

This solved the problem. Thank you very much, didnt know a default value had to be put into Which. – Nuno Teixeira – 2019-11-20T12:14:17.340

@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. – Henrik Schumacher – 2019-11-20T20:48:43.373