Building newton iteration in MATLAB - matlab

I seem to get the error "Warning: Matrix is singular to working precision." when trying to get delta_x. It should be using 5x1 and 5x5 matrices.
clc; close all; clear all;
phi = 1;
delta_x = 1;
error = 10e-15;
x = [ 0; 0; 0; 0; 0];
n =1;
B =0.025;
while norm(phi)>= error && norm(delta_x) >= error
G = [ 40e3 -20e3 -20e3 0 1; -20e3 20e3 0 0 0; -20e3 0 20e3 0 0; 0 0 0 0 0; 0 0 0 0 0];
fx = [ 0;
B*((-x(4)-0.7)*(x(2)-x(4))-(((x(2)-x(4))^2)/2));
B*((-x(4)-0.7)*(x(3)-x(4))-(((x(3)-x(4))^2)/2));
-B*((-x(4)-0.7)*(x(2)-x(4))-(((x(2)-x(4))^2)/2))- B*((-x(4)-0.7)*(x(3)-x(4))-(((x(3)-x(4))^2)/2));
0];
b = [ 0; 0; 0; 200e-6; 2.5];
dfx = [ 0 0 0 0 0;
0 -B*(0.7+x(2)) 0 B*(0.7+x(4)) 0;
0 0 -B*(0.7+x(3)) B*(0.7+x(4)) 0;
0 B*(0.7+x(2)) B*(0.7+x(3)) -2*B*(0.7+x(2)) 0;
0 0 0 0 0];
phi = G*x + fx - b;
m = G + dfx;
delta_x = -m\phi;
x = x+delta_x;
norm_delta_x(n) = norm(delta_x);
norm_phi(n) = norm(phi);
n = n+1;
end

The dimensions of matrices 5x1 and 5x5 are fine, but what you are doing in the step delta_x = -m\phi is solving for an inverse of matrix m. Since m is a matrix that is singular (try running det(m) and you will get a zero), an inverse matrix does not exist. Matlab sees this and notifies you by telling you "Matrix is singular to working precision".

Related

How to list all results of probability experiment in Matlab [duplicate]

I am writing a function in Matlab to model the length of stay in hospital of stroke patients. I am having difficulty in storing my output values.
Here is my function:
function [] = losdf(age, strokeType, dest)
% function to mdetermine length of stay in hospitaal of stroke patients
% t = time since admission (days);
% age = age of patient;
% strokeType = 1. Haemorhagic, 2. Cerebral Infarction, 3. TIA;
% dest = 5.Death 6.Nursing Home 7. Usual Residence;
alpha1 = 6.63570;
beta1 = -0.03652;
alpha2 = -3.06931;
beta2 = 0.07153;
theta0 = -8.66118;
theta1 = 0.08801;
mu1 = 22.10156;
mu2 = 2.48820;
mu3 = 1.56162;
mu4 = 0;
nu1 = 0;
nu2 = 0;
nu3 = 1.27849;
nu4 = 0;
rho1 = 0;
rho2 = 11.76860;
rho3 = 3.41989;
rho4 = 63.92514;
for t = 1:1:365
p = (exp(-exp(theta0 + (theta1.*age))));
if strokeType == 1
initialstatevec = [1 0 0 0 0 0 0];
elseif strokeType == 2
initialstatevec = [0 1 0 0 0 0 0];
else
initialstatevec = [0 0 (1-p) p 0 0 0];
end
lambda1 = exp(alpha1 + (beta1.*age));
lambda2 = exp(alpha2 + (beta2.*age));
Q = [ -(lambda1+mu1+nu1+rho1) lambda1 0 0 mu1 nu1 rho1;
0 -(lambda2+mu2+nu2+rho2) lambda2 0 mu2 nu2 rho2;
0 0 -(mu3+nu3+rho3) 0 mu3 nu3 rho3;
0 0 0 -(mu4+nu4+rho4) mu4 nu4 rho4;
0 0 0 0 0 0 0;
0 0 0 0 0 0 0;
0 0 0 0 0 0 0];
Pt = expm(t./365.*Q);
Pt = Pt(strokeType, dest);
Ft = sum(initialstatevec.*Pt);
Ft
end
end
Then to run my function I use:
losdf(75,3,7)
I want to plot my values of Ft in a graph from from 0 to 365 days. What is the best way to do this?
Do I need to store the values in an array first and if so what is the best way to do this?
Many ways to do this, one straightforward way is to save each data point to a vector while in the loop and plot that vector after you exit your loop.
...
Ft = zeros(365,1); % Preallocate Ft as a vector of 365 zeros
for t = 1:365
...
Ft(t) = sum(initialstatevec.*Pt); % At index "t", store your output
...
end
plot(1:365,Ft);

Make a one simple code from several similar code

