about Clamped cubic spline code in Matlab - matlab

I did the program, but for some reason it marks a mistake (c = tridiagonal ( hi(1:n-1), dd, hi(1:n-1), ri ); ) and I don't know why, I'm sure it's correct so please somebody help.
Here is the code:
function csc = cubic_clamped ( xi, fi, fpa, fpb )n = length ( xi );
m = length ( fi );
if ( n ~= m )
disp ( 'number of ordinates and number of function values must be equal' )
return
end
for i = 1 : n-1
hi(i) = xi(i+1) - xi(i);
end
dd(1) = 2.0*hi(1); dd(n) = 2.0*hi(n-1);
ri(1) = (3.0/hi(1))*(fi(2)-fi(1)) - 3.0 * fpa;
ri(n) = 3.0 * fpb - (3.0/hi(n-1))*(fi(n)-fi(n-1));
for i = 1 : n-2
dd(i+1) = 2.0 * ( hi(i) + hi(i+1) );
ri(i+1) = (3.0/hi(i+1))*(fi(i+2)-fi(i+1))-(3.0/hi(i))*(fi(i+1)-fi(i));
end
disp ( [dd' ri'] )
c = tridiagonal ( hi(1:n-1), dd, hi(1:n-1), ri );
d = zeros ( n,1 );
b = d;
for i = 1 : n-1
d(i) = (c(i+1)-c(i))/(3.0*hi(i));
b(i) = (fi(i+1)-fi(i))/hi(i) - hi(i)*(c(i+1)+2.0*c(i))/3.0;
end
if ( nargout == 0 )
disp ( [ xi' fi' b c' d ] )
else
csc = [ xi' fi' b c' d ];
end
tridiagonal code (error is: w = a(i) - b(i)*v(i-1); )
function y = tridiagonal( a, b, c, f )
n = length(f);
v = zeros(n,1);
y = v;
w = a(1);
y(1) = f(1)/w;
for i=2:n
v(i-1) = c(i-1)/w;
w = a(i) - b(i)*v(i-1);
y(i) = ( f(i) - b(i)*y(i-1) )/w;
end
for j=n-1:-1:1
y(j) = y(j) - v(j)*y(j+1);
end

Related

MF-DFA from Matalb to Julia implementation

I'm working with the MF-DFA method in Matlab but I need to implement it in Julia. The goal is tho obtain the Hurst exponent of the S&P 500. The matlab code is as follows:
sp500 = readtable('sp500_Nasdaq.csv','PreserveVariableNames', true) ;
spClose = table2array(sp500(:,2)) ;
SP1=cumsum(spClose - mean(spClose)) ;
SP1_ordinary=sqrt(mean(SP1.^2));
X=cumsum(spClose-mean(spClose));
X=transpose(X);
scale=[16,32,64,128,256,512,1024];
q=[-5,-3,-1,0,1,3,5];
m=1;
for ns=1:length(scale),
segments(ns)=floor(length(X)/scale(ns));
for v=1:segments(ns)
Index=( ( ( (v-1)*scale(ns) )+1):(v*scale(ns)));
C = polyfit(Index,X(Index),m) ;
fit=polyval(C,Index);
RMS{ns}(v)=sqrt(mean((X(Index)-fit).^2));
end
for nq=1:length(q),
qRMS{nq,ns}=RMS{ns}.^q(nq);
Fq(nq,ns)=mean(qRMS{nq,ns}).^(1/q(nq));
end
Fq(q==0,ns)=exp(0.5*mean(log(RMS{ns}.^2)));
end
The Julia the code looks like this:
using DelimitedFiles, TimeSeries, Plots, DelimitedFiles, Plots, StatsBase
using Polynomials, LinearAlgebra, CSV, DataFrames
sp500 = CSV.read("sp500_Nasdaq.csv", DataFrame)
sp500_V = values(sp500[:,2])
SP1 = cumsum(sp500_V .- mean(sp500_V) ) ;
SP1_Ord = sqrt(mean(SP1.^2)) ;
X = SP1 ;
X = X';
function polyfit(xVals,yVals)
n = length(xVals)
xBar, yBar = #fastmath mean(xVals), mean(yVals)
sXX, sXY = #fastmath ones(n)'*(xVals.-xBar).^2 , dot(xVals.-xBar,yVals.-yBar)
b1A = #fastmath sXY/sXX
b0A = #fastmath yBar - b1A*xBar
return b0A, b1A
end
scales = [16,32,64,128,256,512,1024];
q = [-5,-3,-1,0,1,3,5] ;
segments = zeros(Int64, (1,length(scales)))
global qRMS = zeros( length(q) ,length(scales) ) ;
global Fq = zeros( length(q) , length(scales) ) ;
#inbounds for ns = 1:length(scales)
global segments[ns] = Int(floor( length(X)/scales[ns] ) ) ;
global Index = Array{UnitRange{Int128}}(undef, (segments[ns], length(scales)) ) ;
global ft = zeros(Float64, (segments[ns], length(scales) ) ) ;
global RMS = zeros(Float64, (length(scales) ,segments[ns] ) ) ;
#inbounds for v=1:segments[ns]
global RMSk = Array{Float64}[] ;
Index = ( ( (v-1)*scales[ns] ) + 1 ):( v*scales[ns] ) ;
global C = polyfit( Index, X[Index]) ;
global p = Polynomial(C)
ft =p.(Index);
RMS[ns,v] = sqrt(mean((X[Index] .- ft).^2));
push!(RMSk,RMS )
end
#inbounds for nq = 1:length(q)
qRMS[nq,ns] = RMS[ns].^q[nq];
Fq[nq,ns] = mean( qRMS[nq,ns] ).^(1/q[nq] );
end
Fq[findall(x->x==0, q)[1], ns] = exp( 0.5*mean(log.(RMS[ns].^2) ) ) ;
end
The thing is that the array RMS in Matlab's code is an array of arrays like this:
RMS =
1×7 cell array
{1×159 double} {1×79 double} {1×39 double} {1×19 double} {1×9 double} {1×4 double} {1×2 double}
But Julia returns only the last array
RMS
7×2 Matrix{Float64}:
0.0 0.0
0.0 0.0
0.0 0.0
0.0 0.0
0.0 0.0
0.0 0.0
62178.0 18238.2
How can I obtain the same output as in Matlab?
How can you store arrays into arrays in Julia?
The solutions for this is to use RMScell = Array{Float64}[] is equivalent to a Matlab cell array
using DelimitedFiles, TimeSeries, Plots, DelimitedFiles, Plots
using Polynomials, LinearAlgebra, CSV, DataFrames, StatsBase
sp500 = CSV.read("sp500_Nasdaq.csv", DataFrame) ;
sp500_V = values(sp500[:,2]) ;
SP1 = cumsum( sp500_V .- mean(sp500_V) ) ;
SP1_Ord = sqrt( mean(SP1.^2) ) ;
X = SP1 ;
X = X' ;
function polyfit(xVals,yVals)
n = length(xVals)
xBar, yBar = #fastmath mean(xVals), mean(yVals)
sXX, sXY = #fastmath ones(n)'*(xVals.-xBar).^2 , dot(xVals.- xBar,yVals.-yBar)
b1A = #fastmath sXY/sXX
b0A = #fastmath yBar - b1A*xBar
return b0A, b1A
end
""" Multifractal detrended fluctuation analysis of time series """
scales = [16,32,64,128,256,512,1024];
q = [-5,-3,-1,0,1,3,5] ;
segments = zeros(Int64, (1,length(scales))) ;
global qRMS = zeros( length(q) ,length(scales) ) ;
global Fq = zeros( length(q) , length(scales) ) ;
global RMScell = Array{Float64}[] ;
global qRMScell =[] ;
global segmentsFq = [] ;
#inbounds for ns = 1:length(scales)
global segments[ns] = Int(floor( length(X)/scales[ns] ) ) ;
global ft = zeros(Float64, (segments[ns], length(scales) ) ) ;
global RMS = zeros(Float64, segments[ns]);
#inbounds for v=1:segments[ns]
global Index = ( (v-1)*scales[ns] ) + 1: v*scales[ns] ;
global C = polyfit( Index, X[Index]) ;
global p = Polynomial(C) ;
ft =p.(Index) ;
RMS[v] = sqrt(mean((X[Index] .- ft).^2)) ;
end
l = deepcopy(RMS)
push!(RMScell,l)
global IndexFq = ((ns-1)*length(q) ) + 1 : ns*length(q) ;
push!(segmentsFq, IndexFq) ;
#inbounds for nq = 1:length(q)
l = RMScell[ns].^q[nq]
r = deepcopy(l) ;
push!(qRMScell, r) ;
end
#inbounds for nq = 1: length(scales)
Fq[nq,ns] = mean( qRMScell[segmentsFq[ns]][nq] ).^(1/q[nq] ) ;
end
Fq[findall(x->x==0, q)[1], ns] = exp( 0.5*mean(log.(RMScell[ns].^2) ) ) ;
end
Hq = zeros( Float64,length(q) ) ;
global qRegLine = Array{Float64}[] ;
for nq = 1:length(q)
global C = polyfit( log2.(scales),log2.(Fq[nq,:]) ) ;
Hq[nq] = C[2] ;
global p = Polynomial(C) ;
push!( qRegLine, p.( log2.(scales) ) )
end
tq = Hq.*q .- 1 ;
hq = diff(tq)./(q[2]-q[1]) ;
Dq = ( q[1:end-1].*hq ) - tq[1:end-1] ;

Undefined function or variable 'x'

I am trying to evaluate two matrixes which I defined outside of the function MetNewtonSist using subs and I get the error Undefined function or variable 'x' whenever I try to run the code.
[edit] I added the code for the GaussPivTot function which determines the solution of a liniear system.
syms x y
f1 = x^2 + y^2 -4;
f2 = (x^2)/8 - y;
J = jacobian( [ f1, f2 ], [x, y]);
F = [f1; f2];
subs(J, {x,y}, {1, 1})
eps = 10^(-6);
[ x_aprox,y_aprox, N ] = MetNewtonSist( F, J, 1, 1, eps )
function [x_aprox, y_aprox, N] = MetNewtonSist(F, J, x0, y0, eps)
k = 1;
x_v(1) = x0;
y_v(1) = y0;
while true
k = k + 1;
z = GaussPivTot(subs(J, {x, y}, {x_v(k-1), y_v(k-1)}),-subs(F,{x, y}, {x_v(k-1), y_v(k-1)}));
x_v(k) = z(1) + x_v(k-1);
y_v(k) = z(1) + y_v(k-1);
if norm(z)/norm([x_v(k-1), y_v(k-1)]) < eps
return
end
end
N = k;
x_aprox = x_v(k);
y_aprox = y_v(k);
end
function [x] = GaussPivTot(A,b)
n = length(b);
A = [A,b];
index = 1:n;
for k = 1:n-1
max = 0;
for i = k:n
for j = k:n
if A(i,j) > max
max = A(i,j);
p = i;
m = j;
end
end
end
if A(p,m) == 0
disp('Sist. incomp. sau comp. nedet.')
return;
end
if p ~= k
aux_line = A(p,:);
A(p,:) = A(k, :);
A(k,:) = aux_line;
end
if m ~= k
aux_col = A(:,m);
A(:,m) = A(:,k);
A(:,k) = aux_col;
aux_index = index(m);
index(m) = index(k);
index(k) = aux_index;
end
for l = k+1:n
M(l,k) = A(l,k)/A(k,k);
aux_line = A(l,:);
A(l,:) = aux_line - M(l,k)*A(k,:);
end
end
if A(n,n) == 0
disp('Sist. incomp. sau comp. nedet.')
return;
end
y = SubsDesc(A, A(:,n+1));
for i = 1:n
x(index(i)) = y(i);
end
end
By default, eps is defined as 2.2204e-16 in MATLAB. So do not overwrite it with your variable and name it any word else.
epsilon = 1e-6;
Coming to your actual issue, pass x and y as input arguments to the MetNewtonSist function. i.e. define MetNewtonSist as:
function [x_aprox, y_aprox, N] = MetNewtonSist(F, J, x0, y0, epsilon, x, y)
%added x and y and renamed eps to epsilon
and then call it with:
[x_aprox, y_aprox, N] = MetNewtonSist(F, J, 1, 1, epsilon, x, y);

Image Transformation Without Loop

I am writing image transformation function in matlab instead of using predefined functions like 'imwarp or imtransform'. I am done with writing the code roughly but it is taking too long due to the use of loop.
Please suggest me a solution which can achieve the same result without loops
function I2 = f_transform(A, I1)
%A is an affine transformation matrix
%I1 is original image to be transformed
s=size(A);
if(s(1)~=3 || s(2)~=3)
disp("Invalid Transforming Matrix");
I2=0;
return;
end
if(det(A)==0)
disp("The given Transforming Matrix is Singular");
I2=0;
return;
end
[r, c]=size(I1);
extremeValues = [1 1 r r ; 1 c 1 c; 1 1 1 1];
newExtremeValues = A * extremeValues;
minRow = floor( min( newExtremeValues(1,:) ) );
maxRow = ceil( max( newExtremeValues(1,:) ) );
minCol = floor( min( newExtremeValues(2,:) ) );
maxCol = ceil( max( newExtremeValues(2,:) ) );
I2 = zeros(maxRow - minRow + 1, maxCol - minCol + 1);
for i = minRow:maxRow
for j=minCol:maxCol
b = A \ [i j 1]';
p = b(1) / b(3);
q = b(2) / b(3);
if(p >= 1 && p <= r && q >= 1 && q <= c)
I2(i - minRow + 1, j - minCol + 1) = I1(round(p),round(q));
end
end
end
I2 = uint8(I2);
return;
end

How can I easily create this matrix?

How can I easily create the following matrix in MATLAB?
With A (nxn), B (nxp) and N a positive integer.
Gamma = [B 0 0 ... 0 ;
A*B B 0 ... 0 ;
A^2*B A*B B ... 0 ;
... ... ... ... ... ;
A^(N-1)*B A^(N-2)*B A^(N-3)*B ... B];
How about
[g{1:N,1:N}] = deal( zeros(n,p) );
g{1,1} = B;
for ii = 2:N
g( ii, 2:end ) = g( ii-1, 1:end-1 );
g{ ii, 1 } = A * g{ ii-1, 1 };
end
Gamma = cell2mat( g );
This works, though it is less efficient than it could be.
n = size(A,1);
p = size(B,2);
N = 3;
Gamma = zeros(N*n, N*p);
for ii = 1:N
for jj = 1:N
if ii >= jj
Gamma((ii-1)*n+1:ii*n,(jj-1)*p+1:jj*p) = A^(ii-jj) * B;
end
end
end
Edit: Here's a more efficient version, that does the minimum amount of matrix multiplication.
n = size(A,1);
p = size(A,2);
N = 3;
Gamma = zeros(N*n, N*p);
# Pre-compute all the matrix multiplications we'll need.
memo = cell(1, N);
memo{1} = B;
for ii = 1:N-1
memo{ii+1} = A * memo{ii};
end
for ii = 1:N
for jj = 1:N
if ii >= jj
Gamma((ii-1)*n+1:ii*n,(jj-1)*p+1:jj*p) = memo{ii-jj+1};
end
end
end

Radon transform matrix representation

I am looking for a MATLAB solution to generate the matrix representation of a discrete Radon transform (DRT). That is, given a vectorized version of an MxN image, X, I'd like to generate the matrix R such that R*X(:) is a DRT of the image. In MATLAB, I am expecting it to look something like the following:
>> X = 2D_Image_Of_Size_MxN;
>> R = DRT_Matrix_Of_Size_LPxMN;
>> DRT = reshape( R * X(:), L, P );
I know there are several ways to define a DRT, so I'll just say that I am looking for a normal or standard or not-too-out-of-the-ordinary implmentation.
function [ R rho theta ] = radonmatrix( drho, dtheta, M, N )
% radonmatrix - Discrete Radon Trasnform matrix
%
% SYNOPSIS
% [ R rho theta ] = radonmatrix( drho, dtheta, M, N )
%
% DESCRIPTION
% Returns a matrix representation of a Discrete Radon
% Transform (DRT).
%
% INPUT
% drho Radial spacing the the DRT.
% dtheta Angular spacing of the DRT (rad).
% M Number of rows in the image.
% N Number of columns in the image.
%
% OUTPUT
% R LP x MN DRT matrix. The values of the L and
% P will depend on the radial and angular spacings.
% rho Vector of radial sample locations.
% theta Vector of angular sample locations (rad).
%
% For each angle, we define a set of rays parameterized
% by rho. We then find the pixels on the MxN grid that
% are closest to each line. The elements in R corresponding
% to those pixels are given the value of 1.
% The maximum extent of the region of support. It's for
% rho = 0 and theta = pi/4, the line that runs caddy-corner.
W = sqrt( M^2 + N^2 );
rho = -W/2 : drho : W/2;
theta = 0 : dtheta : 180 - dtheta;
L = length( rho );
P = length( theta );
R = false( L*P, M*N );
% Define a meshgrid w/ (0,0) in the middle that
% we can use a standard coordinate system.
[ mimg nimg ] = imggrid( 1, 1, [ M N ] );
% We loop over each angle and define all of the lines.
% We then just figure out which indices each line goes
% through and put a 1 there.
for ii = 1 : P
phi = theta(ii) * pi/180;
% The equaiton is rho = m * sin(phi) + n * cos(phi).
% We either define a vector for m and solve for n
% or vice versa. We chose which one based on angle
% so that we never g4et close to dividing by zero.
if( phi >= pi/4 && phi <= 3*pi/4 )
t = -W : min( 1/sqrt(2), 1/abs(cot(phi)) ) : +W;
T = length( t );
rhom = repmat( rho(:), 1, T );
tn = repmat( t(:)', L, 1 );
mline = ( rhom - tn * cos(phi) ) ./ sin(phi);
for jj = 1 : L
p = round( tn(jj,:) - min( nimg ) ) + 1;
q = round( mline(jj,:) - min( mimg ) ) + 1;
inds = p >= 1 & p <= N & q >= 1 & q <= M;
R( (ii-1)*L + jj, unique( sub2ind( [ M N ], q(inds), p(inds) ) ) ) = 1;
end
else
t = -W : min( 1/sqrt(2), 1/abs(tan(phi)) ) : +W;
T = length( t );
rhon = repmat( rho(:)', T, 1 );
tm = repmat( t(:), 1, L );
nline = ( rhon - tm * sin(phi) ) ./ cos(phi);
for jj = 1 : L
p = round( nline(:,jj) - min( nimg ) ) + 1;
q = round( tm(:,jj) - min( mimg ) ) + 1;
inds = p >= 1 & p <= N & q >= 1 & q <= M;
R( (ii-1)*L + jj, unique( sub2ind( [ M N ], q(inds), p(inds) ) ) ) = 1;
end
end
end
R = double( sparse( R ) );
return;
Here is the imggrid function used in the above.
function [ m n ] = imggrid( dm, dn, sz )
% imggrid -- Returns rectilinear coordinate vectors
%
% SYNOPSIS
% [ m n ] = imggrid( dm, dn, sz )
%
% DESCRIPTION
% Given the sample spacings and the image size, this
% function returns the row and column coordinate vectors
% for the image. Both vectors are centered about zero.
%
% INPUT
% dm Spacing between rows.
% dn Spacing between columns.
% sz 2x1 vector of the image size: [ Nrows Ncols ].
%
% OUTPUT
% m sz(1) x 1 row coordinate vector.
% n 1 x sz(2) column coordinate vector.
M = sz(1);
N = sz(2);
if( mod( M, 2 ) == 0 )
m = dm * ( ceil( -M/2 ) : floor( M/2 ) - 1 )';
else
m = dm * ( ceil( -M/2 ) : floor( M/2 ) )';
end
if( mod( N, 2 ) == 0 )
n = dn * ( ceil( -N/2 ) : floor( N/2 ) - 1 );
else
n = dn * ( ceil( -N/2 ) : floor( N/2 ) );
end
image = phantom();
projection = radon(image);
R = linsolve(reshape(image,1,[]), reshape(projection,1,[]));