I am following this tutorial on root locus methods and when writing:
syms s
sys = 1/(3*s^2 + 2*s - 1);
rlocus(sys)
I get:
Error using rlocus
Not enough input arguments.
Why is rlocus expecting more input arguments when the documentation states that one input argument is enough?
rlocus(SYS) computes and plots the root locus of the single-input,
single-output LTI model SYS. The root locus plot is used to analyze
the negative feedback loop
Syntax for rlocus:
rlocus(sys)
rlocus(sys1,sys2,...)
[r,k] = rlocus(sys)
r = rlocus(sys,k)
You are supposed to input a transfer function to rlocus not a symbolic variable. The code you provided gave me the same error but this worked just fine
s=tf('s');
sys = 1/(3*s^2 + 2*s - 1);
rlocus(sys);
Related
I am using MATLAB and I want to find the root of an equation F(x)-u=0. Here u=0.2861 and
F=normcdf(sqrt(lambda/t)*(t/mu-1))+exp(2*lambda/mu)*normcdf(-sqrt(lambda/t)*(t/mu+1)).
The value of lambda and mu are both 1.
I typed the following code
[x,fval] = fzero(#(t) normcdf(sqrt(lambda/t)*(t/mu-1))+exp(2*lambda/mu)*normcdf(-sqrt(lambda/t)*(t/mu+1))-u, 10);
and hope this can help me find the root. I can show mathematically that this equation has unique root. However, I keep on getting the following error
Error using erfc Input must be real and full.
Error in normcdf>localnormcdf (line 128) p(todo) = 0.5 * erfc(-z ./
sqrt(2));
Error in normcdf (line 50) [varargout{1:max(1,nargout)}] =
localnormcdf(uflag,x,varargin{:});
Error in
Test>#(t)normcdf(sqrt(lambda/t)*(t/mu-1))+exp(2*lambda/mu)*normcdf(-sqrt(lambda/t)*(t/mu+1))-u
Error in fzero (line 363)
a = x - dx; fa = FunFcn(a,varargin{:});
Then I did a "brutal force" method.
t = [0:0.001:20];
F = normcdf(sqrt(lambda./t).*(t/mu-1))+exp(2*lambda/mu).*normcdf(-sqrt(lambda./t).*(t/mu+1))-u;
plot(t,F)
I can clearly eyeball that F(t)-u is increasing in t and the root is around 0.4. My question is why fzero does not work in this case and is there a way to make fzero work?
The problem is that the function does not change sign, which is required as the docs say:
x = fzero(fun,x0) tries to find a point x where fun(x) = 0. This
solution is where fun(x) changes sign — fzero cannot find a root of a
function such as x^2.
I broke up your code to make it a bit clearer (at least for me).
lambda = 1;
mu = 1;
u = 1;
% break up function code
arg1 = #(t) +sqrt(lambda./t).*(t./mu-1);
arg2 = #(t) -sqrt(lambda./t).*(t./mu+1);
fnc = #(t) normcdf(arg1(t))+exp(2*lambda/mu).*normcdf(arg2(t))-u;
% call fzero to find the root
% [x,fval] = fzero(fnc, 10);
% plot
x = 0:0.01:10;
plot(x,fnc(x))
The function is not defined for any input t < 0 due to the sqrt in my function handle arg. So if you plot it for values t > 0, you see that it never passes zero.
EDITED: sign mix-up in the arguments. Thx flxx for pointing this out. Plot & code updated. The argument still holds.
I am learning OCTAVE, and I am trying to use LSODE ODE solver to integrate a version of FitzHugh–Nagumo model. My attempt looks like this:
time = linspace(0,200,1000);
u0 = rand(32,32);
v0 = rand(32,32);
vec_u0 = reshape(u0,[1,size(u0)(1)*size(u0)(2)]);
vec_v0 = reshape(v0,[1,size(v0)(1)*size(v0)(2)]);
vec_FHN0 = horzcat(vec_u0,vec_v0);
FHN = lsode("FHN_eq_vec", vec_FHN0, time);
FHN(end)
where all of the functions I have defined are in the repository I have set in GitHub - link. I have created a function that transform the two 2D fields of the FHN model into a row vector (as I understand from the examples here the LSODE integrator use row vector as input). I got this error message:
>> fhn_integrate_lsode
warning: non-integer range used as index
warning: called from
FHN_eq_vec at line 3 column 7
fhn_integrate_lsode at line 9 column 5
error: reshape: can't reshape 0x1 array to 1x1 array
error: called from
FHN_eq_vec at line 4 column 3
fhn_integrate_lsode at line 9 column 5
error: lsode: evaluation of user-supplied function failed
error: called from
fhn_integrate_lsode at line 9 column 5
error: lsode: inconsistent sizes for state and derivative vectors
error: called from
fhn_integrate_lsode at line 9 column 5
>>
Someone knows what could be the problem?
This has been answered at http://octave.1599824.n4.nabble.com/Using-Hindmarsh-s-ODE-solver-LSODE-in-OCTAVE-td4674210.html
However, looking quickly at your code, the system that you want to
solve is probably an ordinary differential equation stemming from a
pde space discretization, i.e.,
$dx(t)/dt = f(x,t) := -K x(t) + r(t)$
with K being a square matrix (Laplacian?!) and f a time-dependent
function of matching dimension. I expect that your system is stiff
(due to the negative Laplacian on the right-hand side) and that you
are happy with errors in the order of 10^(-4). Thus you should adapt
the options of lsode:
lsode_options("integration method","stiff");
lsode_options("absolute tolerance",1e-4);
lsode_options("relative tolerance",1e-4);
Then
T = 0:1e-2:1; % time vector
K = sprandsym(32,1)+eye(32); % symmetric stiffness matrix
x0 = rand(32,1); % initial values
r = #(t) rand(32,1)*sin(t); % excitation vector
f = #(x,t) (-K*x+r(t)); % right-hand-side function
x=lsode (f, x0, T); % get solution from lsode
You should exploit any knowledge on the Jacobian df/dx since this will
speed up computations. It's trivial in the case of linear ODE:
f = {#(x,t) -K*x+r(t), #(x,t) -K}; % right-hand-side function.
On the other hand, if the system has an additional mass matrix
$M dx(t)/dt = -K x(t) + r(t)$
things might become more complicated. You probably want to use another
time stepper. Only if M has full rank then you could do
f = #(x,t) ( M\(-K*x+r(t)) ); % right-hand-side function
which is typically not very efficient.
Bye Sebastian
If someone could help me answer the following question in matlab it would be greatly appreciated, I'm new to the software and am pretty confused.
Use fzero to approximate a root of sin(x) = cos(2x) near x = 1.
The fzero function expects to get a function handle and a starting point. It's result is the closest point which is a root for the function. In your case, we are looking for the root of cos(2x)-sin(x)=0 near x=1. The code you need is:
fun = #(x)(cos(2*x)-sin(x)); % Create an anonymous function handle.
x0 = 1; % Set a starting point.
res = fzero(fun, x0); % Calculate the nearest root.
Your question equals to finding the zeropoint of a function:
f=cos(2.*x)-sin(x)
First, create new function file for f:
function y = funczero01(x)
%Finding the zeros of the function below
y=cos(2.*x)-sin(x);
endfunction
Save the file with funczero01.m and load it to the path.
Then invoke funczero01 in the debugger window:
x0=fzero('funczero01',1)
x0 = 0.52360
Make sure that you truly understand fzero('func',x0). For more details,check Matlab Document.
I have been trying to write a MATLAB code that can take in any function for optimization with as many variables as the user wants.
function Enter_Optimization_Code
clear all
clc
x=[];
U='';
n=input('Enter the number of variables= ')
U=input('Enter function with variables as x(1), x(2), x(3)..= ','s')
start=input('Enter coordinates of the starting point as [1,3,..]= ')
for i=1:n
x(i)=start(i)
end
int(U)
The code is asking the user to enter the number of variables they want and then the function they want to optimize (I didnt write the optimization code yet). For now, I want the code to plug in the value of the starting point into the function and spit out the answer.
e.g. I am entering a function that is x(1)+x(2) and start point as [1,2]. This should cause the code to do the calculation of 1+2=3 and print 3. This is what's happening instead:
Enter the number of variables= 2
n =
2
Enter function with variables as x(1), x(2), x(3)..= x(1)+x(2)
U =
x(1)+x(2)
Enter coordinates of the starting point as [1,3,..]= [1,2]
start =
1 2
x =
1
x =
1 2
Undefined function 'int' for input arguments of type 'char'.
Error in Enter_Optimization_Code (line 17)
Can anybody solve this?
If you are trying to integrate the function with the symbolic function int, you can't pass a string input to that function, it has to be a symbolic expression, check the documentation.
You probably need to do int(sym(U)) instead to convert the string U into a symbolic expression.
EDIT based on comments and using TroyHaskin's suggestion
Here's a version that should work. However, I'm not sure why this is a function, it should really be a script.
function Enter_Optimization_Code
% Not sure why you're using a function, this should really be a script
% clear all should only be used in scripts, not in functions
clc
% n=input('Enter the number of variables= '); not needed
U=input('Enter function with variables as x(1), x(2), x(3)..= ','s');
start=input('Enter coordinates of the starting point as [1,3,..]= ');
f = str2func(['#(x)',U]);
y = feval(f,start);
disp([U 'evaluated at x=([' num2str(start) ']) = ' num2str(y)])
If you want the user to enter the equation in this manner, you can convert the string to an anonymous function using str2func:
fun = str2func(['#(x)',U]);
This will work for function literals like x(1)-x(2)^x(3) and valid function calls my_opt(x).
I have the same kind of problem described in this topic:
Using fzero: Undefined function or method 'isfinite' for input arguments of type 'sym'
Their answers really helped me, but I am still stuck.
I also have to find the zeros of a function of w, this function is defined in several steps:
So the only unknown is w, and I defined other objects such as:
lambda= #(w) ((16*rho(i)*A(i)*w^2*Lprime(i)^2)/(E(j)*I(i)))^0.25;
beta=#(w) lambda*b(i)^0.5;
gamma=#(w) lambda*Lprime(i)^0.5;
Then, I define a 4*4 matrix M2:
M2=#(w) [besselj(4,beta) bessely(4,beta) besseli(4,beta) besselk(4,beta);
besselj(3,beta) bessely(3,beta) besseli(3,beta) -besselk(3,beta);
besselj(2,gamma) bessely(2,gamma) besseli(2,gamma) besselk(2,gamma);
besselj(4,gamma) bessely(4,gamma) besseli(4,gamma) besselk(4,gamma)];
Then the equation to be solved is: det(M2)=0. But w=0 is one of the solutions, and I want the first non-zero solution, so I wrote:
delta = #(w) det(M2);
S(i,j)=fzero(delta,500);
Then I run the program, and Matlab says:
??? Error using ==> fzero at 235
FZERO cannot continue because user supplied function_handle ==> #(w)det(M2)
failed with the error below.
Undefined function or method 'det' for input arguments of type 'function_handle'.
Error in ==> frequencies at 57
S(i,j)=fzero(delta,500);
I also tried with the subs and the eval methods, and they don't work either, the error messages are in those cases:
??? Undefined function or method 'isfinite' for input arguments of type 'sym'.
Error in ==> fzero at 323
elseif ~isfinite(fx) || ~isreal(fx)
Error in ==> frequencies at 58
S(i,j)=fzero(#(w) subs(delta,'w',w),500);
Which is the same error as edio's I guess. And:
??? Error using ==> fzero at 307
FZERO cannot continue because user supplied function_handle ==> #(w)eval(delta)
failed with the error below.
Undefined function or method 'eval' for input arguments of type 'function_handle'.
Error in ==> frequencies at 59
S(i,j)=fzero(#(w)eval(delta),500);
Can you help me please?
Your problem appears to be that you are never evaluating your anonymous functions when you place them within other anonymous functions. For example, you define the function lambda as such:
lambda = #(w) ((16*rho(i)*A(i)*w^2*Lprime(i)^2)/(E(j)*I(i)))^0.25;
But when you use it in beta, you need to evaluate it using the input value for w, like so:
beta = #(w) lambda(w)*b(i)^0.5;
%# ^--------------Pass w to lambda to evaluate the function
As such, I believe your other anonymous functions should be defined as follows:
gamma = #(w) lambda(w)*Lprime(i)^0.5;
M2 = #(w) [besselj(4,beta(w)) bessely(4,beta(w)) besseli(4,beta(w)) ...
besselk(4,beta(w)); ...
besselj(3,beta(w)) bessely(3,beta(w)) besseli(3,beta(w)) ...
-besselk(3,beta(w)); ...
besselj(2,gamma(w)) bessely(2,gamma(w)) besseli(2,gamma(w)) ...
besselk(2,gamma(w)); ...
besselj(4,gamma(w)) bessely(4,gamma(w)) besseli(4,gamma(w)) ...
besselk(4,gamma(w))];
delta = #(w) det(M2(w));
A note about efficiency...
There is a GLARING efficiency problem I'm noticing here. By using anonymous functions instead of any other type of function (primary functions, nested functions, or subfunctions) you are going to end up evaluating the same function with the same input multiple times over.
For example, each time you evaluate M2 to create your matrix you will be evaluating both beta and gamma 8 times with the same input! Notice the improvement you could make by placing M2 in a function and passing as input w and the two function handles beta and gamma:
function newMatrix = M2(w,betaFcn,gammaFcn)
bw = betaFcn(w); %# Evaluate the beta function once
gw = gammaFcn(w); %# Evaluate the gamma function once
newMatrix = [besselj(4,bw) bessely(4,bw) besseli(4,bw) besselk(4,bw); ...
besselj(3,bw) bessely(3,bw) besseli(3,bw) -besselk(3,bw); ...
besselj(2,gw) bessely(2,gw) besseli(2,gw) besselk(2,gw); ...
besselj(4,gw) bessely(4,gw) besseli(4,gw) besselk(4,gw)];
end
And your new delta function would look like this:
delta = #(w) det(M2(w,beta,gamma));
Hi thank you very much for your help.
It works, but the last line has to change, obviously (it still took me 10 minuts for figure it out):
lambda= #(w) ((16*rho(i)*A(i)*w^2*Lprime(i)^2)/(E(j)*I(i)))^0.25;
beta=#(w) lambda(w)*b(i)^0.5;
gamma=#(w) lambda(w)*Lprime(i)^0.5;
M2=#(w) [besselj(4,beta(w)) bessely(4,beta(w)) besseli(4,beta(w)) besselk(4,beta(w));
besselj(3,beta(w)) bessely(3,beta(w)) besseli(3,beta(w)) -besselk(3,beta(w));
besselj(2,gamma(w)) bessely(2,gamma(w)) besseli(2,gamma(w)) besselk(2,gamma(w));
besselj(4,gamma(w)) bessely(4,gamma(w)) besseli(4,gamma(w)) besselk(4,gamma(w))];
delta = #(w) det(M2(w));
S(i,j)=fzero(#(w) delta(w),500);
And now it is really faster than before, in another case where the function solve could handle the resolution, it took like 10 seconds for each loop, now it's like 0.06 seconds
I will try your other solution to see the improvements.
Thank you a lot.