How to pass a Matlab vector variable to a MuPAD function? - matlab

I want to use the stats::swGOFT function in MuPAD. I have a numerical vector called r. I used
feval(symengine, 'stats::swGOFT', r);
The error was
Error using mupadengine/feval (line 157)
MuPAD error: Error: Some data are of invalid type.
So I tried a more direct way, which worked:
feval(symengine, 'stats::swGOFT', 1,2,3,4);
But this didn't work:
feval(symengine, 'stats::swGOFT', [1,2,3,4]);
My variable r is a 1146-by-1 double vector. Obviously I can't manually input all the numbers. So, how to pass the vector variable r to the MuPAD function stats::swGOFT?

MuPAD is not Matlab. From the current version documentation for stats::swGOFT, it appears that this function requires a list, as opposed to an array (what Matlab uses). Many MuPAD functions automatically coerce inputs to the desired format, but that doesn't seem to occur in this case. You have several options if you want to call this function from Matlab using numeric values – here's a simple one that will work for both floating point and symbolic numeric values:
r = randn(1146,1);
rStr = char(sym(r(:).'));
feval(symengine, 'stats::swGOFT', rStr(9:end-2))
This one should perform the string conversion more quickly for large datasets of floating point values using sprintf:
r = randn(1146,1);
rStr = ['[' sprintf('%.17g', r(1)) sprintf(',%.17g', r(2:end)) ']'];
feval(symengine, 'stats::swGOFT', rStr)
Since you're converting to a string yourself, you might as well convert the above to use evalin directly:
r = randn(1146,1);
rStr = [ sprintf('%.17g', r(1)) sprintf(',%.17g', r(2:end)) ];
evalin(symengine, ['stats::swGOFT([' rStr '])'])

Related

Using `lsqnonlin` with vector inputs

I have a question about using the lsqnonlin function.
In my case I have two functions:
f_1=#(t,x)sin(t+x.^2);
f_2=#(t,x)cos(x.^2)+3.*t.^2;
f = {f_1, f_2};
I want to find the values of the arguments t and x which would result in the least square error, defined as: f_1(t,x)^2+f_2(t,x)^2. In other words, argmin for LSE.
My code is as follow with initial guess [1,2]:
lsqnonlin(f,[1,2])
And I'm getting the error:
Error in lsqnonlin (line 196)
initVals.F = feval(funfcn{3},xCurrent,varargin{:});
Caused by:
Failure in initial objective function evaluation. LSQNONLIN cannot continue.
lsqnonlin can be used for vector function and vector input according to the documentation. I wonder how to prepare corresponding codes for it. Could anyone suggest the solution?
You are getting an error because lsqnonlin expects a scalar function handle that maps a vector to a vector, whereas you specify a cell array of function handles. To fix this, instead of a vector of functions outputting one scalar each, you need to rewrite it into a single function that accepts a vector of inputs and also outputs a vector:
f = #(xt)[sin(xt(2)+xt(1).^2), cos(xt(1).^2)+3.*xt(2).^2];
% xt = [x,t]
% f = [f_1(xt), f_2(xt)]
so f and xt are both vectors of 2 elements.
Then, the solver works:
lsqnonlin(f,[1,2])
ans =
1.6144 0.5354

Error using integral: A and B must be floating-point scalars

I want to evaluate the simple example of integral
a = max(solve(x^3 - 2*x^2 + x ==0 , x));
fun = #(x) exp(-x.^2).*log(x).^2;
q = integral(fun,0,a)
and the error is
Error using integral (line 85)
A and B must be floating-point scalars.
Any tips? The lower limit of my integral must be a function, not a number.
The Matlab command solve returns symbolic result. integral accepts only numeric input. Use double to convert symbolic to numeric. As your code is written now, already max should throw an error due to symbolic input. The following works.
syms x;
a = max(double(solve(x^3 - 2*x^2 + x)));
fun = #(x) exp(-x.^2).*log(x).^2;
q = integral(fun,0,a)
Output: 1.9331.
the lower limit of my integral must be a function, not a number
integral is a numeric integration routine; the limits of integration must be numeric.
Check values of a by mouse over in breakpoint or removing the ; from the end of the line so it prints a. Based on the error, a is not a scalar float. You might need another max() or double() statement to transform the vector to a single value.
Solve Help : http://www.mathworks.com/help/symbolic/solve.html
Integral Help : http://www.mathworks.com/help/ref/integral.html

How to simplify a symbolic and numeric mixed expression in Matlab

I have a symbolic and numeric mixed expression:
(3145495418313256125*sin(11334310783410932061962315977/17437937757178560512000000000)*cos(theta))/85568392920039424
where theta is a symbolic variable. I want to simplify this expression such that all the numeric numbers and their math operation results are changed to double.
In terms of data types, you can't mix floating point and symbolic values. However, you can use variable precision arithmetic so that the values are represented in decimal form. Using vpa:
syms theta
y1 = (3145495418313256125*sin(11334310783410932061962315977/17437937757178560512000000000)*cos(theta))/85568392920039424
y2 = vpa(y1)
which returns
y2 =
22.24607614528243677915796931637*cos(theta)
The data type (class) of y2 is still sym. See the digits function to adjust the number of significant digits.
If you want to work in actual floating point you'll need to convert your symbolic expression into a function. You can automate that procedure by using the confusingly-named matlabFunction:
thetafun = matlabFunction(y1)
which returns a function using double precision variables:
thetafun =
#(theta)cos(theta).*2.224607614528244e1
The anonymous function thetafun can then be called just like any function, e.g., thetafun(0.5).
You can make use of coeffs command to achieve the desired:
f=2*cos(theta)/3+5*sin(theta)/19
c_f=coeffs(f);
fraction_c_f=double(c_f);
ans = [0.2632 0.6667]

matlab coder covert m-file to c++?

I used MATLAB coder to covert M-file to cpp-file.
There generated problem when is building.
Expected either a logical, char, int, fi, single, or double. Found an
mxArray. MxArrays are returned from calls to the MATLAB
interpreter and are not supported inside expressions. They may only be
used on the right-hand side of assignments and as arguments to
extrinsic functions.
MATLAB code :
nms = sum(transpose(X).^2);
nms0=-1 * nms;
nms2=transpose(nms0);
nms3=transpose(X);
nms4=nms2*ones(1,n);
nms5=ones(n,1)*nms;
nms6=2*X*nms3;
nms7=zeros(150,150);
nms7=nms4-nms5; //This line is wrong
nms8=nms7 + nms6;
K = exp(nms8);
I want to know why code has been run correct in MATLAB,but it has error when is building
This error happens when you try to use result of extrinsic functions in expressions. In the code you provided is "n" or "X" the result of an extrinsic function? Even if they are not directly a result of an extrinsic function, they may have been computed based on data from other extrinsic functions.
One way to fix the problem is to help MATLAB coder convert these extrinsic data to known types. You can do that by pre-defining them with known data. For example,
coder.extrinsic('some_extrinsic_fcn');
y = zeros(10,1);
y = some_extrinsic_fcn();
y = y * 2;
In this case some_extrinsic_fcn should return a double precision vector with 10 elements. This resulting mxArray will be auto-converted and stored in y. Without the line "y = zeros(10,1);" y will be of mxArray type and the line "y = y * 2;" will cause an error.

How do I make a function from a symbolic expression in MATLAB?

How can I make a function from a symbolic expression? For example, I have the following:
syms beta
n1,n2,m,aa= Constants
u = sqrt(n2-beta^2);
w = sqrt(beta^2-n1);
a = tan(u)/w+tanh(w)/u;
b = tanh(u)/w;
f = (a+b)*cos(aa*u+m*pi)+a-b*sin(aa*u+m*pi); %# The main expression
If I want to use f in a special program to find its zeroes, how can I convert f to a function? Or, what should I do to find the zeroes of f and such nested expressions?
You have a couple of options...
Option #1: Automatically generate a function
If you have version 4.9 (R2007b+) or later of the Symbolic Toolbox you can convert a symbolic expression to an anonymous function or a function M-file using the matlabFunction function. An example from the documentation:
>> syms x y
>> r = sqrt(x^2 + y^2);
>> ht = matlabFunction(sin(r)/r)
ht =
#(x,y)sin(sqrt(x.^2+y.^2)).*1./sqrt(x.^2+y.^2)
Option #2: Generate a function by hand
Since you've already written a set of symbolic equations, you can simply cut and paste part of that code into a function. Here's what your above example would look like:
function output = f(beta,n1,n2,m,aa)
u = sqrt(n2-beta.^2);
w = sqrt(beta.^2-n1);
a = tan(u)./w+tanh(w)./u;
b = tanh(u)./w;
output = (a+b).*cos(aa.*u+m.*pi)+(a-b).*sin(aa.*u+m.*pi);
end
When calling this function f you have to input the values of beta and the 4 constants and it will return the result of evaluating your main expression.
NOTE: Since you also mentioned wanting to find zeroes of f, you could try using the SOLVE function on your symbolic equation:
zeroValues = solve(f,'beta');
Someone has tagged this question with Matlab so I'll assume that you are concerned with solving the equation with Matlab. If you have a copy of the Matlab Symbolic toolbox you should be able to solve it directly as a previous respondent has suggested.
If not, then I suggest you write a Matlab m-file to evaluate your function f(). The pseudo-code you're already written will translate almost directly into lines of Matlab. As I read it your function f() is a function only of the variable beta since you indicate that n1,n2,m and a are all constants. I suggest that you plot the values of f(beta) for a range of values. The graph will indicate where the 0s of the function are and you can easily code up a bisection or similar algorithm to give you their values to your desired degree of accuracy.
If you broad intention is to have numeric values of certain symbolic expressions you have, for example, you have a larger program that generates symbolic expressions and you want to use these expression for numeric purposes, you can simply evaluate them using 'eval'. If their parameters have numeric values in the workspace, just use eval on your expression. For example,
syms beta
%n1,n2,m,aa= Constants
% values to exemplify
n1 = 1; n2 = 3; m = 1; aa = 5;
u = sqrt(n2-beta^2);
w = sqrt(beta^2-n1);
a = tan(u)/w+tanh(w)/u;
b = tanh(u)/w;
f = (a+b)*cos(aa*u+m*pi)+a-b*sin(aa*u+m*pi); %# The main expression
If beta has a value
beta = 1.5;
eval(beta)
This will calculate the value of f for a particular beta. Using it as a function. This solution will suit you in the scenario of using automatically generated symbolic expressions and will be interesting for fast testing with them. If you are writing a program to find zeros, it will be enough using eval(f) when you have to evaluate the function. When using a Matlab function to find zeros using anonymous function will be better, but you can also wrap the eval(f) inside a m-file.
If you're interested with just the answer for this specific equation, Try Wolfram Alpha, which will give you answers like:
alt text http://www4c.wolframalpha.com/Calculate/MSP/MSP642199013hbefb463a9000051gi6f4heeebfa7f?MSPStoreType=image/gif&s=15
If you want to solve this type of equation programatically, you probably need to use some software packages for symbolic algebra, like SymPy for python.
quoting the official documentation:
>>> from sympy import I, solve
>>> from sympy.abc import x, y
Solve a polynomial equation:
>>> solve(x**4-1, x)
[1, -1, -I, I]
Solve a linear system:
>>> solve((x+5*y-2, -3*x+6*y-15), x, y)
{x: -3, y: 1}