using 'solve' on vector valued function - matlab

I have a vector-valued function defined like this:
eqns =#(z) [0.2178*z(7) + 1.96*sin(z(1)) == -0.2*z(9)*cos(z(1)),...
0.7*z(9) + 1.5*z(4) + 0.2*z(7)*cos(z(1)) - 0.2*z(2).^2*sin(z(1)) == z(5)]
This is a set of two equations where I want z(7) and z(9) to become the subject of the formulae. That is to say, I want these two equations in the form z(7) = f1(z(1),z(2),z(3),z(4),z(5)) and z(9) = f2(z(1),z(2),z(3),z(4),z(5)).
I tried to do this:
[f1,f2]= solve(eqns,z(7),z(9))
but it gives me the error "Undefined function 'z' for input arguments of type
'double'."
Any help will be much appreiated

Without a declaration of z as a symbolic variable, Matlab doesn't know what z is when it tries to evaluate z(7) and z(9) in the call to solve. Therefore, z must be defined prior to the call and also the definition of eqns. Further, since you are treating z as a vector, it is easiest to declare it using sym rather than syms:
z = sym('z',[9,1]);
Lastly, as mentioned in the comments, the first input to solve is to be "specified as a symbolic expression or symbolic equation", so do not declare eqns to be an anonymous, vector-valued function as you would do, for example, fsolve; simply define it using Symbolic Variables, and it will be a Symbolic Expression by construction.
All that said, this code produces an answer for me:
z = sym('z',[9,1]);
z([1,2,4,5]) = sym(rand(4,1));
eqns = [0.2178*z(7) + 1.96*sin(z(1)) == -0.2*z(9)*cos(z(1)),...
0.7*z(9) + 1.5*z(4) + 0.2*z(7)*cos(z(1)) - 0.2*z(2).^2*sin(z(1)) == z(5)];
[f1,f2]= solve(eqns,z(7),z(9));

Related

How can we put element of vector to symsum?

I am trying to use symsum using Matlab. But I get a strange error.
I am trying to put elements of a vector into symsum:
a=[1,2,3,40,51,61];
syms u n
S1(u) = symsum((a(n+1)*(-u)^n)/factorial(n),n,[0,6])
Error is:
Invalid indexing or function definition. When defining a function, ensure that the arguments are symbolic variables and the body of the function is a SYM expression. When indexing, the input must be numeric, logical, or ':'.
First, I can see a mistake where you write a(n+1), for n going from 0 to 6. When n equals 6, you will have a(7) which doesn't exist. a only has 6 elements.
Then, you have another problem because you are indexing a with a symbol, and symbolic indexing is not allowed (see this post).
Does n really need to be a symbol and do you really need to use symsum? If not, you can try:
a = [1,2,3,40,51,61];
n = 0:5;
syms u
S1(u) = sum( sym( (a(n+1).*(-u).^n)./factorial(n) ) )
This returns:
S1(u) =
- (61*u^5)/120 + (17*u^4)/8 - (20*u^3)/3 + (3*u^2)/2 - 2*u + 1

ODE solver producing runtime error - not enough input arguments [duplicate]

I have a use case as follows:
Inside F.m I have a function F that takes as its argument a 2 x 1 matrix x. F needs to matrix multiply the matrix kmat by x. kmat is a variable that is generated by a script.
So, what I did was set kmat to be global in the script:
global kmat;
kmat = rand(2);
In F.m:
function result = F(x)
global kmat;
result = kmat*x;
end
Then finally, in the script I have (x_0 has already been defined as an appropriate 2 x 1 matrix, and tstart and tend are positive integers):
xs = ode45(F, [tstart, tend], x_0);
However, this is causing the error:
Error using F (line 3)
Not enough input arguments.
Error in script (line 12)
xs = ode45(F, [tstart, tend], x_0);
What is going on here, and what can I do to fix it? Alternatively, what is the right way to pass kmat to F?
Firstly, the proper way to handle kmat is to make it an input argument to F.m
function result = F(x,kmat)
result = kmat*x;
end
Secondly, the input function to ode45 must be a function with inputs t and x (possibly vectors, t is the dependent variable and x is the dependent). Since your F function doesn't have t as an input argument, and you have an extra parameter kmat, you have to make a small anonymous function when you call ode45
ode45(#(t,x) F(x,kmat),[tstart tend],x_0)
If your derivative function was function result=derivative(t,x), then you simply do ode45(#derivative,[tstart tend],x_0) as Erik said.
I believe F in ode45(F,...) should be a function handle, i.e. #F. Also, you can have a look at this page of the MATLAB documentation for different methods to pass extra parameters to functions.

How to use Equations in Matlab?

I'm working on Matlab Code for Lagrange Interpolation.
My problem is working with equations.
For solving Lagrange you need to find the Li(x)'s ( L0(x) to Ln(x) ) first:
e.g. for L0(x) we've got:
L0(x) = (x-x1) (x-x2) (x-x3) / (x0-x1) (x0-x2) (x0-x3)
which for an example it would be:
l0(x) = ( x^3 - ( 2 * x^2 ) + 2x ) / 6
which is an equation.
I write the code but it won't accept the variable z (which i used instead of X ) and it tells:
"Undefined function or variable 'z'."
Which is certainly correct cause it's a variable and not a data but how could i use or write this?
MATLAB by default does not like undefined variables (as do most programming languages!)
You have two ways of solving your problem: numerically solving Lagrange "by hand" -- i.e. with functions like ode45, or trying to do it symbolically. This means that you either have to explicitly define x as a symbolic variable -- with syms x and use the symbolic maths toolbox, or, alternatively, use a numerical scheme and something like ode45.
If you want to define a function in MATLAB, you need to plonk a definition into a separate file and save it.
For example:
function out = ellZero( x, a )
x0 = a(1); x1 = a(2); x2 = a(3); x3 = a(4); % SET Constants
out = (x-x1).*(x-x2).*(x-x3)./((x0-x1).*(x0-x2).*(x0-x3)); % RET Expression
end
If you want to learn more about how MATLAB handles functions and 'sub-functions', have a look at the documentation. You might also be interested in the Partial Differential Equation Toolbox.
Hope that helps!

Evaluate Matlab symbolic function

I have a problem with symbolic functions. I am creating function of my own whose first argument is a string. Then I am converting that string to symbolic function:
f = syms(func)
Lets say my string is sin(x). So now I want to calculate it using subs.
a = subs(f, 1)
The result is sin(1) instead of number.
For 0 it works and calculates correctly. What should I do to get the actual result, not only sin(1) or sin(2), etc.?
You can use also use eval() to evaluate the function that you get by subs() function
f=sin(x);
a=eval(subs(f,1));
disp(a);
a =
0.8415
syms x
f = sin(x) ;
then if you want to assign a value to x , e.g. pi/2 you can do the following:
subs(f,x,pi/2)
ans =
1
You can evaluate functions efficiently by using matlabFunction.
syms s t
x =[ 2 - 5*t - 2*s, 9*s + 12*t - 5, 7*s + 2*t - 1];
x=matlabFunction(x);
then you can type x in the command window and make sure that the following appears:
x
x =
#(s,t)[s.*-2.0-t.*5.0+2.0,s.*9.0+t.*1.2e1-5.0,s.*7.0+t.*2.0-1.0]
you can see that your function is now defined by s and t. You can call this function by writing x(1,2) where s=1 and t=1. It should generate a value for you.
Here are some things to consider: I don't know which is more accurate between this method and subs. The precision of different methods can vary. I don't know which would run faster if you were trying to generate enormous matrices. If you are not doing serious research or coding for speed then these things probably do not matter.

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}