Set complicated assumptions on symbolic function - matlab

I am trying to find the roots of a nonlinear function that depends on several symbolic variables and a symbolic function. To guarantee the existence of a solution I need to set some assumptions on the symbolic function b(x).
By using the Matlab function assume I can set simple assumptions like
syms b(x) d
assume(b(0)==0 & b(x)>=0);
Now I am looking for a way to include this assumption: (symbolic function b(x), symbolic variable d)
There is a value y such that b(x) < d*x for x < y and b(x) > d*x for x > y.
To make it easier we can fix for example d=0.1 and b(10)=1 such that y=10. However I would prefer leaving d and y symbolic.
I tried to write a function that checks the assumption but unsurprisingly Matlab does not seem to accept a symbolic function as an input variable.
Do you know a solution to this problem or have an idea?
Update 2017-01-03:
While having fixed d=0.1,b(10)=1 and y=10 I am trying to check the above assumption by using
syms b(x)
d=0.1;
assume(x, 'real');
assume(x>=0);
assume(b(0)==0 & b(x)>=0 & b(10)==1);
checkAssumption(x)= mySign(x)*(d*x-b(x));
assume(checkAssumption(x)>=0);
where
function sign=mySign(x)
if x<10
sign=-1;
else if x==10
sign=0;
else if x>10
sign=-1;
end
end
end
Then I get the error "Conversion to logical from sym is not possible." in mySign. Using double(x) as the input variable of mySign leads to the error "DOUBLE cannot convert the input expression into a double array".
Do you know a way to get mySign and checkAssumptions evaluated or have an other idea how to assume the above assumption?

Related

Write recursive sub-functions and non-recursive sub-functions in Matlab

I'm newbie to Matlab
I have an assignment :
Legendre polynomial Pn(x), n=0,1,2,. . . The recursive formula of is
Write recursive sub-functions and non-recursive sub-functions separately to find the value of the Legendre polynomial function
This is my code :
function P =Legendre(n,x)
syms x;
n = input('n=');
if n==0
P=1;
elseif n==1
P=x;
elseif n>=2
P=((2*n-1)/n)*x*Legendre(n-1)-((n-1)/n)*Legendre(n-2);
end
end
But I get an error message:
Unrecognized function or variable 'Legendre'.
Error in ti4 (line 9)
P=((2*n-1)/n)*x*Legendre(n-1)-((n-1)/n)*Legendre(n-2);
Sorry for the stupid question. Can anyone help me? Thank u so much
A few things are probably going on here.
File name needs to match function name (for the primary function)
In your case, the filename needs to be Legendre.m.
Symbolic toolbox OR do you want an answer
for most uses of this function, I would leave two full inputs, just as you have them. Bur I would remove the first two lines completely.
As it is, the first two lines will break your inputs. The value for n is reset by the input function. I'm actually not sure what happens when you declare an existing variable x, to a sym.
Input consistency
You are setting up a function with two inputs, named n and x. But when you maek your recursive calls you only pass in one variable. The easiest thing to do here is simply keep passing n in as the first input.
(Right now, you are trying to pass in x in the recursive calls, but it will be interpreted as n.)

"Array indices must be positive integers or logical values"

Problem Details and clues
%For this problem write a script file called NC.m that implements
%the Newton-Cotes method of integration for an arbitrary function f(x). It
%should take as inputs the function and the limits of integration [a: b] and
%output the value of the definite integral. Specifically, you should use the
%Trapezoid rule as presented in Equation (11.73)
function [f]= NC(a,b,fun) %newton-cotes
%a and b are limits of intergration
%setting it up
f(a)= fun(a); %y value for lower limit
f(b)= fun(b); %y value for upper limit
%the actual function
f= (b-a)*(f(a)+f(b))/2;
end
What am i doing wrong? When I type, [f]= NC(-3,0,fun) and set fun= #(x)normpdf(x) . it keeps on returning "Array indices must be positive integers or logical values". Can someone shine some light on this?
The issue is that you try to assign to f(a) where a=0, so you mixed between a vector index and value, as well as use f for two different purposes, one as the output of the function NC, and one for the value of fun(x), that's not a good idea.
Instead you can define the output in a separate variable:
fa=fun(a);
fb=fun(n);
f=(b-a)*(fa+fb)/2;
or just write: f=(b-a)*(fun(a)+fun(b))/2;
The problem lies in the assignments to f(a) and f(b).
The syntax f(x) has three interpretations in MATLAB that are dependent on the type of f:
indexing the array f using the strictly positive integer index (or logical index) x
evaluation of the function handle f using the value of the variable x
manipulation, in some manner, of the symbolic functionf(x) using the symbolic variable x.
Due to MATLAB's dynamic typing and defaulting to double arrays, MATLAB is interpreting the assignments to f(a) and f(b) as the item (1): MATLAB is taking f to be a double array and is expecting a and b to be valid indexes into the array.
Per your intent then, a simple assignment to variable symbols without the parentheses (e.g., fa and fb) should solve your problem.

MATLAB Initial Objective Function Evaluation Error

