Passing matrix element as function handle - matlab

I have applied inverse laplace transform to a matrix and now it is a function of t. My goal is to substitute t value and get the result matrix. I intended this code to be pretty straight foward but I'm not getting it work. This is what I tried:
clc,clear all, close all
% Parameters
syms s
r=3.33;
l = 4.56*10^-3;
j = 4.96*10^-5;
b = 4.59*10^-5;
k = 0.0332;
% State Matrices
F = [-r/l -k/l 0; k/j -b/j 0; 0 1 0]
G = [1/l; 0; 0]
sI = s*eye(3,3)
aux_A = (adjoint(sI-F))/det(sI-F)
laplaceA = ilaplace(aux_A)
result_matrix = #(t) laplaceA
%Assuming t = 0.01
result_matrix(0.01)
Assuming that my goal is just substitute t values within laplaceA matrix, I am open to any suggestions. Thanks!

Replacing syms Variables in Symbolic Functions
Using subs() to substitute the Input parameter of the anonymous function/function handle may be as way to replace all the t terms in laplaceA. Modifying the single line to be as follows should give numerical results without any t variables:
result_matrix = #(Input) subs(laplaceA,"t",Input);
To evaluate the trigonometric functions to numerical values
result_matrix = #(Input) vpa(subs(laplaceA,"t",Input));
Full Script:
clc
clear
close all
% Parameters
syms s
r = 3.33;
l = 4.56*10^-3;
j = 4.96*10^-5;
b = 4.59*10^-5;
k = 0.0332;
% State Matrices
F = [-r/l -k/l 0; k/j -b/j 0; 0 1 0];
G = [1/l; 0; 0];
sI = s*eye(3,3);
aux_A = (adjoint(sI-F))/det(sI-F);
laplaceA = ilaplace(aux_A);
result_matrix = #(Input) vpa(subs(laplaceA,"t",Input));
%Assuming t = 0.01
result_matrix(0.01)
Output Results:

Related

double sum in Matlab

I would like to write a Matlab code to calculate the following:
\sum_{k=0}^{N-1} \frac{1}{k!} \sum_{i=0}^{k} {k \choose i}(a-1)^{k-i} a^k
and my code is:
N = 3;
a = [3 4];
for k = 0:N-1
f = 0;
for i = 0:k
f = f + nchoosek(k,i).* a.^k .* (a-1).^(k-i);
end
sumoff = sum(f);
all = (( 1./ (factorial(k))).*sumoff);
end
overall= sum(all);
'all' variable gives different value when it is inside the for loop rather than outside. But I want it to calculate when k = 0:N-1. What am I doing wrong?
Thank you.
The issue is your current code overwrites all on every iteration. Moving it outside the loop also doesn't work because you'll only save the result of the last iteration.
To save the all of every iteration, define all as a vector and then assign each intermediate result into that vector:
N = 3;
a = [3 4];
% preallocate a vector for `all`
all = nan(N-1, 1);
for k = 0:N-1
f = 0;
for i = 0:k
f = f + nchoosek(k,i) .* a.^k .* (a-1).^(k-i);
end
sumoff = sum(f);
% assign your intermediate result into the `all` vector
all(k+1) = ((1./(factorial(k))) .* sumoff);
end
overall = sum(all);

How to get the output response from a state space equation?

