Matlab Not enough input arguments [closed] - matlab

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
A nonlinear code
% This produces a black waterfall plot of the solution of
% u_t + 6u^2u_x + u_xxx - (b(x,t)u)_x = 0 on [-pi,pi]
% and returns the the time vector to use for efft.m
% The code is a simple modification of Trefethen's example p27.m
% The initial data is given by a double soliton with parameters
% a1, a2 (centers) and c1, c2 (velocities).
% The arguments of mkdvb.m are time t, parameters given in a vector form
% [a1,a2,c1,c2], a function bb = b(x,t), and the log_2 of the number of
% x grid points (the default value is 8).
% It return the time vector T, the position vector X, and the matrix of
% solution values at times given by T.
%
% Here is an example
%
% T = mkdvB(#(x,t) 100*cos(x-10^3*t).^2-50*sin(2*x+10^3*t), 0.05, [1,-1,4,-11],9)
%
% The time vector T can then be entered into effdyn.m code to compare the
% solution to the effective dynamics:
%
% [T,Y]=effdyn(#(x,t) 100*cos(x-10^3*t).^2-50*sin(2*x+10^3*t), T, [1,-1,4,-11])
%
function [T,X,U] = mkdvb2(fun,tmax,ZZ,N)
if (nargin < 2 )
tmax=0.065;
end
if (nargin < 3)
ZZ = [-1,-2,-6,9];
end
if (nargin < 4)
N = 8;
end
N = 2^N;
% Set up grid and two-soliton initial data:
dt = .4/N^2; x = (2*pi/N)*(-N/2:N/2-1)';
drawnow, set(gcf,'renderer','zbuffer')
u=sqrt(2)*qu(x,ZZ);
v = fft(u); k = [0:N/2-1 0 -N/2+1:-1]'; ik3 = 1i*k.^3;
% Solve PDE and plot results:
nplt = floor((tmax/25)/dt); nmax = round(tmax/dt);
udata = u; tdata = 0; h = waitbar(0,'please wait...');
for n = 1:nmax %#ok<ALIGN>
t = n*dt; g = -1i*dt*k;
qz=fun(x,t);
E = exp(dt*ik3/2); E2 = E.^2;
a = g.*fft(real( ifft( v ) ).^3 - ifft( v ).*qz);
b = g.*fft(real( ifft(E.*(v+a/2)) ).^3 - ifft(E.*(v+a/2)).*qz);
c = g.*fft(real( ifft(E.*v + b/2) ).^3 - ifft(E.*v + b/2).*qz);
d = g.*fft(real( ifft(E2.*v+E.*c) ).^3 - ifft(E2.*v+E.*c).*qz);
v = E2.*v + (E2.*a + 2*E.*(b+c) + d)/6;
if mod(n,nplt) == 0
u = real(ifft(v)); waitbar(n/nmax)
udata = [udata u]; tdata = [tdata t];
end
end
udata = udata/sqrt(2);
hold on
[~,P] = size(tdata);
z1=0;
z2=0;
for j=1:P
plot3(x,tdata(j)+0*x, udata(:,j) );
z1=max(z1,max(udata(:,j)));
z2=min(z1,min(udata(:,j)));
end
T = tdata;
U = udata;
X = x;
view(0,60)
xlabel x, ylabel t, axis([-pi pi 0 tmax z2 z1]), grid off
close(h)
function qu = qu(x,ZZ)
k1 = ZZ(3)*(x - ZZ(1));
k2 = ZZ(4)*(x - ZZ(2));
ga1 = exp(-k1);
ga2 = - exp(-k2);
m11=(1+ga1.^2)./(2*ZZ(3));
m22=(1+ga2.^2)./(2*ZZ(4));
m12=(1+ga1.*ga2)./(ZZ(3)+ZZ(4));
M=m11.*m22 - m12.^2;
M1=ga1.*(m12 - m22) + ga2.*(m12-m11);
qu = M1./M;

The code is a bit messy, but fortunately this kind of problem is very easy to troubleshoot.
Save your code in a function or script
turn on dbstop if error
See where the error occurs
You should now be on a line like
[y1, y2] = f(x1,x2,x3)
Try to evaluate all input arguments, at least 1 of them will not exist (yet?).

Related

Finding Percent Error of a Fourier Series

Find the error as a function of n, where the error is defined as the difference between two the voltage from the Fourier series (vF (t)) and the value from the ideal function (v(t)), normalized to the maximum magnitude (Vm ):
I am given this prompt where Vm = 1 V. Below this line is the code which I have written.
I am trying to write a function to solve this question: Plot the error versus time for n=3,n=5,n=10, and n=50. (10points). What does it look like I am doing incorrectly?
clc;
close all;
clear all;
% define the signal parameters
Vm = 1;
T = 1;
w0 = 2*pi/T;
% define the symbolic variables
syms n t;
% define the signal
v1 = Vm*sin(4*pi*t/T);
v2 = 2*Vm*sin(4*pi*t/T);
% evaluate the fourier series integral
an1 = 2/T*int(v1*cos(n*w0*t),0,T/2) + 2/T*int(v2*cos(n*w0*t),T/2,T);
bn1 = 2/T*int(v1*sin(n*w0*t),0,T/2) + 2/T*int(v2*sin(n*w0*t),T/2,T);
a0 = 1/T*int(v1,0,T/2) + 1/T*int(v2,T/2,T);
% obtain C by substituting n in c[n]
nmax = 100;
n = 1:nmax;
a = subs(an1);
b = subs(bn1);
% define the time vector
ts = 1e-2; % ts is sampling the
t = 0:ts:3*T-ts;
% directly plot the signal x(t)
t1 = 0:ts:T-ts;
v1 = Vm*sin(4*pi*t1/T).*(t1<=T/2);
v2 = 2*Vm*sin(4*pi*t1/T).*(t1>T/2).*(t1<T);
v = v1+v2;
x = repmat(v,1,3);
% Now fourier series reconstruction
N = [3];
for p = 1:length(N)
for i = 1:length(t)
for k = N(p)
x(k,i) = a(k)*cos(k*w0*t(i)) + b(k)*sin(k*w0*t(i));
end
% y(k,i) = a0+sum(x(:,i)); % Add DC term
end
end
z = a0 + sum(x);
figure(1);
plot(t,z);
%Percent error
function [per_error] = percent_error(measured, actual)
per_error = abs(( (measured - actual) ./ 1) * 100);
end
The purpose of the forum is helping with specific technical questions, not doing your homework.

how to find satistics of the fitted parameter of an equation [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
For instance: a, b, c and n are the three constants, which are required to be calculated by using data fitting method in a particular equation.
How can I calculate the statistics (mean, standard deviation, variance, skewness value and student t-test value) of the parameters as of a custom equation, for example the quadratic plateau equation?
Example:
x=[0,40,80,100,120,150,170,200],
y=[1865,2855,3608,4057,4343,4389,4415,4478]
y=a*(x+n)^2+b*(x+n)+c, x < xc(Ymax) ....(1) y=yp, x >= xc(Ymax) ....(2)
I have fitted this equation by given code:
yf = #(b,x) b(1).*(x+n).^2+b(2)*(x+n)+b(3); B0 = [0.006; 21; 1878];
[Bm,normresm] = fminsearch(#(b) norm(y - yf(b,x)), B0); a=Bm(1);
b=Bm(2); c=Bm(3); xc=(-b/(2*a))-n; p=p=a*(xc+n)^2+b*(xc+n)+c;
if (x < xc)
yfit = a.*(x+n).^2+ b*(x+n)+c;
else
yfit = p;
end
plot(x,yfit,'*')
hold on; plot(x,y); hold off
Note: I have already used the polyfit command, it was helpful and provided me the results. However, I really don’t find it suitable, as there is no option to customize the equation. Can I find these statistics by any code?
Questions 1, 2 and 4)
Good practice is to set initial values close to the final result if you have previous knowledge about the equation system:
What you have is an overdetermined system of linear equations.
y(1) = a*x(1)^2 + b*x(1) + c
y(2) = a*x(2)^2 + b*x(2) + c
y(3) = a*x(3)^2 + b*x(3) + c
…
y(n) = a*x(n)^2 + b*x(n) + c
or in general:
y = A*X, where
A = [a; b; c]
X = [x(1)^2 x(1) 1;
x(2)^2 x(2) 1;
x(3)^2 x(2) 1;
...
x(n)^2 x(n) 1]
One of the common practices to fit the overdetermined system (since it has no solution) is "least square fit" (mldivide,\ (link))
x=[0; 40; 80; 100; 120; 150; 170; 200];
y=[1865; 2855; 3608; 4057; 4343; 4389; 4415; 4478];
X = [x.^2 x ones(numel(x),1)];
A = y\X;
a0=A(1); %- initial value for a
b0=A(2); %- initial value for b
c0=A(3); %- initial value for c
You can customize equation, when you customize your X and A
but you also can set initial values to ones, it should have neglectable small impact on the result. More related to Question 4
a0=1;
b0=1;
c0=1;
or to random values
rng(10);
A = rand(3,1);
a0=A(1);
b0=A(2);
c0=A(3);
Question 3 - Statistics
If you need more control on monitoring of optimization process, use more general form of writing anonymous function (in code below> myfun) to save all intermediate values of parameters (a_iter, b_iter, c_iter)
function Fiting_ex()
global a_iter b_iter c_iter
a_iter = 0;
b_iter = 0;
c_iter = 0;
x=[0; 40; 80; 100; 120; 150; 170; 200];
y=[1865; 2855; 3608; 4057; 4343; 4389; 4415; 4478];
X = [x.^2 x ones(numel(x),1)];
A = y\X;
a0=A(1);
b0=A(2);
c0=A(3);
B0 = [a0; b0; c0];
[Bm,normresm] = fminsearch(#(b) myfun(b,x,y),B0);
a=Bm(1);
b=Bm(2);
c=Bm(3);
xc=-b/(2*a);
p=c-(b^2/(4*a));
yfit = zeros(numel(x),1);
for i=1:numel(x)
if (x(i) < xc)
yfit(i) = a.*x(i).^2+ b*x(i)+c;
else
yfit(i) = p;
end
end
plot(x,yfit,'*')
hold on;
plot(x,y);
hold off
% Statistic on optimization process
a_mean = mean(a_iter(2:end)); % mean value
a_var = var(a_iter(2:end)); % variance
a_std = std(a_iter(2:end)); % standard deviation
function f = myfun(Bm, x, y)
global a_iter b_iter c_iter
a_iter = [a_iter Bm(1)];
b_iter = [b_iter Bm(2)];
c_iter = [c_iter Bm(3)];
yf = Bm(1)*(x).^2+Bm(2)*(x)+Bm(3);
a=Bm(1);
b=Bm(2);
c=Bm(3);
xc=-b/(2*a);
p=c-(b^2/(4*a));
yfit = zeros(numel(x),1);
for i=1:numel(x)
if (x(i) < xc)
yfit(i) = a.*x(i).^2+ b*x(i)+c;
else
yfit(i) = p;
end
end
f = norm(y - yfit);

Solution of Burger equation by Newton-Raphson method in Matlab

I am solving Burger equation with Newton-Raphson method in Mathlab.
For the description of the problem see 1.
My problem is the following this code finds the solution upto time
$t=1$, but at this time a discontinuity develops and then the wave
moves forward (like a step function), but this code does not produce
correct solutions after time $t=1$.
Any suggestions or comments to improve the code.
Here is the Matlab code that I am using
function BurgerFSolve2
clc; clear;
% define a 1D mesh
a = -1; b = 3; Nx = 100;
x = linspace(a,b,Nx);
dx = (b-a)/Nx;
J = length(x);
% Iinitial condition
p_init = zeros(size(x));
p_init(x<=0) = 1;
p_init(x>0 & x<1)= 1-x(x>0 & x<1);
% storing results
P = zeros(length(p_init),3001);
P(:,1) = p_init;
% Boundary condition
pL = 1; pR = 0;
% solver
dt = 0.001;
t = 0;
T = zeros(1,3001);
c = dt/dx;
for i = 1:3000
t = t+dt;
T(i+1) = t;
options=optimset('Display','iter'); % Option to display output
p = fsolve(#(p) myfun1(p, pL, pR, c, J, P(:,i)), p_init, ...
options);
% Call solver
P(:,i+1) = p;
p_init = p;
figure(1);
plot(x, p, '-o');
title(['t= ' num2str(t) ' s']);
drawnow;
end
end
function F = myfun1(p, pL, pR, c, J, p_Old)
% Rewrite the equation in the form F(x) = 0
F(1) = p(1) + c*(p(1)^2 - p(1)*pL) - p_Old(1);
for i=2:J-1
F(i) = p(i) + c*(p(i)^2 - p(i-1)*p(i)) - p_Old(i);
end
F(J) = p(J) + c*(p(J)^2 - p(J-1)*p(J)) - p_Old(J);
end

Can't recover the parameters of a model using ode45

I am trying to simulate the rotation dynamics of a system. I am testing my code to verify that it's working using simulation, but I never recovered the parameters I pass to the model. In other words, I can't re-estimate the parameters I chose for the model.
I am using MATLAB for that and specifically ode45. Here is my code:
% Load the input-output data
[torque outputs] = DataLogs2();
u = torque;
% using the simulation data
Ixx = 1.00;
Iyy = 2.00;
Izz = 3.00;
x0 = [0; 0; 0];
Ts = .02;
t = 0:Ts:Ts * ( length(u) - 1 );
[ T, x ] = ode45( #(t,x) rotationDyn( t, x, u(1+floor(t/Ts),:), Ixx, Iyy, Izz), t, x0 );
w = x';
N = length(w);
q = 1; % a counter for the A and B matrices
% The Algorithm
for k=1:1:N
w_telda = [ 0 -w(3, k) w(2,k); ...
w(3,k) 0 -w(1,k); ...
-w(2,k) w(1,k) 0 ];
if k == N % to handle the problem of the last iteration
w_dash(:,k) = (-w(:,k))/Ts;
else
w_dash(:,k) = (w(:,k+1)-w(:,k))/Ts;
end
a = kron( w_dash(:,k)', eye(3) ) + kron( w(:,k)', w_telda );
A(q:q+2,:) = a; % a 3N*9 matrix
B(q:q+2,:) = u(k,:)'; % a 3N*1 matrix % u(:,k)
q = q + 3;
end
% Forcing J to be diagonal. This is the case when we consider our quadcopter as two thin uniform
% rods crossed at the origin with a point mass (motor) at the end of each.
A_new = [A(:, 1) A(:, 5) A(:, 9)];
vec_J_diag = A_new\B;
J_diag = diag([vec_J_diag(1), vec_J_diag(2), vec_J_diag(3)])
eigenvalues_J_diag = eig(J_diag)
error = norm(A_new*vec_J_diag - B)
where my dynamic model is defined as:
function [dw, y] = rotationDyn(t, w, tau, Ixx, Iyy, Izz, varargin)
% The output equation
y = [w(1); w(2); w(3)];
% State equation
% dw = (I^-1)*( tau - cross(w, I*w) );
dw = [Ixx^-1 * tau(1) - ((Izz-Iyy)/Ixx)*w(2)*w(3);
Iyy^-1 * tau(2) - ((Ixx-Izz)/Iyy)*w(1)*w(3);
Izz^-1 * tau(3) - ((Iyy-Ixx)/Izz)*w(1)*w(2)];
end
Practically, what this code should do, is to calculate the eigenvalues of the inertia matrix, J, i.e. to recover Ixx, Iyy, and Izz that I passed to the model at the very begining (1, 2 and 3), but all what I get is wrong results.
Is the problem with using ode45?
Well the problem wasn't in the ode45 instruction, the problem is that in system identification one can create an n-1 samples-signal from an n samples-signal, thus the loop has to end at N-1 in the above code.

Trying to solve Simultaneous equations in matlab, cannot work out how to format the functions

I was given a piece of Matlab code by a lecturer recently for a way to solve simultaneous equations using the Newton-Raphson method with a jacobian matrix (I've also left in his comments). However, although he's provided me with the basic code I cannot seem to get it working no matter how hard I try. I've spent many hours trying to introduce the 'func' function but to no avail, frequently getting the message that there aren't enough inputs. Any help would be greatly appreciated, especially with how to write the 'func' function.
function root = newtonRaphson2(func,x,tol)
% Newton-Raphson method of finding a root of simultaneous
% equations fi(x1,x2,...,xn) = 0, i = 1,2,...,n.
% USAGE: root = newtonRaphson2(func,x,tol)
% INPUT:
% func = handle of function that returns[f1,f2,...,fn].
% x = starting solution vector [x1,x2,...,xn].
% tol = error tolerance (default is 1.0e4*eps).
% OUTPUT:
% root = solution vector.
if size(x,1) == 1; x = x'; end % x must be column vector
for i = 1:30
[jac,f0] = jacobian(func,x);
if sqrt(dot(f0,f0)/length(x)) < tol
root = x; return
end
dx = jac\(-f0);
x = x + dx;
if sqrt(dot(dx,dx)/length(x)) < tol
root = x; return
end
end
error('Too many iterations')
function [jac,f0] = jacobian(func,x)
% Returns the Jacobian matrix and f(x).
h = 1.0e-4;
n = length(x);
jac = zeros(n);
f0 = feval(func,x);
for i =1:n
temp = x(i);
x(i) = temp + h;
f1 = feval(func,x);
x(i) = temp;
jac(:,i) = (f1 - f0)/h;
end
The simultaneous equations to be solved are:
sin(x)+y^2+ln(z)-7=0
3x+2^y-z^3+1=0
x+y+Z-=0
with the starting point (1,1,1).
However, these are arbitrary and can be replaced with anything, I mainly just need to know the general format.
Many thanks, I know this may be a very simple task but I've only recently started teaching myself Matlab.
You need to create a new file called myfunc.m (or whatever name you like) which takes a single input parameter - a column vector x - and returns a single output vector - a column vector y such that y = f(x).
For example,
function y = myfunc(x)
y = zeros(3, 1);
y(1) = sin(x(1)) + x(2)^2 + log(x(3)) - 7;
y(2) = 3*x(1) + 2^x(2) - x(3)^3 + 1;
y(3) = x(1) + x(2) + x(3);
end
You can then refer to this function as #myfunc as in
>> newtonRaphson2(#myfunc, [1;1;1], 1e-6);
The reason for the special notation is that Matlab allows you to call a function with no parameters by omitting the parens () that follow it. So for example, Matlab interprets myfunc as you calling the function with no arguments (so it tries to replace it with its result) whereas #myfunc refers to the function itself, rather than its result.
Alternatively you can write a function directly using the # notation, as in
>> newtonRaphson2(#(x) exp(x) - 3*x, 2, 1e-2)
ans =
1.5315
>> newtonRaphson2(#(x) exp(x) - 3*x, 1, 1e-2)
ans =
0.6190
which are the two roots of the equation exp(x) - 3 * x = 0.
Edit - as an aside, your professor has terrible coding style (if the code in your question is a direct copy-paste of what he gave you, and you haven't mangled it along the way). It would be better to write the code like this, with indentation making it clear what the structure of the code is.
function root = newtonRaphson2(func, x, tol)
% Newton-Raphson method of finding a root of simultaneous
% equations fi(x1,x2,...,xn) = 0, i = 1,2,...,n.
%
% USAGE: root = newtonRaphson2(func,x,tol)
%
% INPUT:
% func = handle of function that returns[f1,f2,...,fn].
% x = starting solution vector [x1,x2,...,xn].
% tol = error tolerance (default is 1.0e4*eps).
%
% OUTPUT:
% root = solution vector.
if size(x, 1) == 1; % x must be column vector
x = x';
end
for i = 1:30
[jac, f0] = jacobian(func, x);
if sqrt(dot(f0, f0) / length(x)) < tol
root = x; return
end
dx = jac \ (-f0);
x = x + dx;
if sqrt(dot(dx, dx) / length(x)) < tol
root = x; return
end
end
error('Too many iterations')
end
function [jac, f0] = jacobian(func,x)
% Returns the Jacobian matrix and f(x).
h = 1.0e-4;
n = length(x);
jac = zeros(n);
f0 = feval(func,x);
for i = 1:n
temp = x(i);
x(i) = temp + h;
f1 = feval(func,x);
x(i) = temp;
jac(:,i) = (f1 - f0)/h;
end
end