I am trying to create a plot in MATLAB by iterating over values of a constant (A) with respect to a system of equations. My code is pasted below:
function F=Func1(X, A)
%X(1) is c
%X(2) is h
%X(3) is lambda
%A is technology (some constant)
%a is alpha
a=1;
F(1)=1/X(1)-X(3)
F(2)=X(3)*(X(1)-A*X(2)^a)
F(3)=-1/(24-X(2))-X(3)*A*a*X(2)^(a-1)
clear, clc
init_guess=[0,0,0]
for countA=1:0.01:10
result(countA,:)=[countA,fsolve(#Func1, init_guess)]
end
display('The Loop Has Ended')
display(result)
%plot(result(:,1),result(:,2))
The first set of code, I am defining the set of equations I am attempting to solve. In the second set of lines, I am trying to write a loop which iterates through the values of A that I want, [1,10] with an increment of 0.01. Right now, I am just trying to get my loop code to work, but I keep on getting this error:
"Failure in initial objective function evaluation. FSOLVE cannot continue."
I am not sure why this is the case. From what I understand, this is the result of my initial guess matrix not being the right size, but I believe it should be of size 3, as I am solving for three variables. Additionally, I'm fairly confident there's nothing wrong with how I'm referencing my Func1 code in my Loop code.
Any advice you all could provide would be sincerely appreciated. I've only been working on MATLAB for a few days, so if this is a rather trivial fix, pardon my ignorance. Thanks.
Couple of issues with your code:
1/X(1) in function Func1 is prone to the division by zero miscalculations. I would change it to 1/(X(1)+eps).
If countA is incrementing by 0.01, it cannot be used as an index for result. Perhaps introduce an index ind to increment.
I have included your constant A within the function to clarify what optimization variables are.
Here is the updated code. I don't know if the results are reasonable or not:
init_guess=[0,0,0];
ind = 1;
for countA=1:0.01:10
result(ind,:)=[countA, fsolve(#(X) Func1(X,countA), init_guess)];
ind = ind+1;
end
display('The Loop Has Ended')
display(result)
%plot(result(:,1),result(:,2))
function F=Func1(X,A)
%X(1) is c
%X(2) is h
%X(3) is lambda
%A is technology (some constant)
%a is alpha
a=1;
F(1)=1/(X(1)+eps)-X(3);
F(2)=X(3)*(X(1)-A*X(2)^a);
F(3)=-1/(24-X(2))-X(3)*A*a*X(2)^(a-1);
end

Gradient of implicit symbolic expression in Matlab

The situation I have is as follows:
I have a symbolic expression like:
syms X Y Z K
Ra=51.7;
P=[0 0 200];
Sa=sym('Ra^2==(Z-P(3))^2+(Y-P(2))^2')
Where Y and Z are defined as symbolic. Ra and P are vectors.
I need to get the gradient of Sa but I get an error:
G=gradient(Sa,[Y Z]);
Error using symengine (line 59)
The first argument must be of type 'Type::Arithmetical'.
Error in sym/gradient (line 39)
res = mupadmex('symobj::gradient',fsym.s,x.s);
But if I write the same expression as:
Sa(Y,Z)=((Z-P(3))^2+(Y-P(2))^2-Ra^2);
I get the expected result
G=gradient(Sa,[Y Z])
G(X, Y, Z) =
2*Y
2*Z - 400
Does anyone knows why this is so and if there's any way of using the implicit expression as this is a particular case but in general I have different implicit expressions and my code should be able to deal with them.
I've read the documentation on gradient and some sites, but if I found the answer I didn't notice.
I believe I could use the second form but still, I am curious about this subject.
Thanks for your time.
In the first one Sa is the entire equation, including the ==, while in the second one its a symbolic function depending on 2 variables.
Ultimately the way MATLAB seems to be handle this is that the first one is not derivable (also its dependent in another 2 sym variables, that doesn't know if they are related or not to the derived ones), while the second one gets identified as a function (symbolic) and can get derived.

Can I change the formula of a symbolic function in MATLAB?

I have the following code:
syms t x;
e=symfun(x-t,[x,t]);
In the problem I want to solve x is a function of t but I only know its value at the given t,so I modeled it here as a variable.I want to differentiate e with respect to time without "losing" x,so that I can then substitute it with x'(t) which is known to me.
In another question of mine here,someone suggested that I write the following:
e=symfun(exp(t)-t,[t]);
and after the differentiation check if I can substitute exp(t) with the value of x'(t).
Is this possible?Is there any other neater way?
I'm really not sure I understand what you're asking (and I didn't understand your other question either), but here's an attempt.
Since, x is a function of time, let's make that explicit by making it what the help and documentation for symfun calls an "abstract" or "arbitrary" symbolic function, i.e., one without a definition. In Matlab R2014b:
syms t x(t);
e = symfun(x-t,t)
which returns
e(t) =
x(t) - t
Taking the derivative of the symfun function e with respect to time:
edot = diff(e,t)
returns
edot(t) =
D(x)(t) - 1
the expression for edot(t) is a function of the derivative of x with respect to time:
xdot = diff(x,t)
which is the abstract symfun:
xdot(t) =
D(x)(t)
Now, I think you want to be able to substitute a specific value for xdot (xdot_given) into e(t) for t at t_given. You should be able to do this just using subs, e.g., something like this:
sums t_given xdot_given;
edot_t_given = subs(edot,{t,xdot},{t_given, xdot_given});
You may not need to substitute t if the only parts of edot that are a function of time are the xdot parts.