For a state space equation in which matrix A is dependent on variable t(time), how can I get the step or output response?
This is the code, which doesn't work:
A = [sin(t) 0;0 cos(t)];
B = [0.5; 0.0];
C = [1 0; 0 1];
G = ss(A,B,C,[]);
step(G,t)
x0 = [-1;0;2];
initial(G,x0)
Here are error message:
Error using horzcat Dimensions of matrices being concatenated are not
consistent.
Error in Response (line 11) A = [sin(t) 0;0 cos(t)];
As pointed already, you can only use the ss function to generate LTI systems, but you can discretise your model analytically using methods like forward Euler, backwards Euler, Tustin etc. and simulate your model using a for loop.
For your example, you could run something like this:
consider a sampling period h = 0.01 (or lower if the dynamics are not captured properly);
select N as the number of steps for the simulation (100, 1000 etc.);
declare the time instants vector t = (0:N-1)*h;
create a for loop which computes the system states and outputs, here using the forward Euler method (see https://en.wikipedia.org/wiki/Euler_method):
% A = [sin(t) 0;0 cos(t)];
B = [0.5; 0.0];
C = [1 0; 0 1];
D = [0; 0];
x0 = [-1;1]; % the initial state must have two elements as this is a second-order system
u = 0; % constant zero input, but can be modified
N = 1000;
h = 0.01;
t = (0:N-1)*h;
x_vec = [];
y_vec = [];
xk = x0;
yk = [0;0];
for k=1:N
Ad = eye(2)+h*[sin(t(k)) 0; 0 cos(t(k))];
Bd = h*B; % C and D remain the same
yk = C*xk + D*u;
xk = Ad*xk + Bd*u;
x_vec = [x_vec, xk]; % keep results in memory
y_vec = [y_vec, yk];
end
% Plot output response
plot(t,y_vec);

How to vectorize a matlab script converting a 3d matrix to a single vector?

I am writing a graphical representation of numerical stability of differential operators and I am having trouble removing a nested for loop. The code loops through all entries in the X,Y, plane and calculates the stability value for each point. This is done by finding the roots of a polynomial of a size dependent on an input variable (length of input vector results in a polynomial 3d matrix of size(m,n,(lenght of input vector)). The main nested for loop is as follows.
for m = 1:length(z2)
for n = 1:length(z1)
pointpoly(1,:) = p(m,n,:);
r = roots(pointpoly);
if isempty(r),r=1e10;end
z(m,n) = max(abs(r));
end
end
The full code of an example numerical method (Trapezoidal Rule) is as follows. Any and all help is appreciated.
alpha = [-1 1];
beta = [.5 .5];
Wind = 2;
Wsize = 500;
if numel(Wind) == 1
Wind(4) = Wind(1);
Wind(3) = -Wind(1);
Wind(2) = Wind(4);
Wind(1) = Wind(3);
end
if numel(Wsize) == 1
Wsize(2) = Wsize;
end
z1 = linspace(Wind(1),Wind(2),Wsize(1));
z2 = linspace(Wind(3),Wind(4),Wsize(2));
[Z1,Z2] = meshgrid(z1,z2);
z = Z1+1i*Z2;
p = zeros(Wsize(2),Wsize(1),length(alpha));
for n = length(alpha):-1:1
p(:,:,(length(alpha)-n+1)) = alpha(n)-z*beta(n);
end
for m = 1:length(z2)
for n = 1:length(z1)
pointpoly(1,:) = p(m,n,:);
r = roots(pointpoly);
if isempty(r),r=1e10;end
z(m,n) = max(abs(r));
end
end
figure()
surf(Z1,Z2,z,'EdgeColor','None');
caxis([0 2])
cmap = jet(255);
cmap((127:129),:) = 0;
colormap(cmap)
view(2);
title(['Alpha Values (',num2str(alpha),') Beta Values (',num2str(beta),')'])
EDIT::
I was able to remove one of the for loops using the reshape command. So;
for m = 1:length(z2)
for n = 1:length(z1)
pointpoly(1,:) = p(m,n,:);
r = roots(pointpoly);
if isempty(r),r=1e10;end
z(m,n) = max(abs(r));
end
end
has now become
gg = reshape(p,[numel(p)/length(alpha) length(alpha)]);
r = zeros(numel(p)/length(alpha),1);
for n = 1:numel(p)/length(alpha)
temp = roots(gg(n,:));
if isempty(temp),temp = 0;end
r(n,1) = max(abs(temp));
end
z = reshape(r,[Wsize(2),Wsize(1)]);
This might be one for loop, but I am still going through the same number of elements. Is there a way to use the roots command on all of my rows at the same time?

Matlab solution for non-homogenous heat equation using finite differences

Given the following PDE (non-homogenous heat equation):
ut(x,t) = c2uxx(x,t) + f(x,t)
u(0,t) = u(l,t) = 0
u(x,0) = g(x)
0 < x < l ; t > 0 ; c > 0
I wrote the following code in Matlab, to solve the problem using finite differences:
syms xj tk
% Manually define this values
c = 9;
f(xj,tk) = xj;
g(xj) = 0*xj;
l = 1;
Tmax = 0.1;
% Grid definition
Nx = 50;
Nt = 50;
hx = 1/Nx;
ht = 1/Nt;
x = 0:hx:l;
t = 0:ht:Tmax;
lambda = c^2*ht/hx^2;
% Our target
u = zeros(Nx+1,Nt+1);
% Initial values
for j=1:Nx,
u(j,1) = g(x(j)); % u(x,0) = g(x)
end
for k=1:Nx,
u(1,k+1) = 0; % border condition u(0,t) = 0
for j=2:Nt,
u(j,k+1) = u(j,k) + lambda*(u(j+1,k)-2*u(j,k)+u(j-1,k)) + ht*f(j,k); % the formula here is ok
end
u(Nt,k+1) = 0; % border condition u(l,t) = 0
end
contour3(u)
For some reason that I cant't figure out, data is only appearing in the last columns and in a very strange way.
I'm guessing the implementation of the BC's are doing something nasty. But I don't see it.
Is there something that I'm missing?
Thanks in advance!

how do I integrate, a function with many arguments using matlab

If I'm to integrate a function
y = -((F+h)M^3(cosh(h*M)+M*beta*sinh(h*M)))/(h*M*cosh(h*M)+(-1+h*M^2*beta)*sinh(h*M))- (alpha*(M^2*(F+h)*(-1+2*h^2*M^2+ cosh(2*h*M)-2*h*M*sinh(2*h*M)))/(8*(h*M*cosh(h*M)+(-1+h*M^2*beta)*sinh(h*M))^2));
with respect to x, where
phi = 0.6;
x = 0.5;
M = 2;
theta = -1:0.5:1.5;
F = theta - 1;
h = 1 + phi*cos(2*pi*x);
alpha = 0.2;beta = 0.0;
I have written an Mfile
function r = parameterIntegrate(F,h,M,beta,alpha,theta,phi)
% defining a nested function that uses one variable
phi = 0.6;
x = 0.5;
r = quad(#testf,0,1 + phi*cos(2*pi*x));
% simpson's rule from 0 to h
function y = testf(x)
h = 1 + phi*cos(2*pi*x);
theta = -1:0.5:1.5;
F = theta - 1;
M = 2;
beta = 0;
alpha = 0;
y = -((F+h)*M^3*(cosh(h*M)+M*beta*sinh(h*M)))/(h*M*cosh(h*M)+(-1+h*M^2*beta)*sinh(h*M))- (alpha*(M^2*(F+h)*(-1+2*h^2*M^2+ cosh(2*h*M)-2*h*M*sinh(2*h*M)))/(8*(h*M*cosh(h*M)+(-1+h*M^2*beta)*sinh(h*M))^2));
end
end
and called the function by
tol = [1e-5 1e-3];
q = quad(#parameterIntegrate, 0, h,tol)
or
q = quad(#parameterIntegrate, 0,1 + phi*cos(2*pi*0.5),tol)
its not working its giving me
Error using ==> plus
Matrix dimensions must agree.
What your error message means is that for some line of code, there are 2 matrices, but the dimensions don't match, so it can't add them. What I suggest you do to solve this is as follows:
Figure out exactly which line of code is causing the problem.
If the line has large numbers of variables, simplify them some.
Remember that if there are any matrixs at all, and you don't want to do matrix multiplication/division, use the .*, ./, and .^.
I suspect that if you change your multiplies/divides with step 3, your problem will go away.