COMPGROUPS.NET | Search | Post Question | Groups | Stream | About | Register

### Converting symbolic piecewise functions using matlabFunction

• Email
• Follow

```Hi all,

I am running into an error when trying to use "matlabFunction()" to convert a piecewise symbolic function into a matlab function for use with doubles, ints,... .

I have set the variable "test" to the piecewise function with the MuPad engine using:

test = evalin(symengine,'piecewise([x<=0,10*x],[x>0,x^2])')

and it will correctly evaluate using the "subs()" function:

%Note: I assume that evaluating the function with subs() is very inefficent! (?) %when needing to be called many times and only passing in doubles (arrays)
subs(test,5)-> 25
subs(test,-5)-> -50

Even, "ccode()" and "fortran()" will generate the proper code (for example):

if (0.0D0 .LT. x) then
t = x**2
else
if (x .LE. 0.0D0) then
t = x*1.0D1
else
t = NaN
endif
endif

However, when using the matlabFunction to create a function file i get the following source code:
%--------Command Prompt-----------------------------------------------------------
>> matlabFunction(test,'File','testFun')

ans =

@testFun

%--------Generated Function File-----------------------------------------------------

function test = testFun(x)
%TESTFUN
%    TEST = TESTFUN(X)

%    This function was generated by the Symbolic Math Toolbox version 5.5.
%    22-Dec-2010 14:24:33

test = x.^2;\n  else\n    if (x <= 0.0),\n      t0 = x.*1.0e1;\n    else\n      t0 = NaN;\n    end;\n  end;

Can anyone comment on the proper conversion of symbolic piecewise functions into either a matlab function because I would ideally like to convert it to an EML function to speed up performance. Otherwise my options are to create the the header and gateway information for the needed mex-files and use ccode() or fortran() for the computational routine.

Thanks
```
 0

See related articles to this posting

```On 10-12-22 01:33 PM, Joseph wrote:

> I am running into an error when trying to use "matlabFunction()" to convert a
> piecewise symbolic function into a matlab function for use with doubles,
> ints,... .
>
> I have set the variable "test" to the piecewise function with the MuPad engine
> using:
>
> test = evalin(symengine,'piecewise([x<=0,10*x],[x>0,x^2])')
>
> and it will correctly evaluate using the "subs()" function:

I thought I had a possible short-cut that might potentially work around the
problem, but the more I dig, the more it looks like it might be a difference
between Maple and MuPad. In Maple, piecewise lists end with an "otherwise"
value, which would allow piecewise([x<=0,10*x],[x>0,x^2]) to be converted to
Matlab's piecewise(x<=0,10*x,x^2) with a saving of a test -- a saving that
might just be enough to not trigger the bug you see in which the first part of
the test appears to go missing after conversion to matlabFunction .
```
 0

```"Joseph" wrote in message <ietjph\$muc\$1@fred.mathworks.com>...
> Hi all,
>
> I am running into an error when trying to use "matlabFunction()" to convert a piecewise symbolic function into a matlab function for use with doubles, ints,... .
>
> I have set the variable "test" to the piecewise function with the MuPad engine using:
>
test = evalin(symengine,'piecewise([x<=10,10*x],[x>10,x^2])')

I have created a work-around for this problem by using the ccode() and converting the code into a matlab function. This will allow arrays of arbitrary size to be inputted by testing for the length of the array and using a for loop.

ctest = ccode(test); %Turn piecewise symbolic to C code
ctest = ctest(~ismember(ctest,['{','}'])); %Remove brackets
ctest = [ctest, repmat(['\n end;'],1,1+length(regexp(ctest,'if')))]; %Add end statements for 'if' and 'for' loop
ctest = regexprep(ctest,'x','x(i)'); %Replace with index to input array
ctest = regexprep(ctest,'test','T(i)'); %Replace with index to output array. Note that the 'test' may vary depending on what the symbolic expression is named
ctest = ['len=length(x);\nT=zeros(len,1);\nfor i=1:len;\n' ctest]; %add the length check and also the for loop
fid = fopen('test.m','w+');%Create test.m file
fprintf(fid,ctest);%Write the string to the test.m file
-------------------------------------------------------------------------------
%test.m
function T = test(x)
len=length(x);
T=zeros(len,1);
for i=1:len;
if (1.0E1 < x(i))
T(i) = x(i)*x(i);
else
if (x(i) <= 1.0E1)
T(i) = x(i)*1.0E1;
else
T(i) = NAN;
end;
end;
end;
-------------------------------------------------------------------------------
This works for any size arrays and works for arbitrary piecewise functions. Can anyone comment on why this function works twice as fast as the  mex function version, even though the M-file has a for loop.
```
 0