Hello everybody I have a very simple problem, I have too many data y, p and r. So I want to calculate it in a single code.
This an example of my code if I breakdown into separate code
y1=45
y2=56
y3=67
p1=34
p2=45
p3=56
r1=23
r2=34
r3=45
Ryaw1=[cosd(y1) -sind(y1) 0;
sind(y1) cosd(y1) 0;
0 0 1]
Rpitch1=[cosd(p1) 0 sind(p1);
0 1 0;
-sind(p1) 0 cos(p1)]
Rroll1=[1 0 0;
0 cosd(r1) -sind(r1);
0 sind(r1) cosd(r1)]
R1=Ryaw1*Rpitch1*Rroll1
Coordinate1=R1*X0
Ryaw2=[cosd(y2) -sind(y2) 0;
sind(y2) cosd(y2) 0;
0 0 1]
Rpitch2=[cosd(p2) 0 sind(p2);
0 1 0;
-sind(p2) 0 cos(p2)]
Rroll2=[1 0 0;
0 cosd(r2) -sind(r2);
0 sind(r2) cosd(r2)]
R2=Ryaw2*Rpitch2*Rroll2
Coordinate2=R2*X0
Ryaw3=[cosd(y3) -sind(y3) 0;
sind(y3) cosd(y3) 0;
0 0 1]
Rpitch3=[cosd(p3) 0 sind(p3);
0 1 0;
-sind(p3) 0 cos(p3)]
Rroll3=[1 0 0;
0 cosd(r3) -sind(r3);
0 sind(r3) cosd(r3)]
R3=Ryaw3*Rpitch3*Rroll3
Coordinate3=R3*X0
Coordinate=[Cooedinate1 Coordinate2 Coordinate3]
The goals is to find "Coordinate" (in matrix - combined from Coordinate1, Coordinate2, Coordinate3, .... ,Coordinate..) from every y, p and r data with the same "X0" as a single primary data for calculation.
Sorry for my bad english,
Thanks :)
Use vectors and matrices instead of individual scalars. These are indexed in almost the same way as you had before, i.e. y1 becomes y(1).
Then you can easily loop over the code 3 times and save the repetition.
See my commented code below.
% Define some X0. This should be a column vector.
X0 = [1; 2; 3];
% Make y,p,r into 3 element vectors
y = [45 56 67];
p = [34 45 56];
r = [23 34 45];
% Make R, Ryaw, Rpitch and Rroll 3x3x3 matrices
R = zeros(3,3,3);
Ryaw = zeros(3,3,3);
Rpitch = zeros(3,3,3);
Rroll = zeros(3,3,3);
% Make Coordinate a 3x3 matrix
Coordinate = zeros(3,3);
% Loop k from 1 to 3
% For each 3x3x3 matrix, the kth 3x3 matrix is equivalent to your Ryawk, Rpitchk, Rrollk, Rk
for k = 1:3
Ryaw(:,:,k) = [cosd(y(k)) -sind(y(k)) 0
sind(y(k)) cosd(y(k)) 0
0 0 1];
Rpitch(:,:,k)= [cosd(p(k)) 0 sind(p(k))
0 1 0
-sind(p(k)) 0 cos(p(k))];
Rroll(:,:,k) = [1 0 0
0 cosd(r(k)) -sind(r(k))
0 sind(r(k)) cosd(r(k))];
R(:,:,k) = Ryaw(:,:,k)*Rpitch(:,:,k)*Rroll(:,:,k);
Coordinate(:,k) = R(:,:,k)*X0;
end
disp(Coordinate)

Homographic image transformation issue for sattelite images

