Simple recurrence relation in fortran and matlab - matlab

I wrote the following program in fortran
implicit real*16 (a-h,o-z)
implicit integer*8 (i-n)
parameter (nnmax=130000, nbarmax = nnmax/2,ipmax =5)
parameter (nulatmax=5000)
dimension doef(0:nbarmax)
dimension coef(0:ipmax,0:nnmax)
dimension aux(-1:nnmax)
ip = 2
anzn = 3
coef = 0.q0 !-->zera todos os coeficientes
alamb = 1.q0
!Initial conditions
do i1 =0,ip
coef(i1,0) = 1.q0
end do
! write(*,*)'linha 271'
aux(-1) = 0.q0
! iteracao
M = 30
do nn =1, M
nnbar = (nn+ip)/(ip+1)
natual =mod(nn +2*(ip+1)-1,ip+1)
nanter =mod(nn +2*(ip+1)-2,ip+1)
nfirst =mod(nn +2*(ip+1)-(ip+2),ip+1)
do i2=0,nnbar
aux(i2) = coef(natual,i2)
end do
do i2=0,nnbar
coef(natual,i2) = coef(nanter,i2) -(alamb**anzn)*aux(i2-1)
doef(i2) = coef(natual,i2)
write(511,*) nn,doef(i2)
enddo
enddo
endprogram
that solve the below recurrence relation
Pm+3(x) = Pm+2(x) - x * Pm(x), with m>=0
and initial conditions P0= 1, P1= 1-x, P2= 1-2x.
Now, I'm try to find all roots of this polynomials. I know this is easily done in matlab using roots(X) function, where X is a column vector of polynomial coefficients.
Therefore I would like to write my above routine which calculates the polynomial coefficients in matlab. Thanks if anyone can help me.

Related

Calculating numerical integral using MATLAB

