I'm trying to simulate a regulation object, however when trying to calculate ISE it throws an error:
Dimension argument must be a positive integer scalar within indexing range.
Here's my code:
A=[0 1; -8.6207 -10.0682];
B=[0 ; 1];
C=[34.4827 0];
D=0;
sys=ss(A,B,C,D);
Tp=0.01;
I=eye(2);
Ad=I+A*Tp;
Bd=B*Tp;
Cd=C;
Dd=D;
M=15/Tp;
y=zeros(1, M);
x= [0;0];
kp=12,97;
Ti=0.567;
tt=(1:M)*Tp;
for k = 2:M
%regulator
e=1-y(k-1);
u=kp*(e+(1/Ti)*trapz(e));
%obiekt
x=Ad*x + Bd*u;
y(k)=Cd*x + Dd*u;
%wskaznik jakosci
ise=trapz(tt,e.^2);
end
figure(1);
plot(tt,y);
figure(2);
plot(tt,ise)
Just converting the comments to an answer.
The main problem was that the variables inside the trapz() function were included in the wrong order. Another issue related to plotting was also solved by saving the values of ise from every iteration.
If ise is declared as a vector before the loop, then the warning about changing its size in every iteration won't be shown.
Code:
A=[0 1; -8.6207 -10.0682];
B=[0 ; 1];
C=[34.4827 0];
D=0;
sys=ss(A,B,C,D);
Tp=0.01;
I=eye(2);
Ad=I+A*Tp;
Bd=B*Tp;
Cd=C;
Dd=D;
M=15/Tp;
y=zeros(1, M);
x= [0;0];
kp=12.97; %%%% <----Change
Ti=0.567;
tt=(1:M)*Tp;
ise = zeros(1, M); %%%% <----Change
for k = 2:M
%regulator
e=1-y(k-1);
u=kp*(e+(1/Ti)*trapz(e));
%obiekt
x=Ad*x + Bd*u;
y(k)=Cd*x + Dd*u;
%wskaznik jakosci
ise(k)=trapz(e.^2, tt); %%%% <----Change
end
figure(1);
plot(tt,y);
figure(2);
plot(tt,ise)
The 2nd figure:
Related
I am trying to approximate and plot the solution to u"(x) = exp(x) in the interval 0-3, with boundary conditions x(0)=1,x(3)=3. I am able to plot the approximate solution vs the exact, but the plot looks a bit off:
% Interval
a=0;
b=3;
n=10;
% Boundary vals
alpha=1;
beta=3;
%grid size
h=(b-a)/(n+1);
%Matrix generation
m = -2;
u = 1;
l = 1;
% Obtained from (y(i-1) -2y(i) + y(i+1)) = h^2 exp(x(i)
M = (1/h^2).*(diag(m*ones(1,n)) + diag(u*ones(1,n-1),1) + diag(l*ones(1,n-1),-1));
B=[];
xjj=[];
for j=1:n
xjj=[xjj,j*h];
if j==1
B=[B,f(j*h)-(alpha/h^2)];
continue
end
if j==n
B=[B,f(j*h)-(beta/h^2)];
continue
else
B=[B,f(j*h)];
end
end
X=M\B';
x=linspace(0,3,101);
plot(xjj',X,'r*')
hold on
plot(x,exp(x),'b-')
I appreciate all the advice and explanation. This is the scheme I am following: http://web.mit.edu/10.001/Web/Course_Notes/Differential_Equations_Notes/node9.html
You could shorten the big loop to simply
x=linspace(a,b,n+2);
B = f(x(2:end-1));
B(1)-=alpha/h^2;
B(n)-=beta/h^2;
The exact solution is u(x)=C*x+D+exp(x), the boundary conditions give D=0 and 3*C+exp(3)=3 <=> C=1-exp(3)/3.
Plotting this exact solution against the numerical solution gives a quite good fit for this large step size:
f=#(x)exp(x)
a=0; b=3;
n=10;
% Boundary vals
alpha=1; beta=3;
%grid
x=linspace(a,b,n+2);
h=x(2)-x(1);
% M*u=B obtained from (u(i-1) -2u(i) + u(i+1)) = h^2 exp(x(i))
M = (1/h^2).*(diag(-2*ones(1,n)) + diag(1*ones(1,n-1),1) + diag(1*ones(1,n-1),-1));
B = f(x(2:end-1));
B(1)-=alpha/h^2; B(n)-=beta/h^2;
U=M\B';
U = [ alpha; U; beta ];
clf;
plot(x',U,'r*')
hold on
x=linspace(0,3,101);
C = 1-exp(3)/3
plot(x,exp(x)+C*x,'b-')
I want to evaluate the vector xdata in a piecewise function like this:
dat=load('k2.txt');
xdata = dat(:,1);
ydata = dat(:,2);
n=length(xdata);
p0=[0.0821 6.6 0.4];
y(p0,xdata)
function y_hat = y(p,t)
P=4.885;
T0 = 134.27426;
omega=2*pi/P;
gamma1=0.3539 ;gamma2=0.2851;
c1=0;c2=gamma1+2*gamma2;c3=0;c4=-gamma2;
c0=1-c1-c2-c3-c4;
z= p(2).*((sin(omega.*(t-T0))).^2+((p(3)/p(2)).*cos(omega.*(t-T0))).^2).^(1/2);
lambda1= 0;
lambda3=p(1).^2;
if ((1-p(1)<z) & (z<1+p(1)))
k1 = acos((1-p(1).^2 + z.^2)./(2*z));
k0 = acos(((p(1)).^2+z.^2-1)./(2.*z.*p(1)));
y_hat = 1-1./pi*(p(1).^2.*k0+k1-sqrt((4*z.^2-(1+z.^2-p(1).^2).^2)/4));
end
if (1+p(1)<=z)
y_hat=1-lambda1;
end
if (z<=1-p(1))
y_hat=1-lambda3;
end
end
The problem is that the code doesn't enter none of the if loops and returns nothing. Maybe the reason is that the function tries to fulfill the conditions for all the vector at once? How should I proceed so that y(p0,xdata) returns something?
By the way, I need this because I have to fit a model to data like this:
[theta] = lsqcurvefit(#y, p0, xdata, ydata);
Your code doesn't work, because when you write something like this:
if [1 3 -1] > 0
%code
end
Then "%code" won't be evaluated because it's checking, if the condition holds for every value in the vector.
Let's say you want to define the Heaviside function and evaluate a vector of it. Then, what you do is using a for loop:
x_vals = [-1 1 5];
heav(x_vals)
function y = heav(x)
y = zeros(size(x));
for i = 1:length(x)
if x(i) >= 0
y(i) = 1;
else
y(i) = 0;
end
end
end
There is a two-dimensional random walk that one can find here which works perfectly in Octave. However, when I tried to write a one-dimensional random walk program, I got an error. Here is the program:
t=[];
x=[];
for i=1:100000
J=rand;
if J<0.5
x(i+1)=x(i)+1;
t(i+1)=t(i)+1;
else
x(i+1)=x(i)-1;
t(i+1)=t(i)+1;
end
end
plot(t,x)
Here is the error:
error: A(I): index out of bounds; value 1 out of bound 0
Thank you.
No need for a loop:
N = 100000;
t = 1:N;
x = cumsum(2*(rand(1,N)<.5)-1);
plot(t,x)
For the 2D case you could use the same approach:
N = 100000;
%// t = 1:N; it won't be used in the plot, so not needed
x = cumsum(2*(rand(1,N)<.5)-1);
y = cumsum(2*(rand(1,N)<.5)-1);
plot(x,y)
axis square
You get an error because you ask MATLAB to use x(1) in the first iteration when you actually defined x to be of length 0. So you need to either initialize x and t with the proper size:
x=zeros(1,100001);
t=zeros(1,100001);
or change your loop to add the new values at the end of the vectors:
x(i+1)=[x(i) x(i)+1];
Since t and x are empty, therefore, you cannot index them through x(i+1) and x(i).
I believe you should intialize x and t with all zeros.
In the first iteration, i = 1, you have x(2) = x(1) +or- 1 while x has dimension of zero. You should define the starting point for x and t, which is usually the origin, you can also change the code a little bit,
x = 0;
N = 100000;
t = 0 : N;
for i = 1 : N
x(i+1) = x(i) + 2 * round(rand) - 1;
end
plot(t,x)
Hi I have this function to calculate the coefficient list for the Newton polynomial:
function p = polynom(x,y,c)
m = length(x);
p = c(m)*ones(size(y));
for k = m-1:-1:1
p = p.*(y-x(k)) + c(k);
end
I already have another program that finds the divided differences c correctly. For x=[3 1 5 6], y=[1 -3 2 4] I get c=[1.0000 2.0000 -0.3750 0.1750] which is correct.
But when I use the above function it gives as a result:
p =
-3.0000 -53.6000 -0.1000 1.3500
But the correct answer should be:
p =
0.1750 -1.9500 7.5250 -8.7500
What is wrong with my function?
This is the code I've used. I've used it long time ago, so I'll post whole code. I hope this is what you need.
table.m
%test table
X = [1 1.05 1.10 1.15 1.2 1.25];
Y = [0.68269 0.70628 0.72867 0.74986 0.76986 0.78870];
position.m
%M-file position.m with function position(x)
%that for argument x returns
%value 1 if x<X(2),
%value 2 if x>X(n-1)
%else 0
function position=position(x)
table;
n=length(X);
if x<X(2)
position=1;
else
if x>X(n-1)
position=2;
else position=0;
end
end
Newton.m
function Newton=Newton(x)
table;
%position(x);
n=length(X);
A=zeros(n,n+1);
% table of final differences - upper triangle
for i=1:n
A(i,1)=X(i);
A(i,2)=Y(i);
end
for i=3:n+1
for j=1:(n-i+2)
A(j,i)=A(j+1,i-1)-A(j,i-1);
end
end
%showing matrix of final differences, A
A
h=X(2)-X(1);
q1=(x-X(1))/h;
q2=(x-X(n))/h;
s1=q1;
s2=q2;
%making I Newton polynomial
if (position(x)==1)
p1=A(1,2);
f=1;
for i=1:n-1
f=f*i;
p1=p1+(A(1,i+2)*s1)/f;
s1=s1*(q1-i);
end
Newton=p1;
else
%making II Newton polynomial
if (position(x)==2)
p2=A(n,2);
f1=1;
for i=1:n-1
f1=f1*i;
p2=p2+(A(n-i,i+2)*s2)/f1;
s2=s2*(q2+i);
end
Newton=p2;
%else, printing error
else Newton='There are more suitable methods than Newton(I,II)';
end
end
I recently started using Matlab and I am trying to plot Imaginary part of a function. I can see I am making a mistake somewhere because I have the graph showing what I need to get and I am getting something else. Here is the link of the graph that I need to get, that I am getting and a function that I am plotting:
I know that this function has a singularity at frequency around 270 Hz and I don't know if a 'quadgk' can solve integral then. You guys probably know but theta function inside the integral is a heaviside and I don't know if that is causing problem maybe? Is there something wrong I am doing here? Here is the matlab code I wrote:
clear all
clc
ff=1:10:1000;
K1=(2*3)*log(2*cosh(135/6))/pi;
theta1=ones(size(ff));
theta1(ff<270)=0;
I1=zeros(size(ff));
for n = 1:numel(ff)
f = ff(n);
I1(n)= K1/f + (f/pi)*quadgk(#(x)(sinh(x/3)/(cosh(135/3)+cosh(x/3))-theta1(n))./((f^2)-4*(x.^2)), 0, inf);
end
plot(ff,I1, 'b');
hold on
axis([0 1000 -0.3 1])
First, I altered the expression for your heaviside function to what I think is the correct form.
Second, I introduced the definitions of mu and T explicitly.
Third, I broke down the integral into 4 components, as follows, and evaluated them individually (along the lines of what Fraukje proposed)
Fourth, I use quadl, although this is prob. of minor importance.
(edit) Changed the range of ff
Here's the code with changes:
fstep=1;
ff=[1:fstep:265 275:fstep:1000];
T = 3;
mu = 135;
df = 0.01;
xmax = 10;
K1=(2*T/pi)*log(2*cosh(mu/(2*T)));
theta1=ones(size(ff));
theta1(ff-2*mu<0)=0;
I1=zeros(size(ff));
for n = 1:numel(ff)
f = ff(n);
sigm1 = #(x) sinh(x/T)./((f^2-4*x.^2).*(cosh(mu/T)+cosh(x/T)));
sigm2 = #(x) -theta1(n)./(f^2-4*x.^2);
I1(n) = K1/f + (f/pi)*quadl(sigm1,0,f/2-df); % term #1
% I1(n) = I1(n) + (f/pi)*quadl(sigm1,f/2+df,xmax); % term #2
% I1(n) = I1(n) + (f/pi)*quadl(sigm2,0,f/2-df); % term #3
% I1(n) = I1(n) + (f/pi)*quadl(sigm2,f/2+df,xmax); % term #4
end
I selected to split the integrals around x=f/2 since there is clearly a singularity there (division by 0). But additional problems occur for terms #2 and #4, that is when the integrals are evaluated for x>f/2, presumably due to all of the trigonometric terms.
If you keep only terms 1 and 3 you get something reasonably similar to the plot you show:
However you should probably inspect your function more closely and see what can be done to evaluate the integrals for x>f/2.
EDIT
I inspected the code again and redefined the auxiliary integrals:
I1=zeros(size(ff));
I2=zeros(size(ff));
I3=zeros(size(ff));
for n = 1:numel(ff)
f = ff(n);
sigm3 = #(x) sinh(x/T)./((f^2-4*x.^2).*(cosh(mu/T)+cosh(x/T))) -theta1(n)./(f^2-4*x.^2);
I1(n) = K1/f + (f/pi)*quadl(sigm3,0,f/2-df);
I2(n) = (f/pi)*quadl(sigm3,f/2+df,10);
end
I3=I2;
I3(isnan(I3)) = 0;
I3 = I3 + I1;
This is how the output looks like now:
The green line is the integral of the function over 0<x<f/2 and seems ok. The red line is the integral over Inf>x>f/2 and clearly fails around f=270. The blue curve is the sum (the total integral) excluding the NaN contribution when integrating over Inf>x>f/2.
My conclusion is that there might be something wrong with the curve as you expect it to look.
So far I'd proceed this way:
clc,clear
T = 3;
mu = 135;
f = 1E-04:.1:1000;
theta = ones(size(f));
theta(f < 270)= 0;
integrative = zeros(size(f));
for ii = 1:numel(f)
ff = #(x) int_y(x, f(ii), theta(ii));
integrative(ii) = quad(ff,0,2000);
end
Imm = ((2*T)./(pi*f)).*log(2*cosh(mu/(2*T))) + (f/pi).*integrative;
Imm1 = exp(interp1(log(f(1:2399)),log(Imm(1:2399)),log(f(2400):.001:f(2700)),'linear','extrap'));
Imm2 = exp(interp1(log(f(2985:end)),log(Imm(2985:end)),log(f(2701):.001:f(2984)),'linear','extrap'));
plot([(f(2400):.001:f(2700)) (f(2701):.001:f(2984))],[Imm1 Imm2])
hold on
axis([0 1000 -1.0 1])
plot(f,Imm,'g')
grid on
hold off
with
function rrr = int_y(x,f,theta)
T = 3;
mu = 135;
rrr = ( (sinh(x./T)./(cosh(mu/T) + cosh(x/T))) - theta ) ./ (f.^2 - 4.*(x.^2));
end
I've come up with this plot: