How can I solve BVP for unknown boundary? - maple

I have simple BVP for which one of boundaries is given as "L". My attempts to solve it gives various errors. One of the last attempts clearly shows that Maple "thinks" that L is rather another variable than unknown constant.
de := diff(y(x), x$4)-lambda*y(x) = 0;
sol:=dsolve({de,y(0)=0,(D##2)(y)(0)=0, y(L)=0,(D##2)(y)(L)=0}) assuming lambda<0;
What can I do?

The basic help page for the dsolve command is pretty clear on this.
See the second Calling Sequence example at top, where y(x) is supplied in the second argument.
The Parameters section, immediately below that, describes that second argument thusly:
y(x) - any indeterminate function of one variable, or a set or list of them,
representing the unknowns of the ODE problem
And so that is how you can specify which are the dependent and independent variables. Eg,
de := diff(y(x), x$4)-lambda*y(x) = 0:
sol := dsolve( {de, y(0)=0, (D##2)(y)(0)=0, y(L)=0, (D##2)(y)(L)=0},
{y(x)} ) assuming lambda<0;

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.)

using ode45 to solve y'=y adnd y'=t in Matlab

I first defined functions for dy/dt=y and dy/dt=t:
function dy=d(y):
dy=y
end
function ddy=dd(t):
ddy=t
end
And then I used ode45, respectively:
[t,y]=ode45('d',[1 10],1)
[t,y]=ode45('dd',[1 10],1)
which returns the following error: Error using d
Too many input arguments.
My question is:
Where did I go wrong?
How does Matlab know whether y or t is the independent variable? When I define the first function, it could be reasonably interpreted as dt/dy=y instead of dy/dt=y. Is there a built-in convention for defining functions?
First things first: the docs on ode45 are on the mathworks website, or you can get them from the console by entering help ode45.
The function you pass in needs to take two variables, y then t. As you noticed, with just one it would be impossible to distinguish a function of only y from a function of only t. The first argument has to be the independent, the second is the dependent.
Try defining your function as dy = d(t, y) and ddy = dd(t, y) with the same bodies.
one other note, while using a string representing the function name should work, you can use #d and #dd to reference the functions directly.

MATLAB Using fzero - returns error

I'm trying to use the MATLAB function fzero properly but my program keeps returning an error message. This is my code (made up of two m-files):
friction_zero.m
function fric_zero = friction_zero(reynolds)
fric_zero = 0.25*power(log10(5.74/(power(reynolds,0.9))),-2);
flow.m
function f = flow(fric)
f = 1/(sqrt(fric))-1.873*log10(reynolds*sqrt(fric))-233/((reynolds*sqrt(fric))^0.9)-0.2361;
f_initial = friction_zero(power(10,4));
z = fzero(#flow,f_initial)
The goal is to return z as the root for the equation specified by f when flow.m is run.
I believe I have the correct syntax as I have spent a couple of hours online looking at examples. What happens is that it returns the following error message:
"Undefined function or variable 'fric'."
(Of course it's undefined, it's the variable I'm trying to solve!)
Can someone point out to me what I've done wrong? Thanks
EDIT
Thanks to all who helped! You have assisted me to eventually figure out my problem.
I had to add another file. Here is a full summary of the completed code with output.
friction_zero.m
function fric_zero = friction_zero(re)
fric_zero = 0.25*power(log10(5.74/(power(re,0.9))),-2); %starting value for fric
flow.m
function z = flow(fric)
re = power(10,4);
z = 1/(sqrt(fric))-1.873*log10(re*sqrt(fric))-233/((re*sqrt(fric))^0.9)-0.2361;
flow2.m
f_initial = friction_zero(re); %arbitrary starting value (Reynolds)
x = #flow;
fric_root = fzero(x,f_initial)
This returns an output of:
fric_root = 0.0235
Which seems to be the correct answer (phew!)
I realised that (1) I didn't define reynolds (which is now just re) in the right place, and (2) I was trying to do too much and thus skipped out on the line x = #flow;, for some reason when I added the extra line in, MATLAB stopped complaining. Not sure why it wouldn't have just taken #flow straight into fzero().
Once again, thanks :)
You need to make sure that f is a function in your code. This is simply an expression with reynolds being a constant when it isn't defined. As such, wrap this as an anonymous function with fric as the input variable. Also, you need to make sure the output variable from your function is z, not f. Since you're solving for fric, you don't need to specify this as the input variable into flow. Also, you need to specify f as the input into fzero, not flow. flow is the name of your main function. In addition, reynolds in flow is not defined, so I'm going to assume that it's the same as what you specified to friction_zero. With these edits, try doing this:
function z = flow()
reynolds = power(10,4);
f = #(fric) 1/(sqrt(fric))-1.873*log10(reynolds*sqrt(fric))-233/((reynolds*sqrt(fric))^0.9)-0.2361;
f_initial = friction_zero(reynolds);
z = fzero(#f, f_initial); %// You're solving for `f`, not flow. flow is your function name
The reason that you have a problem is because flow is called without argument I think. You should read a little more about matlab functions. By the way, reynolds is not defined either.
I am afraid I cannot help you completely since I have not been doing fluid mechanics. However, I can tell you about functions.
A matlab function definition looks something like this:
function x0 = f(xGuess)
a = 2;
fcn =#(t) a*t.^3+t; % t must not be an input to f.
disp(fcn);
a = 3;
disp(fcn);
x0 = fsolve(fcn1,xGuess); % x0 is calculated here
The function can then ne called as myX0 = f(myGuess). When you define a matlab function with arguments and return values, you must tell matlab what to do with them. Matlab cannot guess that. In this function you tell matlab to use xGuess as an initial guess to fsolve, when solving the anonymous function fcn. Notice also that matlab does not assume that an undefined variable is an independent variable. You need to tell matlab that now I want to create an anonymous function fcn which have an independent variable t.
Observation 1: I use .^. This is since the function will take an argument an evaluate it and this argument can also be a vector. In this particulat case I want pointwise evaluation. This is not really necessary when using fsolve but it is good practice if f is not a matrix equation, since "vectorization" is often used in matlab.
Observation 2: notice that even if a changes its value the function does not change. This is since matlab passes the value of a variable when defining a function and not the variable itself. A c programmer would say that a variable is passed by its value and not by a pointer. This means that fcn is really defined as fcn = #(x) 2*t.^3+t;. Using the variable a is just a conveniance (constants can may also be complicated to find, but when found they are just a value).
Armed with this knowledge, you should be able to tackle the problem in front of you. Also, the recursive call to flow in your function will eventuallt cause a crash. When you write a function that calls itself like this you must have a stopping criterium, something to tell the program when to stop. As it is now, flow will call ifself in the last row, like z = fzero(#flow,f_initial) for 500 times and then crash. Alos it is possible as well to define functions with zero inputs:
function plancksConstant = h()
plancksConstant = 6.62606957eāˆ’34;
Where the call h or h() will return Plancks constant.
Good luck!

Solving a system of equations using a specific initial guess in Matlab

I have a question about solving a system of equations and initial guesses of the solution. I want to solve a system of equations where "x", a Tx1 vector, are my unknowns, "a" a Tx1 vector and "B" a TxT matrix. "f" is the function I want to solve for. I want to solve for "x" such that "f==0":
x = sym('x', [T,1]);
f = -x+1-(1+erf((a - B*x)./sqrt(2)))/2; % -x+1-normcdf(a-B*x)
Spp = solve(f==0, x);
I use Matlab's solve (or vpasolve) functions to obtain values. If the entries of "B" are above a certain value I should observe a jump for changing values of "a" (which I do). However, depending on the initial guess of the solution, i.e. for example either the initial guess is 1 or 0, the position of the jump occurs at different values for "a", a hysteresis cycle occurs.
I solved the equation using fzero for T=1. I specified the initial guess and indeed was able to observe the hysteresis cycle. For T>1, fzero does not work anymore and I tried solve as well as vpasolve. solve does not allow initial guesses and for vpasolve I even get with examples from Matlab's help site an error whenever I include more than the system of equations and the unknown variables, i.e. vpasolve(eqn,var) works fine but for vpasolve(eqn,var,init_guess) I get the following error:
Error using getEqnsVars (line 50) Expecting two arguments: a vector of
equations and a vector of variables.
Error in sym/vpasolve (line 91) [eqns,vars] =
getEqnsVars(varargin{1:end-1});
What am I doing wrong? Is there another function I could try?
Edit: I didn't use 'fsolve' but 'fzero' to find the roots.
You can use slightly different definition of function f and try fsolve. Here you don't have to explicitly define x as symbolic variables.
f = #(x) -x+1-(1+erf((a - B*x)./sqrt(2)))/2; % -x+1-normcdf(a-B*x)
initial_guess = zeros(T,1);
Spp = fsolve(f,initial_guess);

Can I Expand "Nested" Symbolic Functions in Matlab?

I'm trying to model the effect of different filter "building blocks" on a system which is a construct based on these filters.
I would like the basic filters to be "modular", i.e. they should be "replaceable", without rewriting the construct which is based upon the basic filters.
For example, I have a system of filters G_0, G_1, which is defined in terms of some basic filters called H_0 and H_1.
I'm trying to do the following:
syms z
syms H_0(z) H_1(z)
G_0(z)=H_0(z^(4))*H_0(z^(2))*H_0(z)
G_1(z)=H_1(z^(4))*H_0(z^(2))*H_0(z)
This declares the z-domain I'd like to work in, and a construct of two filters G_0,G_1, based on the basic filters H_0,H_1.
Now, I'm trying to evaluate the construct in terms of some basic filters:
H_1(z) = 1+z^-1
H_0(z) = 1+0*z^-1
What I would like to get at this point is an expanded polynomial of z.
E.g. for the declarations above, I'd like to see that G_0(z)=1, and that G_1(z)=1+z^(-4).
I've tried stuff like "subs(G_0(z))", "formula(G_0(z))", "formula(subs(subs(G_0(z))))", but I keep getting result in terms of H_0 and H_1.
Any advice? Many thanks in advance.
Edit - some clarifications:
In reality, I have 10-20 transfer functions like G_0 and G_1, so I'm trying to avoid re-declaring all of them every time I change the basic blocks H_0 and H_1. The basic blocks H_0 and H_1 would actually be of a much higher degree than they are in the example here.
G_0 and G_1 will not change after being declared, only H_0 and H_1 will.
H_0(z^2) means using z^2 as an argument for H_0(z). So wherever z appears in the declaration of H_0, z^2 should be plugged in
The desired output is a function in terms of z, not H_0 and H_1.
A workable hack is having an m-File containing the declarations of the construct (G_0 and G_1 in this example), which is run every time H_0 and H_1 are redefined. I was wondering if there's a more elegant way of doing it, along the lines of the (non-working) code shown above.
This seems to work quite nicely, and is very easily extendable. I redefined H_0 to H_1 as an example only.
syms z
H_1(z) = 1+z^-1;
H_0(z) = 1+0*z^-1;
G_0=#(Ha,z) Ha(z^(4))*Ha(z^(2))*Ha(z);
G_1=#(Ha,Hb,z) Hb(z^(4))*Ha(z^(2))*Ha(z);
G_0(H_0,z)
G_1(H_0,H_1,z)
H_0=#(z) H_1(z);
G_0(H_0,z)
G_1(H_0,H_1,z)
This seems to be a namespace issue. You can't define a symbolic expression or function in terms of arbitrary/abstract symfuns and then later on define these symfuns explicitly and be able to use them to obtain an exploit form of the original symbolic expression or function (at least not easily). Here's an example of how a symbolic function can be replaced by name:
syms z y(z)
x(z) = y(z);
y(z) = z^2; % Redefines y(z)
subs(x,'y(z)',y)
Unfortunately, this method depends on specifying the function(s) to be substituted exactly ā€“ because strings are used, Matlab sees arbitrary/abstract symfuns with different arguments as different functions. So the following example does not work as it returns y(z^2):
syms z y(z)
x(z) = y(z^2); % Function of z^2 instead
y(z) = z^2;
subs(x,'y(z)',y)
But if the last line was changed to subs(x,'y(z^2)',y) it would work.
So one option might be to form strings for case, but that seems overly complex and inelegant. I think that it would make more sense to simply not explicitly (re)define your arbitrary/abstract H_0, H_1, etc. functions and instead use other variables. In terms of the simple example:
syms z y(z)
x(z) = y(z^2);
y_(z) = z^2; % Create new explicit symfun
subs(x,y,y_)
which returns z^4. For your code:
syms z H_0(z) H_1(z)
G_0(z) = H_0(z^4)*H_0(z^2)*H_0(z);
G_1(z) = H_1(z^4)*H_0(z^2)*H_0(z);
H_0_(z) = 1+0*z^-1;
H_1_(z) = 1+z^-1;
subs(G_0, {H_0, H_1}, {H_0_, H_1_})
subs(G_1, {H_0, H_1}, {H_0_, H_1_})
which returns
ans(z) =
1
ans(z) =
1/z^4 + 1
You can then change H_0_ and H_1_, etc. at will and use subs to evaluateG_1andG_2` again.