I want to apply homography to the satellite images. I found this post quite helpful. So I decided to use the same Matlab code.
im = imread('cameraman.tif');
n = [0;0;-1];
d = Inf
theta = 60*pi/180;
R = [ 1 0 0 ;
0 cos(theta) -sin(theta);
0 sin(theta) cos(theta)];
t = [0;0;0];
K=[300 0 0;
0 300 0;
0 0 1];
H=K*R/K-1/d*K*t*n'*K;
img=imagehomog(im,H','c');
figure;imshow(img)
but the output is just the small box.
I am using MATLAB 2015b
EDIT
Homography using imtransform and maketform
n = [0;0;-1];
d = Inf;
im = imread('cameraman.tif');
theta = 60*pi/180;
R = [ 1 0 0 ;
0 cos(theta) -sin(theta);
0 sin(theta) cos(theta)];
t = [0;0;0];
K=[300 0 0;
0 300 0;
0 0 1];
H=K*R/K-1/d*K*t*n'*K;
tform = maketform('projective',H');
imT = imtransform(im,tform);
imshow(imT)
Output
How can I do it from the center. Something like this

MATLAB Yalmip: unable to run optimizer; error in eliminatevariables

Bottomline:
Matlab throws the errors below and it is not obvious to me what is the root cause. The problem seems to reside in the input arguments, but I cannot figure out exactly what it is. I would greatly appreciate any help in finding it.
Index exceeds matrix dimensions.
Error in eliminatevariables (line 42)
aux(model.precalc.index2) = value(model.precalc.jj2);
Error in optimizer/subsref (line 276)
[self.model,keptvariablesIndex] =
eliminatevariables(self.model,self.model.parameterIndex,thisData(:),self.model.parameterIndex);
Error in SCMv0_justrun (line 68)
[solutions,diagnostics] = controller{inputs};
Background:
I am trying to program a Model Predictive Control but I am not very familiar yet with either Yalmip or mathematical optimization algorithms. I have made sure that the defined inputs and the actual inputs have the same dimensions, hence why I am surprised that the error has to do with matrix dimensions.
The error originates in when my code calls the optimizer.
My code is based on: https://yalmip.github.io/example/standardmpc/
Here is my code (the first part of the code is only needed to define the optimization problem and is marked between "%%%%%"; the error occurs near the end):
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
yalmip('clear')
clear all
% Model data
A = eye(3);
B = [1 0 -1 0 0 0 0; 0 1 0 -1 0 0 0; 0 0 0 0 1 -1 -1];
nx = 3; % Number of states
nu = 7; % Number of inputs
% MPC data
Q = [10 10 20]';
R = [10 10 1 1 5 3 3]';
C = [50 0; 0 30];
N = 90;
ny = 2;
E = [0 0 0 0 0 1 0; 0 0 0 0 0 0 1];
u = sdpvar(repmat(nu,1,N),repmat(1,1,N));
x = sdpvar(repmat(nx,1,N+1),repmat(1,1,N+1));
r = sdpvar(repmat(ny,1,N+1),repmat(1,1,N+1));
d = sdpvar(ny,1);
pastu = sdpvar(nu,1);
dx = 0.05;
Gx=[-1*eye(3);eye(3)];
gx = [0 0 0 500 500 1000]';
COVd = [zeros(5,7);0 0 0 0 0 10 0; 0 0 0 0 0 0 10];
COVx = zeros(nx,nx);
auxa = eye(5);
auxb = zeros(5,2);
Gu = [-1*eye(7,7); auxa auxb;0 0 0 0 0 1 1];
gu = [zeros(7,1); 200; 200; 50; 50; 100; 500];
Ga = [0 0 0.5 0.5 -1 0 0];
constraints = [];
objective = 0;
for k = 1:N
r{k} = r{k} + d;
objective = objective + Q'*x{k} + R'*u{k} + (r{k}-E*u{k})'*C*(r{k}-E*u{k});
constraints = [constraints, x{k+1} == A*x{k}+B*u{k}];
COVx = A*COVx*A' + B*COVd*B';
COVGx = Gx*COVx*Gx';
StDevGx = sqrt(diag(COVGx));
chance = gx - norminv(1-dx/(length (gx)*N))*StDevGx;
constraints = [constraints, Ga*u{k}==0, Gu*u{k}<=gu, Gx*x{k}<=gx-chance];
end
objective = objective + Q'*x{N+1};
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
parameters_in = {x{1},[r{:}],d,pastu};
solutions_out = {[u{:}], [x{:}]};
controller = optimizer(constraints, objective,[],parameters_in,solutions_out);
x = 100*ones(nx,1);
clf;
disturbance = randn(ny,1)*10;
oldu = zeros(nu,1);
hold on
for i = 1:150
future_r = [4*sin((i:i+N)/40);3*sin((i:i+N)/20)];% match dimensions of r
inputs = {x,future_r,disturbance,oldu};
[solutions,diagnostics] = controller{inputs};
U = solutions{1};oldu = U(1);
X = solutions{2};
if diagnostics == 1
error('The problem is infeasible');
end
x = A*x+B*u;
end
It's a bug in the latest version of YALMIP.

"Contour not rendered for non-finite ZData"

I'm trying to plot a frequency characteristic equation using ezplot, but Matlab gives the following warning, "Contour not rendered for non-finite ZData". I have used this command to plot frequency equations previously but now I get a warning and the plot display is empty and it does not change the axis range as well. Can someone please help. Would be much appreciated.
Here's the code i'm using.
% Transfer Matrix for Case-I, thin rotor
clear all;
clc;
EI = 1626;
l = 0.15;
m = 0.44108;
It = 2.178*10^-4;
I_p = 2.205*10^-5;
Itr = 0.24;
I_pr = 0.479;
syms p n;
F = [1 l*1i l^2/(2*EI)*1i l^3/(6*EI);
0 1 l/EI -l^2/(2*EI)*1i;
0 0 1 -l*1i;
0 0 0 l];
P = [ 1 0 0 0;
0 1 0 0;
0 -It*p^2+I_p*n*p 1 0;
-m*p^2 0 0 1];
P_r = [1 0 0 0;
0 1 0 0;
0 -Itr*p^2+I_pr*n*p 1 0;
-m*p^2 0 0 1];
A = F*P*F*P*F*P*F;
B = P_r*F*P*F*P*F;
r = A(1,2)/A(1,4);
a12_p = 0;
a22_p = A(2,2)-r*A(2,4);
a32_p = A(3,2)-r*A(3,4);
a42_p = A(4,2)-r*A(4,4);
Ap(2,2) = a22_p;
Ap(3,2) = a32_p;
Ap(4,2) = a42_p;
Ap(4,4) = 1;
C = B*Ap;
M = [C(3,2) C(3,4);
C(4,2) C(4,4)];
sol = det(M);
ezplot(sol,[-2*10^10 2*10^10]);
The sol is displayed if u ask for it but the plot doesn't display.
Thanks in advance for ur help !! Much appreciated.