I have a series of z values zk and a temperature value Tadjust0 at each zk. From this I'd like to create a series of steps of height Tadjust0(j) going from zk(j-1) to zk(j).
I'm trying to achieve this with:
zk=[40.41; 50.04; 59.56; 68.95; 78.22; 87.40; 99.95];
Tadjust0=[-1.1500; 1.6033; 2.4287; 3.2430; 3.8500; 3.8500; 3.8500];
zo=[1:0.01:100];
Tadjust1=interp1(zk,Tadjust0,zo,'next','extrap');
figure
plot(zo,Tadjust1)
figure
scatter(zk,Tadjust0)
But as far as I can tell, the interpolation seems to be using 'nearest' rather than 'next': the steps don't end at zk(j), they end at (zk(j)+zk(j+1))/2. In fact, if I change the code to 'nearest' I get exactly the same plots.
I suspect that the problem lies within the simultaneous use of next neighbour interpolation and extrapolation. You can separate the interpolation and extrapolation to be sure:
zk=[40.41; 50.04; 59.56; 68.95; 78.22; 87.40; 99.95];
Tadjust0=[-1.1500; 1.6033; 2.4287; 3.2430; 3.8500; 3.8500; 3.8500];
zo=[1:0.01:100];
% Nearest neigbour inter-/ extrapolation
Tadjust1=interp1(zk,Tadjust0,zo,'nearest','extrap');
% Get indices of zo within the range of zk
interp_range = zo > min(zk) & zo < max(zk);
% Replace the interpolated values by next neighbour interpolation
Tadjust1(interp_range)=interp1(zk,Tadjust0,zo(interp_range),'next');
figure
plot(zo,Tadjust1)
figure
scatter(zk,Tadjust0)
Raw data:
Result:
Related
For a function of 3 variables: f, ksid and rho, I want to search the combination of f and ksid in order to have the minimum peak for the curve y-rho.
I used 3 'for loops' to define the range of the 3 variables.
minH5 is the the value of minimum peak for curve y-rho, p is the index which can help me to find the corresponding value of f and ksid.
The result is different from fitting curve which I drawed to compare. I would appreciate a lot if someone can point out where is the error.
clear all
close all
m=0.01;
ksi=0.02;
f1=[];
ksid1=[];
f1=[];
max1f=[];
max1=[];
y1=[];
pe1=[];
H5e=[];
for ksid=0.1:0.0001:0.12
for f=0.85:0.0001:0.9
for e=0.85:0.001:1.4
y=((f.^2-e.^2).^2+(2.*ksid.*e.*f).^2).^0.5./((-f.^2.*e.^2.*m+(1-e.^2).*(f.^2-
e.^2)-4.*ksi.*ksid.*f.*e.^2).^2+4.*(ksi.*e.*(f.^2-e.^2)+ksid.*f.*e.*(1-e.^2.*(1+m))).^2).^0.5;
y1=[y1,y];
end
[H5e,pe]=max(y1);
y1 = [];
pe1=[pe1,pe];
max1f=[max1f,H5e];
f1=[f1,f];
end
ksid1=[ksid1,ksid];
end
[minH5,p]=min(max1f);
I have a matrix time-series data for 8 variables with about 2500 points (~10 years of mon-fri) and would like to calculate the mean, variance, skewness and kurtosis on a 'moving average' basis.
Lets say frames = [100 252 504 756] - I would like calculate the four functions above on over each of the (time-)frames, on a daily basis - so the return for day 300 in the case with 100 day-frame, would be [mean variance skewness kurtosis] from the period day201-day300 (100 days in total)... and so on.
I know this means I would get an array output, and the the first frame number of days would be NaNs, but I can't figure out the required indexing to get this done...
This is an interesting question because I think the optimal solution is different for the mean than it is for the other sample statistics.
I've provided a simulation example below that you can work through.
First, choose some arbitrary parameters and simulate some data:
%#Set some arbitrary parameters
T = 100; N = 5;
WindowLength = 10;
%#Simulate some data
X = randn(T, N);
For the mean, use filter to obtain a moving average:
MeanMA = filter(ones(1, WindowLength) / WindowLength, 1, X);
MeanMA(1:WindowLength-1, :) = nan;
I had originally thought to solve this problem using conv as follows:
MeanMA = nan(T, N);
for n = 1:N
MeanMA(WindowLength:T, n) = conv(X(:, n), ones(WindowLength, 1), 'valid');
end
MeanMA = (1/WindowLength) * MeanMA;
But as #PhilGoddard pointed out in the comments, the filter approach avoids the need for the loop.
Also note that I've chosen to make the dates in the output matrix correspond to the dates in X so in later work you can use the same subscripts for both. Thus, the first WindowLength-1 observations in MeanMA will be nan.
For the variance, I can't see how to use either filter or conv or even a running sum to make things more efficient, so instead I perform the calculation manually at each iteration:
VarianceMA = nan(T, N);
for t = WindowLength:T
VarianceMA(t, :) = var(X(t-WindowLength+1:t, :));
end
We could speed things up slightly by exploiting the fact that we have already calculated the mean moving average. Simply replace the within loop line in the above with:
VarianceMA(t, :) = (1/(WindowLength-1)) * sum((bsxfun(#minus, X(t-WindowLength+1:t, :), MeanMA(t, :))).^2);
However, I doubt this will make much difference.
If anyone else can see a clever way to use filter or conv to get the moving window variance I'd be very interested to see it.
I leave the case of skewness and kurtosis to the OP, since they are essentially just the same as the variance example, but with the appropriate function.
A final point: if you were converting the above into a general function, you could pass in an anonymous function as one of the arguments, then you would have a moving average routine that works for arbitrary choice of transformations.
Final, final point: For a sequence of window lengths, simply loop over the entire code block for each window length.
I have managed to produce a solution, which only uses basic functions within MATLAB and can also be expanded to include other functions, (for finance: e.g. a moving Sharpe Ratio, or a moving Sortino Ratio). The code below shows this and contains hopefully sufficient commentary.
I am using a time series of Hedge Fund data, with ca. 10 years worth of daily returns (which were checked to be stationary - not shown in the code). Unfortunately I haven't got the corresponding dates in the example so the x-axis in the plots would be 'no. of days'.
% start by importing the data you need - here it is a selection out of an
% excel spreadsheet
returnsHF = xlsread('HFRXIndices_Final.xlsx','EquityHedgeMarketNeutral','D1:D2742');
% two years to be used for the moving average. (250 business days in one year)
window = 500;
% create zero-matrices to fill with the MA values at each point in time.
mean_avg = zeros(length(returnsHF)-window,1);
st_dev = zeros(length(returnsHF)-window,1);
skew = zeros(length(returnsHF)-window,1);
kurt = zeros(length(returnsHF)-window,1);
% Now work through the time-series with each of the functions (one can add
% any other functions required), assinging the values to the zero-matrices
for count = window:length(returnsHF)
% This is the most tricky part of the script, the indexing in this section
% The TwoYearReturn is what is shifted along one period at a time with the
% for-loop.
TwoYearReturn = returnsHF(count-window+1:count);
mean_avg(count-window+1) = mean(TwoYearReturn);
st_dev(count-window+1) = std(TwoYearReturn);
skew(count-window+1) = skewness(TwoYearReturn);
kurt(count-window +1) = kurtosis(TwoYearReturn);
end
% Plot the MAs
subplot(4,1,1), plot(mean_avg)
title('2yr mean')
subplot(4,1,2), plot(st_dev)
title('2yr stdv')
subplot(4,1,3), plot(skew)
title('2yr skewness')
subplot(4,1,4), plot(kurt)
title('2yr kurtosis')
I am not very sure how the hist function in MATLAB works. I seem to have few problems with it.
Bascially, in the code below, i am trying to run the rotation invariant Uniform Local Binary Pattern(LBP) code. I have no problem with the LBP code but the problem is with hist function(indicated in the code below).
The problem is that the range i should get is from 0:9 but when i apply the histogram function i get values greater than 9 such as 35, 27 and even values such as 178114.Not very sure how to correct it.
I2 = imread('test.png');
RIUniformHist=[];
m=size(I2,1);
n=size(I2,2);
for i=1:10:m
for j=1:10:n
for k=i+1:i+8
for l=j+1:j+8
J0=I2(k,l);
I3(k-1,l-1)=I2(k-1,l-1)>J0;
I3(k-1,l)=I2(k-1,l)>J0;
I3(k-1,l+1)=I2(k-1,l+1)>J0;
I3(k,l+1)=I2(k,l+1)>J0;
I3(k+1,l+1)=I2(k+1,l+1)>J0;
I3(k+1,l)=I2(k+1,l)>J0;
I3(k+1,l-1)=I2(k+1,l-1)>J0;
I3(k,l-1)=I2(k,l-1)>J0;
LBP=I3(k-1,l-1)*2^7+I3(k-1,l)*2^6+I3(k-1,l+1)*2^5+I3(k,l+1)*2^4+I3(k+1,l+1)*2^3+I3(k+1,l)*2^2+I3(k+1,l-1)*2^1+I3(k,l-1)*2^0;
bits = bitand(LBP, 2.^(7:-1:0))>0;
if nnz(diff(bits([1:end, 1]))) <= 2
RIULBP(k,l)=abs(I3(k-1,l-1)-I3(k-1,l))+ abs(I3(k-1,l)-I3(k-1,l+1))+ abs(I3(k-1,l+1)-I3(k,l+1))+ abs(I3(k,l+1)-I3(k+1,l+1))+abs(I3(k+1,l+1)-I3(k+1,l))+abs(I3(k+1,l)-I3(k+1,l-1))+abs(I3(k+1,l-1)-I3(k,l-1));
else
RIULBP(k,l)=9;
end
end
end
RIULBP=uint8(RIULBP);
RIULBPv=reshape(RIULBP,1,size(RIULBP,1)*size(RIULBP,2));
RIUHist=hist(RIULBPv,0:9); % problem
RIUniformHist = [RIUniformHist RIUHist];
end
end
The vector returned by
RIUHist=hist(data, bins)
is the count of how many elements of data are nearest the point identified by the bins vector. So if you have a value of 178114, that juts means that there were 178114 elements of data that were nearest to the matching index in bins.
You can use
[RIUHist, binsOut] = hist(data)
to let Matlab choose the bins (I believe it uses 20 bins) or
[RIUHist, binsOut] = hist(data, binCount)
To let Matlab choose the bins, but force a certain number of bins (I often use 100 or 200).
I am a bit stuck on a simple exercise and would appreciate some help.
I am trying to do some simple 2D interpolation using the "interp2" function in Matlab for a variable 'tmin' of dimension [15x12]:
lat = 15:1.5:32;
lon = 70:1.5:92;
lat_interp = 15:1:32;
lon_interp = 70:1:92;
[X,Y] = meshgrid(lat,lon);
[Xi,Yi] = meshgrid(lat_interp,lon_interp);
tmin_interp = zeros(length(lon_interp),length(lat_interp),Num_Days);
tmin_interp(:,:) = interp2(X,Y,tmin(:,:),Xi,Yi,'linear');
This code results in the last row and last column of tmin_interp to be NaNs, i.e.:
tmin_interp(23,1:18) ==> NaN
tmin_interp(1:23,18) ==> NaN
Does anyone know what I might be doing wrong? Am I making a simple mistake with regards to the interpolation setup? Thank you for your time.
The reason they are nans is that there is no data before and after your grid to interpolate to. Linear interpolation uses the gradient of the field at the Xi,Yi, in order to estimate the value at that point. If there is nothing either side, it can't.
You can use extrapval parameter to extrapolate outside the X,Y you specify. Just add the parameter 0 after 'linear':
interp2(X,Y,tmin(:,:),Xi,Yi,'linear', 0);
This will put zero for the points 'on the edge'. However, it is likely that for points outside, they may fall off to some default value, like zero. To do this, you can add zeros before and after tmin:
tmin_padded = [ zeros(1,size(tmin,2)+2)
zeros(size(tmin,1),1) tmin zeros(size(tmin,1),1)
zeros(1,size(tmin,2)+2) ];
(haven't checked this but you get the idea.) you will also need to add some pre- and post-values to X and Y.
Use some other value, if that's the 'outside' or 'default' value of tmin.
PS why are you creating tmin_interp as 3-dimensional?
Or just try:
interp2(X,Y,tmin(:,:),Xi,Yi,'spline');
to avoid imposing the 0 value.
HTH!
i have a piece of metropolis algorithm:
mB=5.79*10^(-9); %Bohr magnetone in eV*G^-1
kB=0.86*10^(-4); %Boltzmann in eV*K^-1
%system parameters
L=60; %side square grid
L2=L*L; % total number grid position
Tstep=5; %step in temperature change (K)
Maxstep=10; %max number of steps
nmcs=5; % cycle numberof Metropolis algorithm
magnet=NaN(1,Maxstep);%store magnetization in "monte carlo images" of sample
%Creation initial point arrangement of magnetic spins
%Outer parameters
H=100000; %Gauss
T=20; % Kelvin
%Energy alteration in spin-reverse
de =# (i,j) (2*mB*H).*mlat(i,j);
%Metropolis probability
pmetro=# (i,j) exp(-de(i,j)./(kB*T));
%Creation and display of initial lattice
mlat=2*round(rand(L,L))-1;
mtotal=sum(mlat(:))./L2
% Alteration of system with time
for ii=1:Maxstep
for imc=1:nmcs
for i=1:L
for j=1:L
if pmetro(i,j)>=1
mlat(i,j)=-mlat(i,j);
elseif rand<pmetro(i,j)
mlat(i,j)=-mlat(i,j);
end
end
end
end
magnet(:,ii)=sum(mlat(:))./L2;
%figure(ii);
%pcolor(mlat);
% shading interp;
end
m1=mean(magnet)
error=std(magnet) ./sqrt(numel(magnet))
fprintf('Temperature = %d K',T)
figure(13)
plot(magnet(1,:),'b.')
axis([0 10 0 0.5])
grid on
xlabel('i (Configuration) ')
ylabel('M/(N*mB)')
Now,the problem is in figure(13).The values it gives me are around zero (0.05,0.02..).It supposes to give me values around 0.3..
Generally,the graph its ok,It gives me the right "shape"(it has points) but as i said around zero.
I really don't know how to put this post in order to be understood.Maybe i have some mistake in the "magnet"matrix ,i don't know.
Anyway,i don't demand from anybody to check it thoroughly ,i am just asking if with a quick look anyone can help.
ΕDIT--->> Also,sometimes when i run the program ,it gives me :
Undefined function or method 'mlat'
for input arguments of type 'double'.
Error in ==> #(i,j)(2*mB*H).*mlat(i,j)
Error in ==>
#(i,j)exp(-de(i,j)./(kB*T))
Error in ==> metropolis at 39
if pmetro(i,j)>=1
EDIT--->>> I found the "mistake" .In my code in the loops where i have the function "pmetro" i replaced it with the "exp(-(2*mB*H).*mlat(i,j)./(kB*T))" and the program worked just fine!!!
Why it didn't work with calling the "pmetro"??How can i overcome this?Is there a problem with function handles in loops?
Blockquote
I very strongly suggest that you try writing code without using any function handles until you're really familiar with Matlab.
The line
de =# (i,j) (2*mB*H).*mlat(i,j);
is what causes your problems. In Matlab, when you define a function handle that refers to, say, an array, the function handle will use the array as it was at the time of definition. In other words, even though mlat changes inside your loop, mlat(i,j) inside the function de is always the same. In fact, you cannot even run this code unless you have previously defined mlat in the workspace.
You should therefore rewrite the main loop as follows
for iStep = 1:maxStep
for imc = 1:mcs
pmetro = $some function of mlat - this can be calculated using the
entire array as input
%# for each element in mlat (and thus pmetro), decide whether
%# you have to switch the spin
switchIdx = pmetro > 1 | pmetro < rand(size(mlat));
mlat(switchIdx) = -mlat(switchIdx);
end
$calculate magnetization$
end
Also, note that there is a command mean to take the average. No need to sum and then divide by the number of elements.