I'm working on an script that uses sym functions within a loop, because of the way my functions are defined. Also I need to use their derivatives. I cannot just write down the explicit matlab function for each, so defining each individual function and derivatives is not an option.
the code is this:
[out]=sym_script(n)
syms x;
out=[];
for i=1:n
Function=sin(x)+i*x;
out=[out Some_operation(Function,vec)];
end
(min example, actual sym function more complicated ) the problem is that matlab seems to be unable to overwrite Function if it is syms.
I have tried the script in Matlab 2015a for pc and mac and get the same error in both.
Never mind the trouble was inside other function I called in the loop. It had a variable named "diff" which caused conflict with the matlab's function diff() to calculate derivatives.
Related
I am just getting started with MATLAB and I have written a function to produce the binomial expansion of (x-a)^n when given x, a and n. As far as I can tell my code should work, but I do not seem to be using the function variables correctly.
function expand(a,n,x)
f = 0;
for k = 0:1:n
f = f + nchoosek(n,k).*x.^(n-k).*(-a).^k;
end
end
I need to be able to call the function and have it output f as the expanded polynomial in x, for example calling expand(1,3,x) should return x^3-3*x^2+3*x-1, but instead, calling it gives this error:
Unrecognized function or variable 'x'. It seems like it wants me to call the function with x being another number but I in fact need it to be able to be any letter to be used as the variable in the polynomial.
I know in Maple I would specify the variable type in the function to be x::name so I'm assuming there's something similar in MATLAB that I don't yet know.
Thanks for any help.
There are two ways to go about this:
Create x as a symbolic variable. For example, syms x; expand(a,n,x). This gives you the power of using the symbolic toolbox features like simplify(), but comes with a bit of a performance penalty. You should avoid using the symbolic toolbox in intensive calculations.
Return an anonymous function, f=#(X)sum(arrayfun(#(k)nchoosek....,1:n). This has better performance and does not require double(subs(...)) when you want an actual numeric value, but may be too difficult to implement for a beginner.
I have a density function f_N which is defined as follows (K_nu(z) is the modified Bessel function):
I want to compute the following integral for each value of N:
The following is the implementation of the above in matlab.
for N=1:100
syms z
f =#(z) (1/(gamma(N)*sqrt(pi))*(z/2).^(N-0.5).*besselk(0.5-N,z));
g = #(z) f(z).*log(f(z));
val=integral(g,0,Inf);
But when I run the above code, it's always returning NaN for varoious values of N with the following warning:
Warning: Infinite or Not-a-Number value encountered
Can someone suggest a simple way to do this or avoid this issue?
I don't think you are doing what you think you are doing. Your declaration of z as a symbol will get overridden by the function handle definition. That means the integral is not a symbolic one, but a numeric one. So what you simply need to do is to drop the function handle notation "#(z)" and do the integral symbolically...
My guess, without thoroughly analysing this, is that one of the points in you integration domain [0,inf] yields a value f (x)=inf, which would destroy a numeric integration technique, but perhaps not a symbolic one.
I'm trying to figure out how to solve a system of ODEs inside a subsystem in a Simulink model. Basically, each call to this subsystem, which happens at each tick of the simulation clock (fixed-step), entails solving the ODEs. So there's like a different "clock" for the subsystem.
I have an M-file that implements the function for the system of ODEs. Currently, I have a MATLAB Function block for that. It needs a lot of parameters that I can get from the base workspace (via evalin and using coder.extrinsic('evalin') at the beginning). But I'm not allowed to define function_handle objects or inner functions to parameterize the function that is used by ode*. I think that if I'm able to solve the ODEs in this block, I'll have solved my problem. But those restrictions are "ruining" it.
I'd appreciate if you have any ideas of how to accomplish this. I welcome different approaches.
Thank you.
EDIT
A simple example is given below. It attempts to solve the van der Pol equation by changing the mu parameter randomly. This is the main idea I have at the moment, which doesn't work because of the problems mentioned above.
This is the main model with the subsystem:
This is the subsystem:
This is the MATLAB Function block implementation (note that there's an error in the # symbol, since defining function_handle objects isn't allowed):
Just use the MATLAB Function block as a wrapper. Put the bulk of your code into a "standard" MATLAB function (i.e. one callable from MATLAB, not the MATLAB Function block) and call that function (after defining it as coder.extrinsic) from the MATLAB Function block.
This will be a bit more complex than Phil Goddard's solution. The advantage is that it will allow you to generate standalone code, if necessary, whereas extrinsic functions are not compatible with standalone code generation.
The functions ode23 and ode45 are supported for code generation as of MATLAB R2014b so this applies if your MATLAB release is at least that new. Supposing so, the main limitation you are seeing is that anonymous functions are not supported for code generation.
Simulate Anonymous Function Parameters with Persistent Variables
However, these parameterized anonymous functions can be simulated using a normal function with a persistent. To simulate your function with the parameter mu, make a MATLAB file odefcn.m:
function x = odefcn(t,y)
%#codegen
persistent mu;
if isempty(mu)
% Adjust based on actual size, type and complexity
mu = 0;
end
if ischar(t) && strcmp(t,'set')
% Syntax to set parameter
mu = y;
else
x = [y(2); mu*(1-y(1)^2)*y(2)-y(1)];
end
Then in the MATLAB Function Block, use:
function y = fcn(mu)
%#codegen
% Set parameter
odefcn('set',mu);
% Solve ODE
[~,Y] = ode45(#odefcn,[0, 20], [2; 0]);
y = Y(end,1);
That should work both for simulation and for code generation. You can just add more arguments to odefcn if you need more parameters.
I need to solve a system of nonlinear equations; in order to use fsolve , I have written an m-file containing my function "myfun". This function is called by the main m-file.
Both the system and the unknowns must be written using a "for" loop.
Example:
function F=myfun(x)
n=20;`
for j=1:n
c1=sqrt(x(j)^2-3*x(j));
c2=x(j)^(1/2);
F(j)=c1+c2;
end
My problem is that I have to preallocate memory for my vectors, both F and x, otherwise the solver considers numel(x)=1.
But if I declare
F=zeros(n,1);
x=zeros(n,1);
I have the following output:
No solution found.
fsolve stopped because the problem appears regular as measured by the gradient,
but the vector of function values is not near zero as measured by the
default value of the function tolerance.
Any suggestions? Thanks
You don't need the loop, just use
F = sqrt(x.^2-3*x) + x.^(1/2);
Then you also don't need to declare n, c1, c2.
Your error message also doens't sound like it's a problem with the allocation, but more with finding a solution to you fsolve problem.
I would like to create a Symbolic function within a Simulink Matlab Function to solve the variables h and t1. Matlab produces error "The function 'syms' is not supported for standalone code generation. See the documentation for coder.extrinsic to learn how you can use this function in simulation." when I try to compile the Simulink Matlab function with the following code.
syms Eq1(h,t1);
Eq1(h,t1) = h*t1;
I tried adding "coder.extrinsic('syms')" at the top, as shown below, and this generated the error "Undefined function or variable 'h'."
coder.extrinsic('syms');
syms Eq1(h,t1);
Eq1(h,t1) = h*t1;
How do I use symbolic variables and functions (Syms) in a Simulink Matlab Function?
It might be possible to fix the "Undefined function or variable 'h'." using sym instead of syms, but then the coder will tell you it can't generate code for symbolic variables. You have to declare everything which uses the symbolic toolbox to be extrinsic. Simplest way: Put everything into a function and declare this function to be extrinsic.