I have an equation of the following form:
where A,B,C, and q are 3-by-3 matrix and Tr[...] represent trace. And
here b is a constant. The explicit form of A,B(x,y,E),C(x,y,E), q(x,y) matrices is written in the below MATLAB code. I am trying to solve it using the integral3() function of MATLAB. But it is giving me errors.
I wrote the function for the integrant in two different ways. And run the script:
integral3(#fun1,-pi,pi,-pi,pi,-inf,inf)
function file 1:
function out = fun1(x,y,E)
%=============just some constants==========
DbyJ = 2/sqrt(3);
T = 1e-2;
eta = 1e-3;
b = 1/T;
D = 1+1i*DbyJ;
fk1 = 1+exp(1i*x);
fk2 = 1+exp(1i*y);
fk1k2 = 1+exp(1i*(x-y));
%=============Matrices==========
A = eye(3); A(1,1) = 1;
q = [0, 1i*D*exp(-1i*x), 0 ;
-1i*conj(D)*exp(1i*x), 0,-1i*D*exp(1i*(x-y));
0,1i*conj(D)*exp(1i*(y-x)),0];
h = [0 -D*conj(fk1) -conj(D)*conj(fk2);
-conj(D)*fk1 0 -D*fk1k2;
-D*fk2 -conj(D)*conj(fk1k2) 0];
B = ((E-1i*eta)*eye(3) - h)^(-1);
C = conj(B);
Term1 = A*(B-C)*q*(B-C);
trc = trace(Term1);
N = -b*exp(b*E)/((exp(b*E)-1)^2);
out = trc*E*N;
It gave me the following error:
Error using horzcat
Dimensions of arrays being concatenated are not consistent.
Error in fun1 (line 19)
q = [0, 1i*D*exp(-1i*x), 0 ;
Then I tried to solve Tr[...] part symbolically and removed the matrices from integrant. The function file is very large for this, so, I am not putting it here. Anyway, it give me error that
Error using *
Incorrect dimensions for matrix multiplication. Check that the number of columns in the first matrix matches the number of rows in the second matrix. To perform elementwise multiplication, use '.*'.
Error in fun1 (line 33)
trc = (D*exp(-x*1i)*((exp(conj(x ... (it is a very long expression that I calculated symbolically to remove matrices.)
Question:
Why integral3() is not working?
Is there any other way to solve this kind of integrals numerically? (In Python or in any other software/language).
Thank you for reading.
TLDD:
How can I solve the above given integral numerically?

Matlab vector return to multiple vectors

num = zeros(1,freq);
den = zeros(1,freq);
for R = 1:freq
[num(R), den(R)]=butter(4, [0.1 0.9]);
end
I thought it was quite trivial but once I run it, I get:
In an assignment A(I) = B, the number of elements in B and I must be the same.
What am I doing wrong?
What you are doing wrong is that both num and den will contain multiple coefficients:
[b,a] = butter(n,Wn) returns the transfer function coefficients of an nth-order lowpass digital Butterworth filter with normalized cutoff frequency Wn.
b,a — Transfer function coefficients
row vectors
As copied from the documentation
The way to get your code working would be to either set num and den to a matrix, or to a cell array:
num = zeros(freq,4);
den = zeros(freq,4);
for R = 1:freq
[num(R,:), den(R,:)]=butter(4, [A(R) B(R)]); % matrix
end
for R = 1:freq
[num{R}, den{R}]=butter(4, [A(R) B(R)]); % cell
end
Probably the matrix is better suited for your purposes.

Matlab: finding coefficients of ODE system

I have all the data and an ODE system of three equations which has 9 unknown coefficients (a1, a2,..., a9).
dS/dt = a1*S+a2*D+a3*F
dD/dt = a4*S+a5*D+a6*F
dF/dt = a7*S+a8*D+a9*F
t = [1 2 3 4 5]
S = [17710 18445 20298 22369 24221]
D = [1357.33 1431.92 1448.94 1388.33 1468.95]
F = [104188 104792 112097 123492 140051]
How to find these coefficients (a1,..., a9) of an ODE using Matlab?
I can't spend too much time on this, but basically you need to use math to reduce the equation to something more meaningful:
your equation is of the order
dx/dt = A*x
ergo the solution is
x(t-t0) = exp(A*(t-t0)) * x(t0)
Thus
exp(A*(t-t0)) = x(t-t0) * Pseudo(x(t0))
Pseudo is the Moore-Penrose Pseudo-Inverse.
EDIT: Had a second look at my solution, and I didn't calculate the pseudo-inverse properly.
Basically, Pseudo(x(t0)) = x(t0)'*inv(x(t0)*x(t0)'), as x(t0) * Pseudo(x(t0)) equals the identity matrix
Now what you need to do is assume each time step (1 to 2, 2 to 3, 3 to 4) is an experiment (therefore t-t0=1), so the solution would be to:
1- Build your pseudo inverse:
xt = [S;D;F];
xt0 = xt(:,1:4);
xInv = xt0'*inv(xt0*xt0');
2- Get exponential result
xt1 = xt(:,2:5);
expA = xt1 * xInv;
3- Get the logarithm of the matrix:
A = logm(expA);
And since t-t0= 1, A is our solution.
And a simple proof to check
[t, y] = ode45(#(t,x) A*x,[1 5], xt(1:3,1));
plot (t,y,1:5, xt,'x')
You have a linear, coupled system of ordinary differential equations,
y' = Ay with y = [S(t); D(t); F(t)]
and you're trying to solve the inverse problem,
A = unknown
Interesting!
First line of attack
For given A, it is possible to solve such systems analytically (read the wiki for example).
The general solution for 3x3 design matrices A take the form
[S(t) D(t) T(t)].' = c1*V1*exp(r1*t) + c2*V2*exp(r2*t) + c3*V3*exp(r3*t)
with V and r the eigenvectors and eigenvalues of A, respectively, and c scalars that are usually determined by the problem's initial values.
Therefore, there would seem to be two steps to solve this problem:
Find vectors c*V and scalars r that best-fit your data
reconstruct A from the eigenvalues and eigenvectors.
However, going down this road is treaturous. You'd have to solve the non-linear least-squares problem for the sum-of-exponentials equation you have (using lsqcurvefit, for example). That would give you vectors c*V and scalars r. You'd then have to unravel the constants c somehow, and reconstruct the matrix A with V and r.
So, you'd have to solve for c (3 values), V (9 values), and r (3 values) to build the 3x3 matrix A (9 values) -- that seems too complicated to me.
Simpler method
There is a simpler way; use brute-force:
function test
% find
[A, fval] = fminsearch(#objFcn, 10*randn(3))
end
function objVal = objFcn(A)
% time span to be integrated over
tspan = [1 2 3 4 5];
% your desired data
S = [17710 18445 20298 22369 24221 ];
D = [1357.33 1431.92 1448.94 1388.33 1468.95 ];
F = [104188 104792 112097 123492 140051 ];
y_desired = [S; D; F].';
% solve the ODE
y0 = y_desired(1,:);
[~,y_real] = ode45(#(~,y) A*y, tspan, y0);
% objective function value: sum of squared quotients
objVal = sum((1 - y_real(:)./y_desired(:)).^2);
end
So far so good.
However, I tried both the complicated way and the brute-force approach above, but I found it very difficult to get the squared error anywhere near satisfyingly small.
The best solution I could find, after numerous attempts:
A =
1.216731997197118e+000 2.298119167536851e-001 -2.050312097914556e-001
-1.357306715497143e-001 -1.395572220988427e-001 2.607184719979916e-002
5.837808840775175e+000 -2.885686207763313e+001 -6.048741083713445e-001
fval =
3.868360951628554e-004
Which isn't bad at all :) But I would've liked a solution that was less difficult to find...

Formulating a summation objective function to minimize for fmincon in MatLab

I have a summation objective function (non-linear portfolio optimization) which looks like:
minimize w(i)*w(j)*cv(i,j) for i = 1 to 10 and j = 1 to 10
w is the decision vector
cv is a known 10 by 10 matrix
I have the formulation done for the constraints (a separate .m file for the project constraints) and for the execution of the fmincon (a separate .m file for the lower/upper bounds, initial value, and calling fmincon with the arguments).
I just can't figure out how to do the objective function. I'm used to linear programming in GLPK rather than matlab so I'm not doing so good.
I'm currently got:
ObjectiveFunction.m
function f = obj(w)
cv = [all the constants are in here]
i = 1;
j = 1;
n = 10;
var = 0;
while i <= n
while j<=n
var = var + abs(w(i)*w(j)*cv(i, j));
j = j + 1;
end
i = i + 1;
end
f = var
...but this isn't working.
Any help would be appreciated! Thanks in advance :)
So this is from a class I took a few years ago, but it addresses a very similar problem to your own with respect to use of fminsearch to optimize some values. The problem is essentially that you have a t, y, and you want a continuous exponential function to represent t, y in terms of c1*t.*exp(c2*t). The textbook I lifted the values from is called Numerical Analysis by Timothy Sauer. Unfortunately, I don’t remember the exact problem or chapter, but it’s in there somewhere.
c1 and c2 are found recursively by fminsearch minimizing a residual y - ((c1) * t .* exp((c2) * t)). Try copying and running my code below to get a feel for things:
%% Main code
clear all;
t = [1,2,3,4,5,6,7,8];
y = [8,12.3,15.5,16.8,17.1,15.8,15.2,14];
lambda0=[1 -.5];
lambda=fminunc(#expdecayfun,lambda0, ...
optimset('LargeScale','off','Display','iter','TolX',1.e-6),t,y);
c1=lambda(1);
c2=lambda(2);
fprintf('Using the BFGS method through fminunc, c1 = %e\n',c1);
fprintf('and c2 = %e. Since these values match textbook values for\n', c2);
fprintf('c1 and c2, I will stop here.\n');
%% Index of functions:
% expdecayfun
function res=expdecayfun(lambda,t,y) c1=lambda(1);
c2=lambda(2);
r=y-((c1)*t.*exp((c2)*t));
res=norm(r);
Hope this helps!

Histogram matching of 3D datasets using L2 norm minimisation (Matlab)

I need to perform some elementary histogram matching on 2 sets of 3D data. This is part of a larger algorithm.
My goal is to perform this by minimising the following cost function:
|| cumpdf(f(A)) - cumpdf(B) || .^2
where:
cumpdf is the cumulative histogram
f() is linear transformation a*A + b where a/b are affine coefficients to be
determined
A is the image to be transformed and B is the image to be matched
I am using lsqcurvefit however I have run into some trouble and therefore really need some help.
A(maskA==0)=0;
B(maskB==0)=0;
[na,~] = hist(A(maskA~=0),500);
na = na ./ numel(A(maskA~=0));
x_data = cumsum(na);
[nb,~] = hist(B(maskB~=0),500);
nb = nb ./ numel(B(maskB~=0));
y_data = cumsum(nb);
xo = [1.5 -200];
[coeff,~] = lsqcurvefit(#cost,xo,x_data,y_data);
function F = cost(x,xc)
F = x(1).*A + x(2);
[nc,~] = hist(C(maskA~=0),500);
nc = nc / numel(C(maskA~=0));
xc = cumsum(nc);
Amask and Bmask just represent some indexing I need to do.
My question is: I know that the above is wrong. However, I think it represents best what I want to do, regarding the cost function and the goal. Some help would me much appreciated!