Serving the Quantitative Finance Community

 
User avatar
Amin
Topic Author
Posts: 2586
Joined: July 14th, 2002, 3:00 am

Re: Breakthrough in the theory of stochastic differential equations and their simulation

February 15th, 2024, 8:04 am

Friends, we were not working with correlation earlier and my intention was to get the model to work somewhere and then fix the errors. Now when we have to work with correlations, I think we have an error in our jacobian calculation as well. We do change probability density in two dimensions with respect to bivariate standard normal and then recreate the original probability density after doing change of derivatives with two standard normals (standard normal density functions in the equation). 
We have calculated [$]\frac{\partial Z_x}{\partial X}[$] which is the right derivative. But I think problem is that we calculated this function from one dimensional slices (along Z_y) of two dimensional density. This partial derivative has to be calculated from the entire two dimensional density(two dimensional calculations) and not from slices. Sorry this was an error that I earlier overlooked since things were working well (without correaltions) and we were still not working with correlations. Since partial derivative is written the same way, it gives the wrong impression that calculations are right but the way I calculated it from one dimensional slices, it was a wrong way to calculate it. I think it can be calculated form one dimensional slices but we will have to modify the calculations somewhat for that. I will be fixing this in new versions. We can calculate it both ways, from the 2D function or from modifying the 1D slice calculations. I will try to come up with a more detailed post in the evening but surely will fix this in new version of the program. 
You think life is a secret, Life is only love of flying, It has seen many ups and downs, But it likes travel more than the destination. Allama Iqbal
 
User avatar
Amin
Topic Author
Posts: 2586
Joined: July 14th, 2002, 3:00 am

Re: Breakthrough in the theory of stochastic differential equations and their simulation

February 16th, 2024, 8:56 pm

Friends, I tried the suggestion in previous post and found out that actually this was not the problem and the way I was calculating derivatives on the slices, it was probably right.
However I think that the part  of my program where I reverse the standardization to get densities back in original form has problems for X when X and Y are correlated. I am trying to find a proper way to fix that now.
You think life is a secret, Life is only love of flying, It has seen many ups and downs, But it likes travel more than the destination. Allama Iqbal
 
User avatar
Amin
Topic Author
Posts: 2586
Joined: July 14th, 2002, 3:00 am

Re: Breakthrough in the theory of stochastic differential equations and their simulation

February 17th, 2024, 10:18 am

Friends, yes there was an error in backing out standardized version of 2D density of X. I have fixed the error and played somewhat with the program and have been able to get very close shapes to stochastic volatility models with high negative correlations. Here are a few comparison graphs for the problems with high negative correlation.

Please pardon slight discontinuities in the analytic graphs (we will continue to fix these errors/problems in future). I will post the program used to make these graphs in the next post. There was a very silly error in de-standardizing the 2D hermite series/Z-series. 

.
.
Image
.
Image
.
.
Image
.
.
Image
.
.
.
Image
.
.
Image

.
.
.
Image
.
.
.
Image
.
.
.
Image
You think life is a secret, Life is only love of flying, It has seen many ups and downs, But it likes travel more than the destination. Allama Iqbal
 
User avatar
Amin
Topic Author
Posts: 2586
Joined: July 14th, 2002, 3:00 am

Re: Breakthrough in the theory of stochastic differential equations and their simulation

February 17th, 2024, 10:36 am

Friends, we still have to work on better optimization and also on how to divide the marginal density better into first row and first column (I did this just ad-hoc yet). But I am sure that we are fixing all problems and issues one by one. Option prices are still far from perfect for high correlation but we got a better general shape by fixing some previous errors.
We will have to work on robustness of solutions against the kind of spikes we see in the analytic graphs in previous posts but I am sure we will soon fix all these issues.

Here are the programs.
function []= SVMonteCarloAndAssetConditionalDensityHermites()

%The purpose of this program is to take two random varaibles one of which
%is independent and the other is dependent on the first varaible also with 
%its own dynamics.
%We want to capture the conditional dependent density structure from the 
%cross moments of dependent and in dependent random variables by
%employing a two dimensional density for the dependent variable.
%We want to find the detailed relationship between Y and X so we can get
%the conditional density of dependent variable X given a particular value
%of independent variable Y. This will be done by calibrating coefficients
%of our 2D hermite series to data so that a very good fit to cross moments
%between X and Y is retrieved.

%In this program, we jointly simulate the system of SV and asset SDEs to
%get the joint data of asset and stochastic volatility.
%We use this data to calculate cross moments of asset and volatility. These
%cross moments are then used to calibrate the coefficients of the 2D
%hermite series density of dependent variable X. We also find univariate
%density of independent random variable volatility.
%We use the 2D Hermite series density of dependent variable X and
%univariate density of V to draw a graph of bivariate analytic density of
%X and V.
%We compare this graph of analytic bivariate density with monte carlo
%generated 2D bivariate density of simulated values of X and V in order to
%get an idea how good our calculation of 2D dependent density of X is. We
%also compare analytically calculated values of call prices using our
%calculated 2D hermite series conditional density of X in order to get an
%idea how good our calculation of the 2D hermite series density of X is.

% 2D Hermite Series Form used in this program is given as
% 
% X = bnmH(1,1) + bnmH(2,1) H_1(Z_y) + bnmH(3,1) H_2(Z_y) + bnmH(4,1) H_3(Z_y) + bnmH(5,1) H_4(Z_y) + bnmH(6,1) H_5(Z_y) 
% + [ bnmH(1,2) + bnmH(2,2) H_1(Z_y) + bnmH(3,2) H_2(Z_y) + bnmH(4,2) H_3(Z_y) + bnmH(5,2) H_4(Z_y) + bnmH(6,2) H_5(Z_y)] H_1(Zx) 
% + [ bnmH(1,3) + bnmH(2,3) H_1(Z_y) + bnmH(3,3) H_2(Z_y) + bnmH(4,3) H_3(Z_y) + bnmH(5,3) H_4(Z_y) + bnmH(6,3) H_5(Z_y)] H_2(Zx)
% + [ bnmH(1,4) + bnmH(2,4) H_1(Z_y) + bnmH(3,4) H_2(Z_y) + bnmH(4,4) H_3(Z_y) + bnmH(5,4) H_4(Z_y) + bnmH(6,4) H_5(Z_y)] H_3(Zx)
% + [ bnmH(1,5) + bnmH(2,5) H_1(Z_y) + bnmH(3,5) H_2(Z_y) + bnmH(4,5) H_3(Z_y) + bnmH(5,5) H_4(Z_y) + bnmH(6,5) H_5(Z_y)] H_4(Zx)
% + [ bnmH(1,6) + bnmH(2,6) H_1(Z_y) + bnmH(3,6) H_2(Z_y) + bnmH(4,6) H_3(Z_y) + bnmH(5,6) H_4(Z_y) + bnmH(6,6) H_5(Z_y)] H_5(Zx)
 
% 2D Z-Series Form used in this program is given as
% 
% X = bnm(1,1) + bnm(2,1) Z_y + bnm(3,1) (Z_y)^2 + bnm(4,1) (Z_y)^3 + bnm(5,1) (Z_y)^4 + bnm(6,1) (Z_y)^5 
% + [ bnm(1,2) + bnm(2,2) Z_y + bnm(3,2) (Z_y)^2 + bnm(4,2) (Z_y)^3 + bnm(5,2) (Z_y)^4 + bnm(6,2) (Z_y)^5 ] Zx 
% + [ bnm(1,3) + bnm(2,2) Z_y + bnm(3,3) (Z_y)^2 + bnm(4,3) (Z_y)^3 + bnm(5,3) (Z_y)^4 + bnm(6,3) (Z_y)^5 ] Zx^2 
% + [ bnm(1,4) + bnm(2,2) Z_y + bnm(3,4) (Z_y)^2 + bnm(4,4) (Z_y)^3 + bnm(5,4) (Z_y)^4 + bnm(6,4) (Z_y)^5 ] Zx^3 
% + [ bnm(1,5) + bnm(2,2) Z_y + bnm(3,5) (Z_y)^2 + bnm(4,5) (Z_y)^3 + bnm(5,5) (Z_y)^4 + bnm(6,5) (Z_y)^5 ] Zx^4 
% + [ bnm(1,6) + bnm(2,2) Z_y + bnm(3,6) (Z_y)^2 + bnm(4,6) (Z_y)^3 + bnm(5,6) (Z_y)^4 + bnm(6,6) (Z_y)^5 ] Zx^5


%Asset SDE is
%dX(t) = a X(t)^alpha1 dt+ b X(t)^alpha2 dt+ sigma1 V(t)^gammaV X(t)^gammaX dZ(t)
%We usually take a=0 and b=0 in our simulations
%SV SDE is 
%dV(t)=mu1 V(t)^beta1 dt+ mu2 V(t)^beta2 dt + sigma0 V(t)^gamma dZ(t)
%In mean reverting SDEs we ususally have
%mu1= kappaV * thetaV
%beta1=0
%mu2=-kappa
%beta2=0



X0=1.0;
alpha1=0;
alpha2=1;
kappaX=0;
thetaX=1;
a=kappaX*thetaX;
b=-kappaX;

rho=-.7;
%sigma1=1;
sigma1=1;%.225;%1;
gammaV=.5;
gammaX=.95;
% %%%%%%%%`%%%%%
V0=.32;%1;%.35;
thetaV=.045;%1;%.04;
kappaV=1.5;%1.5;
mu1=kappaV*thetaV;
mu2=-kappaV;
beta1=0;
beta2=1;
gamma=.5;
sigma0=.45%1.250%.5;

%V0=1;
%thetaV=1;
%kappaV=1.50;
mu1=kappaV*thetaV;
mu2=-kappaV;
beta1=0;

beta2=1;
%gamma=.5;
%sigma0=1.25;

dt=.03125/2;
Tt=64*1;


T=Tt*dt;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5

%In this code block, we do monte carlo simulation of stochastic volatility SDEs
%And also calculate monte carlo call prices.

seed0=21872418;
seed0=82150987;
rng(seed0, 'twister')
paths=500000;
V(1:paths)=V0;
X(1:paths)=X0;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5


paths0=paths;
paths00=paths;
Random1(1:paths00)=0;
Random2(1:paths0)=0;

for tt=1:Tt
    
Random2=randn(size(Random2)); 
Random1=randn(size(Random1)); 

% sum(Random1)/paths
% sum(Random1.^2)/paths
% sum(Random1.^3)/paths
% sum(Random1.^4)/paths
% sum(Random1.^5)/paths
% sum(Random1.^6)/paths
% 
% tt
% 
% str=input("Look at moments of MC Normals");

%Random1(paths00+1:2*paths00)=-1*Random1(1:paths00);
%Random2(paths0+1:2*paths0)=-1*Random2(1:paths0);    
%Random1(paths0+1:2*paths0)=Random1(1:paths0);    
%antithetic variates above


X(1:paths)=X(1:paths)+ ...
    (a* X(1:paths).^alpha1 + b* X(1:paths).^alpha2)* dt + ...
    sqrt(1-rho^2)* sigma1* V(1:paths).^gammaV.* X(1:paths).^gammaX .*Random1(1:paths) * sqrt(dt) + ...
    rho* sigma1* V(1:paths).^gammaV .*X(1:paths).^gammaX .*Random2(1:paths)*sqrt(dt) + ...
    (a*alpha1* X(1:paths).^(alpha1-1)+b*alpha2* X(1:paths).^(alpha2-1)).* ...
    (((a* X(1:paths).^alpha1 + b* X(1:paths).^alpha2)* dt^2/2)+ ...
    (sqrt(1-rho^2)* sigma1* V(1:paths).^gammaV.* X(1:paths).^gammaX .*Random1(1:paths) *(1-1/sqrt(3)).*dt^1.5+ ...
    rho* sigma1* V(1:paths).^gammaV .*X(1:paths).^gammaX .*Random2(1:paths)*(1-1/sqrt(3)).*dt^1.5))+ ...
    .5*(a*alpha1*(alpha1-1)* X(1:paths).^(alpha1-2)+b*alpha2*(alpha2-1).* X(1:paths).^(alpha2-2)).* ...
    ( sigma1^2* V(1:paths).^(2*gammaV).* X(1:paths).^(2*gammaX)) *dt^2/2 + ...
    sqrt(1-rho^2)* sigma1* V(1:paths).^gammaV.*gammaX.* X(1:paths).^(gammaX-1).* ...
    ((a* X(1:paths).^alpha1 + b* X(1:paths).^alpha2).*Random1(1:paths) * 1/sqrt(3).* dt^1.5 + ...
    sqrt(1-rho^2)* sigma1* V(1:paths).^gammaV.* X(1:paths).^gammaX .*(Random1(1:paths).^2-1) * dt/2 + ...
    rho* sigma1* V(1:paths).^gammaV .*X(1:paths).^gammaX .*Random1(1:paths).*Random2(1:paths)*dt/2)+ ...
    .5*sqrt(1-rho^2)* sigma1* V(1:paths).^gammaV.*gammaX.*(gammaX-1).* X(1:paths).^(gammaX-2).* ...
    (sigma1^2* V(1:paths).^(2*gammaV).* X(1:paths).^(2*gammaX) .*Random1(1:paths).*1/sqrt(3).*dt^1.5)+ ...
    sqrt(1-rho^2)* sigma1*gammaV.* V(1:paths).^(gammaV-1).* X(1:paths).^(gammaX).* ...
    ((mu1.*V(1:paths).^beta1 + mu2.*V(1:paths).^beta2).*Random1(1:paths) * 1/sqrt(3).* dt^1.5 + ...
    sigma0*V(1:paths).^gamma.*Random1(1:paths).*Random2(1:paths)*dt/2)+ ...
    .5*sqrt(1-rho^2)* sigma1*gammaV.*(gammaV-1).* V(1:paths).^(gammaV-2).* X(1:paths).^(gammaX).* ...
    (sigma0^2*V(1:paths).^(2*gamma).*Random1(1:paths)*1/sqrt(3)*dt^1.5)+ ...
    sqrt(1-rho^2)* sigma1*gammaV.* V(1:paths).^(gammaV-1).*gammaX.* X(1:paths).^(gammaX-1).* ...
    rho.* sigma1.* V(1:paths).^gammaV .*X(1:paths).^gammaX .*sigma0.*V(1:paths).^gamma.*Random1(1:paths)*1/sqrt(3)*dt^1.5+ ...
    rho* sigma1* V(1:paths).^gammaV.*gammaX.* X(1:paths).^(gammaX-1).* ...
    ((a* X(1:paths).^alpha1 + b* X(1:paths).^alpha2).*Random2(1:paths) * 1/sqrt(3).* dt^1.5 + ...
    sqrt(1-rho^2)* sigma1* V(1:paths).^gammaV.* X(1:paths).^gammaX .*Random1(1:paths).*Random2(1:paths) * dt/2 + ...
    rho* sigma1* V(1:paths).^gammaV .*X(1:paths).^gammaX .*(Random2(1:paths).^2-1)*dt/2)+ ...
    .5*rho* sigma1* V(1:paths).^gammaV.*gammaX.*(gammaX-1).* X(1:paths).^(gammaX-2).* ...
    (sigma1^2* V(1:paths).^(2*gammaV).* X(1:paths).^(2*gammaX) .*Random2(1:paths).*1/sqrt(3).*dt^1.5)+ ...
    rho* sigma1*gammaV.* V(1:paths).^(gammaV-1).* X(1:paths).^(gammaX).* ...
    ((mu1.*V(1:paths).^beta1 + mu2.*V(1:paths).^beta2).*Random2(1:paths) * 1/sqrt(3).* dt^1.5 + ...
    sigma0*V(1:paths).^gamma.*(Random2(1:paths).^2-1)*dt/2)+ ...
    .5*rho* sigma1*gammaV.*(gammaV-1).* V(1:paths).^(gammaV-2).* X(1:paths).^(gammaX).* ...
    sigma0^2.*V(1:paths).^(2*gamma).*Random2(1:paths) * 1/sqrt(3).* dt^1.5+ ...
    rho* sigma1*gammaV.* V(1:paths).^(gammaV-1).*gammaX.* X(1:paths).^(gammaX-1).* ...
    rho.* sigma1.* V(1:paths).^gammaV .*X(1:paths).^gammaX .*sigma0.*V(1:paths).^gamma.*Random2(1:paths)*1/sqrt(3)*dt^1.5;
    

    V(1:paths)=V(1:paths)+ ...
        (mu1.*V(1:paths).^beta1 + mu2.*V(1:paths).^beta2)*dt + ...
        sigma0*V(1:paths).^gamma .*Random2(1:paths)*sqrt(dt) + ...
        (mu1.*beta1*V(1:paths).^(beta1-1) + mu2.*beta2.*V(1:paths).^(beta2-1)).* ...
        ((mu1.*V(1:paths).^beta1 + mu2.*V(1:paths).^beta2)*dt^2/2 + ...
        sigma0*V(1:paths).^gamma .*Random2(1:paths)*(1-1/sqrt(3))*dt^1.5) + ...
        .5*(mu1.*beta1.*(beta1-1).*V(1:paths).^(beta1-2) + mu2.*beta2.*(beta2-1).*V(1:paths).^(beta2-2)).* ...    
        sigma0^2.*V(1:paths).^(2*gamma).*dt^2/2 + ...
        sigma0*gamma*V(1:paths).^(gamma-1) .* ...
        ((mu1.*V(1:paths).^beta1 + mu2.*V(1:paths).^beta2).*Random2(1:paths).*1/sqrt(3)*dt^1.5 + ...
        sigma0.*V(1:paths).^gamma .*(Random2(1:paths).^2-1)*dt/2) + ...
        .5*sigma0*gamma*(gamma-1).*V(1:paths).^(gamma-2) .* ...
        sigma0^2.*V(1:paths).^(2*gamma) .*Random2(1:paths).*1/sqrt(3)*dt^1.5;


end
% X1=X;
% V1=V;
% 

% 
 X(X<0)=0;
 V(V<0)=0;
 X=real(X);
 V=real(V);

save('MCData1.mat','X','V');


% str=input("Monte carlo data has been saved");


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
%load("MCData1.mat","X","V");

%str=input("File has been loaded");


CallStrikes=[.5,.55,.6,.65,.7,.75,.8,.85,.9,.95,1,1.05,1.1,1.15,1.2,1.25,1.3,1.35,1.4,1.45,1.5,1.55,1.6,1.65,1.7,1.75];
NoOfCallStrikes=length(CallStrikes);

CallPricesMC(1:NoOfCallStrikes)=0;
for nn=1:NoOfCallStrikes
    for pp=1:paths
        if(X(pp)>CallStrikes(nn))
            CallPricesMC(nn)=CallPricesMC(nn)+(X(pp)-CallStrikes(nn))/paths;
        end
    end
end


% CallPricesMC
% 
% str=input("Look at Call prices");

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%In this code block, we calculate and draw numerically calculated
%2D bivariate density of X and V.


NoOfBinsV=120;
NoOfBinsX=120;
MaxCutOffX=8.5;
MaxCutOffV=8.825;


[XYProbDensity2D,Xn,Vm,BinSizeX,BinSizeV] = Find2DDensitFromSimulation_Infiniti(X,V,paths,NoOfBinsX,NoOfBinsV,MaxCutOffX,MaxCutOffV);
                                                                                                                                                            
%Above, we calculate the joint bivariate density of X and V numerically
%from simulated values of X and V. We do this calculation only for comparison
%purposes with analytic 2D bivariate density of X and V.


surf(Xn(2:NoOfBinsX+1),Vm(3:NoOfBinsV+1),transpose(XYProbDensity2D(2:NoOfBinsX+1,3:NoOfBinsV+1)))
title(sprintf('Numerical Density : x0 = %.4f,gammaX=%.3f,sigmaX=%.2f,rho=%.2f,gammaV=%.3f,v0=%.3f,kappaV=%.3f,thetaV=%.3f,gamma=%.3f,sigma0=%.3f,T=%.2f', X0,gammaX,sigma1,rho,gammaV,V0,kappaV,thetaV,gamma,sigma0,T));%,sprintf('theta= %f', theta), sprintf('kappa = %f', kappa),sprintf('sigma = %f', sigma0),sprintf('T = %f', T));
xlabel('Asset'), ylabel('Stochastic Volatility'),zlabel('Bivariate Density of Asset and Volatility')

str=input("Look at numerical bivariate density of Asset and Stochastic Volatility")



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
%In this block, we calculate the 2D conditional Z-series density of dependent 
%variable X given by coefficients 2D array bnm and 1D univariate Z-series density with
%coefficients stored in aa.
%We draw a graph of this analytic density and calculate the difference with
%numerical density.

[bnm,aa] = CalculateConditionalProbabilitiesYtoXLinearRegression04IterB(V,X);

[pXY2D] = Calculate2VariablesOn2DGridFromAnalyticZSeriesA(Xn,Vm,NoOfBinsX,NoOfBinsV,bnm,aa);

surf(Xn(2:NoOfBinsX+1),Vm(3:NoOfBinsV+1),transpose(pXY2D(2:NoOfBinsX+1,3:NoOfBinsV+1)))
title(sprintf('Analytic Density : x0 = %.4f,gammaX=%.3f,sigmaX=%.2f,rho=%.2f,gammaV=%.3f,v0=%.3f,kappaV=%.3f,thetaV=%.3f,gamma=%.3f,sigma0=%.3f,T=%.2f', X0,gammaX,sigma1,rho,gammaV,V0,kappaV,thetaV,gamma,sigma0,T));%,sprintf('theta= %f', theta), sprintf('kappa = %f', kappa),sprintf('sigma = %f', sigma0),sprintf('T = %f', T));
xlabel('Asset'), ylabel('Stochastic Volatility'),zlabel('Bivariate Density of Asset and stochastic Volatility')



str=input("Look at Analytic density of Asset and Stochastic volatility")
%str=input("Look at Analytic density of Asset and Stochastic volatility")
surf(Xn(2:NoOfBinsX+1),Vm(3:NoOfBinsV+1),transpose(pXY2D(2:NoOfBinsX+1,3:NoOfBinsV+1)-XYProbDensity2D(2:NoOfBinsX+1,3:NoOfBinsV+1)))
%title(sprintf('Difference of Analytic and Numerical Density  : x0 = %.4f,gammaX=%.3f,sigmaX=%.2f,gammaV=%.3f,v0=%.3f,kappaV=%.3f,thetaV=%.3f,gamma=%.3f,sigma0=%.3f,T=%.2f', X0,gammaX,sigma1,gammaV,V0,kappaV,thetaV,gamma,sigma0,T));%,sprintf('theta= %f', theta), sprintf('kappa = %f', kappa),sprintf('sigma = %f', sigma0),sprintf('T = %f', T));
xlabel('Asset'), ylabel('Stochastic Volatility'),zlabel('Bivariate Density of Asset and stochastic Volatility')

str=input("Look at difference of numerical and analytic densities of Asset and stochastic volatility")



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%In this last block, we use previously calculated values of 2D Z-series
%coefficients of dependent variable X stored in 2D array bnm and Z-series
%univariate density of V to calculate the option prices. We compare
%analytically calculated option prices with monte carlo option prices.
%Purpose again is to find out how good our calculation of 2D conditional
%Z-series density of dependent variable X is.


CallStrikes=[.5,.55,.6,.65,.7,.75,.8,.85,.9,.95,1,1.05,1.1,1.15,1.2,1.25,1.3,1.35,1.4,1.45,1.5,1.55,1.6,1.65,1.7,1.75]

VolGridSize=400;


[CallPricesAnalytic]=PriceCallArrayOver2DDensityB(bnm,CallStrikes,VolGridSize);

%[CallPricesAnalytic]=PriceCallArrayOver2DDensityA(aa,bnm,CallStrikes,VolGridSize);

CallPricesAnalytic
CallPricesMC

str=input("Look at comparison of analytic and monte carlo call prices");

end
.
.
.
.
function [bnm,aa] = CalculateConditionalProbabilitiesYtoXLinearRegression04IterB(Yin,Xin)

%Yin argument translates to independent random variable Y
%Xin argument translates to dependent variable X.
%This function takes observations of an independent variable Y and
%dependent varaible X. These have to be joint observations in the sense
%that nth observation of Y, given by Y(n) is taken jointly with nth
%observation of X, given by X(n). Two arrays of observations are the same
%length and nth mmber of independent variable Y is jointly observed with nth
%member of depedent variable X.
%We want to find the detailed relationship between Y and X so we can get
%the conditional density of dependent variable X given a particular value
%of independent variable Y. This will be done by calibrating coefficients
%of our 2D hermite series to data so that a very good fit to cross moments
%between X and Y is retrieved.
%We will first find univariate Z-series/hermite series of both random
%variables independently. For joint dynamics of dependent variable given 
%te independnet variable, we will assume a 2D hermite series (This has to 
%be two dimensional to be able to capture the dynamics from independent variable Y
%and have its own dynamics) and form but we do not know the coefficients of 
%this 2D hermite series. In this program, we try to use iterative optimization 
%to find the unknown coefficients of 2D hermite series of dependent variable X 
%in a way that after taking products with independent varaible Y, expectation   
%of these products i.e cross moments are as exactly retrieved as possible.
%Our iterative optimization procedure perturbs each hermite coefficient in 
%2D hermite series  by a very slight amount and checks the objective function.
%If the objective function decreases, we eccept the perturbation otherwise
%reject it and then perturb by a small amount in other opposite direction
%and then again check the objective function. If perturbations in both sides 
%are rejected, we do not change the coefficients but slightly decrease the
%perturbation size. 
%We will first standardize the data of both random variables and then
%calculate univariate hermite series of both variables and also their 
%cross moments in standardized form. We do all the calculations of coefficients
%of independent variable Y and 2D dependent variable X
%in standardized version of variables and moments. After optimization of coefficents on 
%standardized data, at the end, we invert the standardization of both 
%dependent and independent variables appropriately to get the Z-series and
%hermite series of actual varaibles in theri original coordinates back from
%standardized coordinates.
%Before optimization, we place two conditions on 2D dependent variable X so that
%first row and first column of 2D hermite coefficents of X is already
%known before optimization stage and it is not changed in optimization. 
%We do not iteratively optimize over this first row and first colums
%which are analytically known from these two conditions.
%Our first condition is that after integration (of bivaraite density or
%alternatively bivaraite 2D Z-series/2D Hermite series) over independent
%variable, we should get the univaraite marginal density/Z-series/Hermite series of X
%which has already been calculated out of data. This fixes the zeroth
%hermite(of independent varaible Y) related terms in the Z-series/hermite series. 
%Please look at this forum post# 2121 for explanation of this first condition.
% https://forum.wilmott.com/viewtopic.php?t=99702&start=2115#p879042

%We can analytically solve for first order cross moments of X with higher
%order in Y. From the analytical solution of these moments, we find first
%row of coefficents in the hermite form.


% 2D Hermite Series Form used in this program is given as
% 
% X = bnmH(1,1) + bnmH(2,1) H_1(Z_y) + bnmH(3,1) H_2(Z_y) + bnmH(4,1) H_3(Z_y) + bnmH(5,1) H_4(Z_y) + bnmH(6,1) H_5(Z_y) 
% + [ bnmH(1,2) + bnmH(2,2) H_1(Z_y) + bnmH(3,2) H_2(Z_y) + bnmH(4,2) H_3(Z_y) + bnmH(5,2) H_4(Z_y) + bnmH(6,2) H_5(Z_y)] H_1(Zx) 
% + [ bnmH(1,3) + bnmH(2,3) H_1(Z_y) + bnmH(3,3) H_2(Z_y) + bnmH(4,3) H_3(Z_y) + bnmH(5,3) H_4(Z_y) + bnmH(6,3) H_5(Z_y)] H_2(Zx)
% + [ bnmH(1,4) + bnmH(2,4) H_1(Z_y) + bnmH(3,4) H_2(Z_y) + bnmH(4,4) H_3(Z_y) + bnmH(5,4) H_4(Z_y) + bnmH(6,4) H_5(Z_y)] H_3(Zx)
% + [ bnmH(1,5) + bnmH(2,5) H_1(Z_y) + bnmH(3,5) H_2(Z_y) + bnmH(4,5) H_3(Z_y) + bnmH(5,5) H_4(Z_y) + bnmH(6,5) H_5(Z_y)] H_4(Zx)
% + [ bnmH(1,6) + bnmH(2,6) H_1(Z_y) + bnmH(3,6) H_2(Z_y) + bnmH(4,6) H_3(Z_y) + bnmH(5,6) H_4(Z_y) + bnmH(6,6) H_5(Z_y)] H_5(Zx)
 
% 2D Z-Series Form used in this program is given as
% 
% X = bnm(1,1) + bnm(2,1) Z_y + bnm(3,1) (Z_y)^2 + bnm(4,1) (Z_y)^3 + bnm(5,1) (Z_y)^4 + bnm(6,1) (Z_y)^5 
% + [ bnm(1,2) + bnm(2,2) Z_y + bnm(3,2) (Z_y)^2 + bnm(4,2) (Z_y)^3 + bnm(5,2) (Z_y)^4 + bnm(6,2) (Z_y)^5 ] Zx 
% + [ bnm(1,3) + bnm(2,2) Z_y + bnm(3,3) (Z_y)^2 + bnm(4,3) (Z_y)^3 + bnm(5,3) (Z_y)^4 + bnm(6,3) (Z_y)^5 ] Zx^2 
% + [ bnm(1,4) + bnm(2,2) Z_y + bnm(3,4) (Z_y)^2 + bnm(4,4) (Z_y)^3 + bnm(5,4) (Z_y)^4 + bnm(6,4) (Z_y)^5 ] Zx^3 
% + [ bnm(1,5) + bnm(2,2) Z_y + bnm(3,5) (Z_y)^2 + bnm(4,5) (Z_y)^3 + bnm(5,5) (Z_y)^4 + bnm(6,5) (Z_y)^5 ] Zx^4 
% + [ bnm(1,6) + bnm(2,2) Z_y + bnm(3,6) (Z_y)^2 + bnm(4,6) (Z_y)^3 + bnm(5,6) (Z_y)^4 + bnm(6,6) (Z_y)^5 ] Zx^5




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%In the code block below, we standardize the independent variable Y and dependent variable X.
%We do all later calculations of various Z-series and cross moments in 
%standardized framework and then at the end of the program, we convert 
%the calculated coefficients of 2D hermite series/Z-series of dependent 
%variable X into original non-standardized framework.

 Ndata=length(Yin);
 
 MeanY=sum(Yin(1:Ndata))/Ndata;
 MeanX=sum(Xin(1:Ndata))/Ndata;
 
 Ym(1:Ndata)=Yin(1:Ndata)-MeanY;
 Xm(1:Ndata)=Xin(1:Ndata)-MeanX;
 
 
 
  
 
 
 
 
 
 
 
 
 
 
 YmVar=sum(Ym(1:Ndata).^2)/Ndata;
 XmVar=sum(Xm(1:Ndata).^2)/Ndata;
 
 Y(1:Ndata)=Ym(1:Ndata)/sqrt(YmVar);
 X(1:Ndata)=Xm(1:Ndata)/sqrt(XmVar);


 NMomentsY=6;
 NMomentsX=6;
     for nn=1:NMomentsY
        for mm=1:NMomentsX
            CrossMoments11(nn,mm)=0;
            for pp=1:Ndata
               CrossMoments11(nn,mm)=CrossMoments11(nn,mm)+Yin(pp).^nn.*Xin(pp).^mm/Ndata;
               %CrossMoments11(nn,mm)=CrossMoments11(nn,mm)+Y(pp).^nn.*X(pp).^mm/Ndata;
               %CrossMoments11(nn,mm)=CrossMoments11(nn,mm)+Ym(pp).^nn.*Xm(pp).^mm/Ndata;
            end
        end
     end
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Code block below uses polynomial regression to find univariate Z-series 
%coefficients of independent variable Y.
%To know more about polynomial regression read the following and associated
%posts:  https://forum.wilmott.com/viewtopic.php?t=99702&start=2010#p877143
 
%You can get the text file MomentMatchParams08.txt from the forum post below
%https://forum.wilmott.com/viewtopic.php?f=4&t=99702&start=2040#p877863

Mtable=readtable('C:\Users\Lenovo\Documents\MATLAB\MATLAB1\MomentMatchParams08.txt');

%ZI is moment matched grid along the normal density with number of grid
%points equal to data elements in Y given by Ndata. The grid is constructed
%so that probability mass in each grid cell is 1/Ndata so this matches the
%observation probability of Ndata data elements. Due to equal probability
%mass in each grid cell, we call it equiprobable grid.

[ZI] = MatchMomentParametersOfIdealZhalf04(Ndata,Mtable);

Ys=sort(Y);
Ymu(1:Ndata,1)=Ys(1:Ndata);

W(1:Ndata,1)=1;
W(1:Ndata,2)=ZI(1:Ndata);
W(1:Ndata,3)=ZI(1:Ndata).^2;
W(1:Ndata,4)=ZI(1:Ndata).^3;
W(1:Ndata,5)=ZI(1:Ndata).^4;
W(1:Ndata,6)=ZI(1:Ndata).^5;
% W(1:Ndata,7)=ZI(1:Ndata).^6;
% W(1:Ndata,8)=ZI(1:Ndata).^7;


coeff=inv(W'*W)*(W'*Ymu);

%Above, we get coefficients of univariate Z-series of independent
%variable Y by least square regression.


a0=coeff(1,1);
a(1:5)=coeff(2:6,1);

%Above, we assign zeroth power Z-series coefficient to a0 and rest of
%the coefficients to array a.
%This was older format but we might need it since many old functions are written 
%in this format.

%Below, we assign same Z-series coefficients to a single array. This is
%newer format that we want to use mostly.
aa(1:6)=coeff(1:6);


%uncomment these lines if you want to see shape of Z-series constructed
%density of Y. We had calculated coefficients of this Z-series by
%least square polynomial regression.
%PlotZSeriesDensity(a0,a,'r')
%str=input("Look at the density of volatility");
    
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5    
%In this code block, we calcualate the coefficients of univariate marginal
%density of dependent variable X again by least square polynomial
%regression as we did in previous block for independent variable Y.
    
Xs=sort(X);
Xmu(1:Ndata,1)=Xs(1:Ndata);

W(1:Ndata,1)=1;
W(1:Ndata,2)=ZI(1:Ndata);
W(1:Ndata,3)=ZI(1:Ndata).^2;
W(1:Ndata,4)=ZI(1:Ndata).^3;
W(1:Ndata,5)=ZI(1:Ndata).^4;
W(1:Ndata,6)=ZI(1:Ndata).^5;

coeff=inv(W'*W)*(W'*Xmu);

c0=coeff(1,1);
c(1:5)=coeff(2:6,1);

cc(1:6)=coeff(1:6,1);

[ccH] = ConvertZSeriesToHermiteSeriesNew(cc,5);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Zy= CalculateZgivenXAndZSeriesC5Improved(Y,a0,a);

[Xs,I]=sort(X);

Zys=Zy(I);

Zx=ZI;

Xmu(1:Ndata,1)=Xs(1:Ndata);


W=0;

W(1:Ndata,1)=1.0;
W(1:Ndata,2)=Zx(1:Ndata);
W(1:Ndata,3)=(Zx(1:Ndata).^2-1);
W(1:Ndata,4)=(Zx(1:Ndata).^3-3*Zx(1:Ndata));
W(1:Ndata,5)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3);
W(1:Ndata,6)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata));

W(1:Ndata,7)=1.*Zys(1:Ndata);
W(1:Ndata,8)=Zx(1:Ndata).*Zys(1:Ndata);
W(1:Ndata,9)=(Zx(1:Ndata).^2-1).*Zys(1:Ndata);
W(1:Ndata,10)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*Zys(1:Ndata);
W(1:Ndata,11)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*Zys(1:Ndata);
W(1:Ndata,12)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata)).*Zys(1:Ndata);

W(1:Ndata,13)=(Zys(1:Ndata).^2-1);
W(1:Ndata,14)=Zx(1:Ndata).*(Zys(1:Ndata).^2-1);
W(1:Ndata,15)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^2-1);
W(1:Ndata,16)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^2-1);
W(1:Ndata,17)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^2-1);
W(1:Ndata,18)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata)).*(Zys(1:Ndata).^2-1);

W(1:Ndata,19)=(Zys(1:Ndata).^3-3*Zy(1:Ndata));
W(1:Ndata,20)=Zx(1:Ndata).*(Zys(1:Ndata).^3-3*Zy(1:Ndata));
W(1:Ndata,21)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^3-3*Zy(1:Ndata));
W(1:Ndata,22)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^3-3*Zys(1:Ndata));
W(1:Ndata,23)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^3-3*Zys(1:Ndata));
W(1:Ndata,24)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata)).*(Zys(1:Ndata).^3-3*Zys(1:Ndata));

W(1:Ndata,25)=(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
W(1:Ndata,26)=Zx(1:Ndata).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
W(1:Ndata,27)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
W(1:Ndata,28)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
W(1:Ndata,29)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
W(1:Ndata,30)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata)).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);

W(1:Ndata,31)=(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
W(1:Ndata,32)=Zx(1:Ndata).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
W(1:Ndata,33)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
W(1:Ndata,34)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
W(1:Ndata,35)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
W(1:Ndata,36)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata)).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));

coeff=inv(W'*W)*(W'*Xmu);


bnmH0(1,1:6)=ccH(1:6);  %Replace first line of X-hermites with Marginal density retrieval condition
bnmH0(2,1:6)=coeff(7:12);
bnmH0(3,1:6)=coeff(13:18);
bnmH0(4,1:6)=coeff(19:24);
bnmH0(5,1:6)=coeff(25:30);
bnmH0(6,1:6)=coeff(31:36);

bnmH=bnmH0;





%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


SeriesOrder1=6;
NMomentsY=6;


SeriesOrder10=6; %SeriesOrder10 = 1 + highest power of Zy in 2D Z-series%Here highest power of Zy is five 
SeriesOrder01=6; %SeriesOrder01 = 1 + highest power of Zx in 2D Z-series%Here highest power of Zx is also five
%notation is  bnm(1:SeriesOrder10,1:SeriesOrder01)
%Similalry    bnmH(1:SeriesOrder10,1:SeriesOrder01)
 
NMomentsX=6; %Highest moment of X in cross moments of X and Y
NMomentsY=6; %Highest moment of Y in cross moments of X and Y

%Below we calculate various cross moments between X and Y. These are
%calculated from standardized data.
for nn=1:NMomentsY
   for mm=1:NMomentsX
       CrossMoments(nn,mm)=0;
       for pp=1:Ndata
          CrossMoments(nn,mm)=CrossMoments(nn,mm)+Y(pp).^nn.*X(pp).^mm/Ndata;
       end
   end
end
    
    
%Below are the weights on calculation of objective function. More weight on
%a particular moment means that its better match with target moments gets more emphasized as
%compared to match of other moments.
%Choice of good weights is non-trivial.
%Current choice is only haphazard. Please try improvements/
    
    
 w2D(1:NMomentsY,1:NMomentsX)=1;
for nn=NMomentsY-1:-1:1
    for mm=NMomentsX-1:-1:1
        w2D(nn,mm)=w2D(nn+1,mm+1)*(nn+1)*(mm+1);
    end
end

w2D(:,1)=w2D(:,1)*5000000;

w2D(:,2)=w2D(:,2)*500000;
w2D(1,2)=w2D(1,2)*100;
w2D(2,2)=w2D(2,2)*10;
w2D(3,2)=w2D(3,2)*5;
w2D(:,3)=w2D(:,3)*100000;
w2D(1,3)=w2D(1,3)*20;
w2D(2,3)=w2D(2,3)*5;
w2D(1,:)=w2D(1,:)*10000;
w2D(2,:)=w2D(2,:)*100;
w2D(3,:)=w2D(3,:)*10;
w2D(:,4)=w2D(:,4)*10000;
w2D(1,4)=w2D(1,4)*10;
w2D(2,4)=w2D(2,4)*2;
w2D(:,5)=w2D(:,5)*1000;    

%Please look on detailed comments inside function below for more insight about it.
%The function below returns coefficients on first row of hermite series so that all
%cross moments of first order in dependent variable X and various orders in independent
%variable Y are matched.

[ddH] = ProduceFirstRowofConditioal2DZSeries02_6M_A(aa,SeriesOrder1,CrossMoments);

%Below we define a 2D array of hermite series coefficents and populate its
%first row with output from above function so that all cross moments of
%first order in X and different orders in Y are matched.
%We also populate first column with univariate hermite coefficients of 
%marginal density of X because of the condition that upon integration of
%the bivariate hermite form, we should get univariate marginal density as a
%result. %Please look at this forum post# 2121 for explanation of this first condition.
% https://forum.wilmott.com/viewtopic.php?t=99702&start=2115#p879042

% 
% %%%%%%%%%%%%%%%%%%%%%%%%%5
% 
ccH0=ccH;

for nn=2:6
    %ccH(nn)=sign(ccH(nn)-dd(nn)).*sqrt(abs(sign(ccH(nn)).*ccH(nn).^2-sign(dd(nn)).*dd(nn).^2));
    if(abs(ccH(nn))>abs(ddH(nn)))
        ccH(nn)=sign(ccH(nn)).*sqrt(ccH(nn).^2-ddH(nn).^2);
    else
    
        ccH(nn)=0;
    end 
end

% %[ccH1] = SubtractZSeriesRVsByMonteCarlo(ccH0,ddH);
% 
% %[ccH2] = SubtractDensity(ccH0,ddH)
% 
% 
% %ddH
% 
% %ccH0
% 
% ccH
% 
% %ccH1
% 
% %ccH2
% %str=input("Look at comparison of ccH");
% 
  bnmH(1,1:6)=ccH(1:6);     %populate first column with univariate margianl density hermite coefficients of X.
% % %bnmH(1,1)=MeanX;
  bnmH(1:6,1)=ddH(1:6);      %populate first row so that all cross moments of first order in X are matched.
% % % 
% %%%%%%%%%%%%%%%%%%%%%%%5

% [Zy] = CalculateZgivenXAndZSeriesC5Improved(Y,a0,a);
% [Zx] = CalculateZgivenXAndZSeriesC5Improved(X,c0,c);
% 
% paths=Ndata;
% [CorrH0] = CalculateCorrelationBivariateHermiteCH(Zx,Zy,paths,5);
% 
% bnmH(1,1)=ddH(1);
% bnmH(1,2)=sqrt(1-CorrH0(1).^2).*ccH(2);
% bnmH(1,3)=sqrt(1-CorrH0(2).^2).*ccH(3);
% bnmH(1,4)=sqrt(1-CorrH0(3).^2).*ccH(4);
% bnmH(1,5)=sqrt(1-CorrH0(4).^2).*ccH(5);
% bnmH(1,6)=sqrt(1-CorrH0(5).^2).*ccH(6);
% 
% bnmH(2,1)=CorrH0(1).*ccH(2);
% bnmH(3,1)=CorrH0(2).*ccH(3);
% bnmH(4,1)=CorrH0(3).*ccH(4);
% bnmH(5,1)=CorrH0(4).*ccH(5);
% bnmH(6,1)=CorrH0(5).*ccH(6);
% 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%In our iterative optimization, we will not alter the above first column and first row of 2D hermite coefficients array.


%In the block below, we convert 2D hermite coefficients array bnmH to 2D
%Z-series array bnm. We calculate the values of cross moments given the values of 
%coefficients in 2D Z-series bnm. We use these model cross moments and
%co1mpare them with target cross moments to evaluate the objective function.

%Convert from 2D Hermite Series Coefficients bnmH to 2D Z-series
%coefficients bnm
[bnm] = Convert2DHermitesInto2DSeries(bnmH);
%Evaluate the model cross moments in the function below.
[Moments2D,Moments1D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
%Evaluate the objective function based on weighted squared difference
%between model cross moments and target cross momensts from data.
[ObjFuncBest] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
    %%%%%%%%%%%%%%%%

SeriesOrderIter10=6;
SeriesOrderIter01=6;
alphaSuccessCount(1:SeriesOrderIter10,1:SeriesOrderIter01)=0;
SuccessPrevalpha(1:SeriesOrderIter10,1:SeriesOrderIter01)=0;


%array of perturbation sizes of coefficients of the 2D Hermite form 
%of dependent variable X in iterative optimization.
for nn=1:SeriesOrderIter10
    for mm=1:SeriesOrderIter01
        if(bnmH(nn,mm)~=0)
            delta_bnmHCoeff(nn,mm)=bnmH(nn,mm)./50;
        else
            delta_bnmHCoeff(nn,mm)=.00001;
        end
    end    
end

%Assign initial value of bnmH to workhorse variable bnmHCoeff which will be
%used in iterative ioptimization
bnmHCoeff=bnmH;

mul1=.9; %decrease the perturbation step size by multiplying it with .9 when 
%objective function does not decrease upon perturbation on both sides.  
mul2=1.1; %Increase the perturbation step size after several successive 
%successes in decreasing the objective function
Iterations=5000;
MM1=2;
NN1=2;
MM2=2
NN2=2;
for iter=1:Iterations
iter
bnmHCoeff
ObjFuncBest

%Below we run a two dimensional loop that loops over all rows and columns
%of 2D array of hermite series coefficients. However, we exclude first row
%and first column from this optimization as values there were already fixed
%analytically.


    for kk=NN1:MM1 %SeriesOrderIter10 %Optimize over Zy hermites.
        for jj=NN2:MM2 %Optimize over Zx hermites
            if(iter>500)
                NN1=2;
                MM1=3;
                NN2=2;
                MM2=SeriesOrderIter01;
            end
            if(iter>1000)
                NN1=2;
                MM2=SeriesOrderIter10;
                NN2=2;
                MM2=3;
                
            end
            if(iter>1500)
                NN1=2;
                MM1=4;
                NN2=2;
                MM2=SeriesOrderIter01;
            end
            if(iter>2000)
                NN1=2;
                MM1=SeriesOrderIter10;
                NN2=2;
                MM2=4;
            end
            if(iter>2500)
                NN1=2;
                MM1=5;
                NN2=2;
                MM2=SeriesOrderIter01;
            end
            
            if(iter>3000)
                NN1=2;
                MM1=SeriesOrderIter01;
                NN2=2;
                MM2=6;
            end
        
            if(iter>3500)
                NN1=2;
                MM1=SeriesOrderIter01;
                NN2=1;
                MM2=6;
            end
            if(iter>4000)
                NN1=1;
                MM1=SeriesOrderIter01;
                NN2=1;
                MM2=6;
            end
%     for kk=2:SeriesOrderIter10 %Optimize over Zy hermites.
%         for jj=2:SeriesOrderIter01 %Optimize over Zx hermites
        
        
            %Assign 2D hermite coefficients to workhorse variable
            bnmHCoeffNew(1:SeriesOrderIter10,1:SeriesOrderIter01)=bnmHCoeff(1:SeriesOrderIter10,1:SeriesOrderIter01);
            %perturb the (kk,jj) coefficient by magnitude given in its
            %delta array named delta_bnmHCoeff(kk,jj)
            bnmHCoeffNew(kk,jj)=bnmHCoeff(kk,jj)+delta_bnmHCoeff(kk,jj);
            %convert to Z-series to calculate the cross moments
            [bnm] = Convert2DHermitesInto2DSeries(bnmHCoeffNew);
            [Moments2D,Moments1D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
            %Calculate the objective function value.
            [ObjFuncNew] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
        

            if(ObjFuncNew<ObjFuncBest) %If objective function decreases, accept the perturbation 
                %and change it in orginal coefficients array
                bnmHCoeff=bnmHCoeffNew;
                %update objective function
                ObjFuncBest=ObjFuncNew;
                if(SuccessPrevalpha(kk,jj)==1)
                    alphaSuccessCount(kk,jj)=alphaSuccessCount(kk,jj)+1;
                end
                SuccessPrevalpha(kk,jj)=1;
            else %If perturbation in first side is not accepted, 
                 %do it again in opposite direction.
            
                bnmHCoeffNew(1:SeriesOrderIter10,1:SeriesOrderIter01)=bnmHCoeff(1:SeriesOrderIter10,1:SeriesOrderIter01);
           
                bnmHCoeffNew(kk,jj)=bnmHCoeff(kk,jj)-delta_bnmHCoeff(kk,jj);
                        
                [bnm] = Convert2DHermitesInto2DSeries(bnmHCoeffNew);

                [Moments2D,Moments1D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);

                [ObjFuncNew] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
                if(ObjFuncNew<ObjFuncBest)
                    bnmHCoeff=bnmHCoeffNew;
                    ObjFuncBest=ObjFuncNew;
                    if(SuccessPrevalpha(kk,jj)==1)
                        alphaSuccessCount(kk,jj)=alphaSuccessCount(kk,jj)+1;
                    end
                    SuccessPrevalpha(kk,jj)=1;
                else
                    SuccessPrevalpha(kk,jj)=0;
                    alphaSuccessCount(kk,jj)=0;
                    delta_bnmHCoeff(kk,jj)=delta_bnmHCoeff(kk,jj)*mul1;
                end
            end
        
        end
    end

    for kk=2:SeriesOrderIter10
        for jj=2:SeriesOrderIter01
            if(alphaSuccessCount(kk,jj)>3) %After successive successes, increase the perturbation step size.
                delta_bnmHCoeff(kk,jj)=delta_bnmHCoeff(kk,jj).*mul2;
            end
        end
    end
   if(rem(iter,500)==0)
         bnm
         Moments2D
         CrossMoments
         Moments2D(:,1)
         CrossMoments(:,1)
         
         ObjFuncBest
         
         str=input("Look at fit of moments");
         
      end
   
end

bnmH=bnmHCoeff;



%save("bnmHFile.mat","bnmH");
%load("bnmHFile.mat","bnmH");

%str=input("File has been loaded");



% W=0;
% 
% % W(1:Ndata,1)=1.0;
% % W(1:Ndata,2)=Zx(1:Ndata);
% % W(1:Ndata,3)=(Zx(1:Ndata).^2-1);
% % W(1:Ndata,4)=(Zx(1:Ndata).^3-3*Zx(1:Ndata));
% % W(1:Ndata,5)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3);
% % W(1:Ndata,6)=(Zx(1:Ndata).^5-10*Zx(1:Ndata)+15*Zx(1:Ndata));
% 
% W(1:Ndata,1)=1.*Zys(1:Ndata);
% W(1:Ndata,2)=Zx(1:Ndata).*Zys(1:Ndata);
% W(1:Ndata,3)=(Zx(1:Ndata).^2-1).*Zys(1:Ndata);
% W(1:Ndata,4)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*Zys(1:Ndata);
% W(1:Ndata,5)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*Zys(1:Ndata);
% W(1:Ndata,6)=(Zx(1:Ndata).^5-10*Zx(1:Ndata)+15*Zx(1:Ndata)).*Zys(1:Ndata);
% 
% W(1:Ndata,7)=(Zys(1:Ndata).^2-1);
% W(1:Ndata,8)=Zx(1:Ndata).*(Zys(1:Ndata).^2-1);
% W(1:Ndata,9)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^2-1);
% W(1:Ndata,10)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^2-1);
% W(1:Ndata,11)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^2-1);
% W(1:Ndata,12)=(Zx(1:Ndata).^5-10*Zx(1:Ndata)+15*Zx(1:Ndata)).*(Zys(1:Ndata).^2-1);
% 
% W(1:Ndata,13)=(Zys(1:Ndata).^3-3*Zy(1:Ndata));
% W(1:Ndata,14)=Zx(1:Ndata).*(Zys(1:Ndata).^3-3*Zy(1:Ndata));
% W(1:Ndata,15)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^3-3*Zy(1:Ndata));
% W(1:Ndata,16)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^3-3*Zys(1:Ndata));
% W(1:Ndata,17)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^3-3*Zys(1:Ndata));
% W(1:Ndata,18)=(Zx(1:Ndata).^5-10*Zx(1:Ndata )+15*Zx(1:Ndata)).*(Zys(1:Ndata).^3-3*Zys(1:Ndata));
% 
% W(1:Ndata,19)=(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
% W(1:Ndata,20)=Zx(1:Ndata).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
% W(1:Ndata,21)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
% W(1:Ndata,22)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
% W(1:Ndata,23)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
% W(1:Ndata,24)=(Zx(1:Ndata).^5-10*Zx(1:Ndata)+15*Zx(1:Ndata)).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
% 
% W(1:Ndata,25)=(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
% 
% W(1:Ndata,27)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
% W(1:Ndata,28)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
% W(1:Ndata,29)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
% W(1:Ndata,30)=(Zx(1:Ndata).^5-10
% 
% 
% bnmH=bnmH0;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SeriesOrder1=6;
NMomentsY=6;
NMomentsX=6;
    for nn=1:NMomentsY
       for mm=1:NMomentsX
           CrossMoments(nn,mm)=0;
           for pp=1:Ndata
              CrossMoments(nn,mm)=CrossMoments(nn,mm)+Y(pp).^nn.*X(pp).^mm/Ndata;
           end
       end
    end



[chh] = ProduceFirstRowofConditioal2DZSeries02_6M_A(aa,SeriesOrder1,CrossMoments);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[bnm] = Convert2DHermitesInto2DSeries(bnmH);

SeriesOrder1=6;
SeriesOrder10=6;
SeriesOrder01=6;
NMomentsX=6;
NMomentsY=6;
[Moments2D0] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);

Moments2D0

CrossMoments

str=input("Look at comparison of moments--first-standardized");

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%In the code block below, we convert 2D hermite series coefficients of 
%dependent variable X from standardized version to original version.
%For that we first multiply the entire 2D Hermite series by square root of
%variance.
%Later we multiply each column of hermite series of X with particular 
%order of Zy hermite polynomials by square root of volatility(independent variable)
%raised to that power of Zy polynomial order as below.
%bnmH=bnmH.*sqrt(XmVar);
%bnmH(:,1)=bnmH(:,1)*sqrt(XmVar);
%for nn=2:6
%    bnmH(nn,:)=bnmH(nn,:).*(sqrt(YmVar)).^(nn-1);
%end

 bnmH=bnmH*sqrt(XmVar);
% for nn=2:6
%     bnmH(nn,:)=bnmH(nn,:).*(sqrt(YmVar)).^(nn-1);
% end
% for nn=2:6
%     bnmH(:,nn)=bnmH(:,nn).*(sqrt(XmVar)).^(nn-1);
% end

%We convert X from hermite series form to Z-series form.
[bnm] = Convert2DHermitesInto2DSeries(bnmH);
bnm(1,1)=MeanX-bnm(3,1)-3*bnm(5,1)-1*bnm(1,3)-1*3*bnm(1,5)-3*bnm(5,3)-bnm(3,3)-3*bnm(3,5)-9*bnm(5,5);

%Finally in above line, we make sure that mean of the 2D Z-series is


%Below, we convert Z-series of independent variable Y from standard form to
%original variable form.

aa=aa*sqrt(YmVar);
aa(1)=MeanY-aa(3)-3*aa(5);


 SeriesOrder1=6;
 SeriesOrder10=6;
 SeriesOrder01=6;
 NMomentsX=6;
 NMomentsY=6;
 [Moments2D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
 
 Moments2D
 
 CrossMoments11
 
 str=input("Look at comparison of moments");
% 
% 
% for nn=1:NMomentsX
%     for mm=1:NMomentsY
%         
%         Moments2D(mm,nn)
%         Moments2D0(mm,nn).*(sqrt(YmVar)).^(mm).*(sqrt(XmVar)).^(nn)
%         Moments2D0(mm,nn)./(sqrt(YmVar)).^(mm)./(sqrt(XmVar)).^(nn)
%         Moments2D(mm,nn)./(sqrt(YmVar)).^(mm)./(sqrt(XmVar)).^(nn)
%         nn
%         mm
%         str=input("Look at moments again---22---22-222---")
%     end
% end
        




end
.
.
.
function [pXY2D] = Calculate2VariablesOn2DGridFromAnalyticZSeriesB(XX,YY,NoOfBinsX,NoOfBinsY,bnm,aa)


%YY are Y-coordinates of 2D Grid. In our case this is stochastic
%volatility and is univariate and independent of asset so it can be
%inverted as a univariate Z-series. its Z-series is given by a0 and a.

a0=aa(1);
a(1:length(aa)-1)=aa(2:length(aa));
[Zy] = CalculateZgivenXAndZSeriesC5Improved(YY,a0,a);


for indexY=1:NoOfBinsY+1
    b0=bnm(1,1)+bnm(2,1).*Zy(indexY)+bnm(3,1).*Zy(indexY).^2+bnm(4,1).*Zy(indexY).^3+bnm(5,1).*Zy(indexY).^4+bnm(6,1).*Zy(indexY).^5;
    for mm=2:6
        b(mm-1)=bnm(1,mm)+bnm(2,mm).*Zy(indexY)+bnm(3,mm).*Zy(indexY).^2+bnm(4,mm).*Zy(indexY).^3+bnm(5,mm).*Zy(indexY).^4+bnm(6,mm).*Zy(indexY).^5;
    end   
    
    [Zx0] = CalculateZgivenXAndZSeriesC5Improved(XX,b0,b);
    Zx(1:NoOfBinsX+1,indexY)=Zx0(1:NoOfBinsX+1);
    % Zx0
    % XX
    % indexY
    % str=input("Look at Zxx(indexY)")       
end

dbnm(1:5,1:5)=0;

for nn=1:6
    for mm=1:5
        dbnm(nn,mm)=mm.*bnm(nn,mm+1);
    end
end

EZZ=EZZ2();
dXdZx(1:indexY,1:NoOfBinsX+1)=0;
for nn=1:indexY
    for mm=1:NoOfBinsX+1
        for nn1=1:6
            for mm1=1:5
        dXdZx(nn,mm)=dXdZx(nn,mm)+dbnm(nn1,mm1).*Zy(nn).^(nn1-1).*Zx(mm,nn).^(mm1-1);
            end
        end
        
    end
end




%Below we make calculations of density in original coordinates by doing 
%change of probability derivative with respect to gaussian density.
DinvfXX(1:NoOfBinsX+1,1:NoOfBinsY+1)=0;
for mm=1:NoOfBinsY
    %DinvfXX(1,mm)= (Zx(1 + 1,mm) - Zx(1,mm))/(XX(1 + 1) - XX(1));
    for nn=2:NoOfBinsX
    
        DinvfXX(nn,mm) = (Zx(nn + 1,mm) - Zx(nn - 1,mm))/(XX(nn + 1) - XX(nn - 1));
    
    end
    %DinvfXX(nn,mm) = (Zx(nn + 1,mm) - Zx(nn - 1,mm))/(XX(nn + 1) - XX(nn - 1));
    DinvfXX(NoOfBinsX+1,mm)=DinvfXX(NoOfBinsX,mm);
    DinvfXX(1,mm)=DinvfXX(2,mm);
end




DinvfYY(1:NoOfBinsY+1)=0;
%DinvfYY(1) = (Zy(1+1) - Zy(1))/(YY(1 + 1) - YY(1));
for mm=2:NoOfBinsY
    
        DinvfYY(mm) = (Zy(mm+1) - Zy(mm-1))/(YY(mm + 1) - YY(mm - 1));
    
end
DinvfYY(NoOfBinsY+1)=DinvfYY(NoOfBinsY);
DinvfYY(1)=DinvfYY(2);


pXY2D(1:NoOfBinsX+1,1:NoOfBinsY+1)=0;
for mm=1:NoOfBinsY
    for nn=1:NoOfBinsX
    
    %pXY2D(nn,mm) = (normpdf(Zx(nn,mm),0, 1))*abs(DinvfXX(nn,mm)).*(normpdf(Zy(mm),0, 1))*abs(DinvfYY(mm));
    pXY2D(nn,mm) = (normpdf(Zx(nn,mm),0, 1))./abs(dXdZx(mm,nn)).*(normpdf(Zy(mm),0, 1))*abs(DinvfYY(mm));
 
    end
end


end

.
.
.
function [CallPrices]=PriceCallArrayOver2DDensityB(bnm,CallStrikes,VolGridSize)

NoOfCallStrikes=length(CallStrikes);

Nn=VolGridSize;  % No of normal density subdivisions
dNn=(8)/Nn;
NnMid=((1+Nn)/2)*dNn;
Zv(1:Nn)=(((1:Nn)*dNn)-NnMid);
ZProb(1)=normcdf(.5*Zv(1)+.5*Zv(2),0,1)-normcdf(.5*Zv(1)+.5*Zv(2)-dNn,0,1);
ZProb(Nn)=normcdf(.5*Zv(Nn)+.5*Zv(Nn-1)+dNn,0,1)-normcdf(.5*Zv(Nn)+.5*Zv(Nn-1),0,1);
ZProb(2:Nn-1)=normcdf(.5*Zv(2:Nn-1)+.5*Zv(3:Nn),0,1)-normcdf(.5*Zv(2:Nn-1)+.5*Zv(1:Nn-2),0,1);



Mm=VolGridSize;  % No of normal density subdivisions
dMm=(8)/Mm;
MmMid=((1+Mm)/2)*dMm;
Zx(1:Mm)=(((1:Mm)*dMm)-MmMid);
ZxProb(1)=normcdf(.5*Zx(1)+.5*Zx(2),0,1)-normcdf(.5*Zx(1)+.5*Zx(2)-dMm,0,1);
ZxProb(Mm)=normcdf(.5*Zx(Mm)+.5*Zx(Mm-1)+dMm,0,1)-normcdf(.5*Zx(Mm)+.5*Zx(Mm-1),0,1);
ZxProb(2:Mm-1)=normcdf(.5*Zx(2:Mm-1)+.5*Zx(3:Mm),0,1)-normcdf(.5*Zx(2:Mm-1)+.5*Zx(1:Mm-2),0,1);

CallPrices(1:NoOfCallStrikes)=0;
for nn=1:Nn
    for mm=1:Mm
        X=0;
        for nn1=1:6
            for mm1=1:6
                X=X+bnm(nn1,mm1).*Zv(nn).^(nn1-1).*Zx(mm).^(mm1-1);
            end
        end
        for qq=1:NoOfCallStrikes
            if(X>CallStrikes(qq))
                CallPrices(qq)=CallPrices(qq)+(X-CallStrikes(qq)).*ZProb(nn).*ZxProb(mm);
            end
        end
    end
end


end

.
.
.
function [pXY2D] = Calculate2VariablesOn2DGridFromAnalyticZSeriesA(XX,YY,NoOfBinsX,NoOfBinsY,bnm,aa)


%YY are Y-coordinates of 2D Grid. In our case this is stochastic
%volatility and is univariate and independent of asset so it can be
%inverted as a univariate Z-series. its Z-series is given by a0 and a.

a0=aa(1);
a(1:length(aa)-1)=aa(2:length(aa));
[Zy] = CalculateZgivenXAndZSeriesC5Improved(YY,a0,a);


for indexY=1:NoOfBinsY+1
    b0=bnm(1,1)+bnm(2,1).*Zy(indexY)+bnm(3,1).*Zy(indexY).^2+bnm(4,1).*Zy(indexY).^3+bnm(5,1).*Zy(indexY).^4+bnm(6,1).*Zy(indexY).^5;
    for mm=2:6
        b(mm-1)=bnm(1,mm)+bnm(2,mm).*Zy(indexY)+bnm(3,mm).*Zy(indexY).^2+bnm(4,mm).*Zy(indexY).^3+bnm(5,mm).*Zy(indexY).^4+bnm(6,mm).*Zy(indexY).^5;
    end   
    [Zx0] = CalculateZgivenXAndZSeriesC5Improved(XX,b0,b);
    Zx(1:NoOfBinsX+1,indexY)=Zx0(1:NoOfBinsX+1);
    % Zx0
    % XX
    % indexY
    % str=input("Look at Zxx(indexY)")       
end

%Below we make calculations of density in original coordinates by doing 
%change of probability derivative with respect to gaussian density.
DinvfXX(1:NoOfBinsX+1,1:NoOfBinsY+1)=0;
for mm=1:NoOfBinsY
    %DinvfXX(1,mm)= (Zx(1 + 1,mm) - Zx(1,mm))/(XX(1 + 1) - XX(1));
    for nn=2:NoOfBinsX
    
        DinvfXX(nn,mm) = (Zx(nn + 1,mm) - Zx(nn - 1,mm))/(XX(nn + 1) - XX(nn - 1));
    
    end
    %DinvfXX(nn,mm) = (Zx(nn + 1,mm) - Zx(nn - 1,mm))/(XX(nn + 1) - XX(nn - 1));
    DinvfXX(NoOfBinsX+1,mm)=DinvfXX(NoOfBinsX,mm);
    DinvfXX(1,mm)=DinvfXX(2,mm);
end




DinvfYY(1:NoOfBinsY+1)=0;
%DinvfYY(1) = (Zy(1+1) - Zy(1))/(YY(1 + 1) - YY(1));
for mm=2:NoOfBinsY
    
        DinvfYY(mm) = (Zy(mm+1) - Zy(mm-1))/(YY(mm + 1) - YY(mm - 1));
    
end
DinvfYY(NoOfBinsY+1)=DinvfYY(NoOfBinsY);
DinvfYY(1)=DinvfYY(2);


pXY2D(1:NoOfBinsX+1,1:NoOfBinsY+1)=0;
for mm=1:NoOfBinsY
    for nn=1:NoOfBinsX
    
    pXY2D(nn,mm) = (normpdf(Zx(nn,mm),0, 1))*abs(DinvfXX(nn,mm)).*(normpdf(Zy(mm),0, 1))*abs(DinvfYY(mm));
 
    end
end


end

You think life is a secret, Life is only love of flying, It has seen many ups and downs, But it likes travel more than the destination. Allama Iqbal
 
User avatar
Amin
Topic Author
Posts: 2586
Joined: July 14th, 2002, 3:00 am

Re: Breakthrough in the theory of stochastic differential equations and their simulation

February 18th, 2024, 12:43 pm

Friends, I noticed that after I removed the error in previous program, the graphs became less robust and there were all sorts of spikes and instabilities. I have been working to fix that. I have had enough success. But more work needs to be done. I am showing some graphs from both totally non-correlated SV model and with corr=-.7 for one year. These were quite challenging as I initially thought. 
I made improvements to iterative optimization. I also improved the objective function(that is minimized) weights in the program. It works far better now than yesterday's program and I will make a few more changes to it. I will be posting these new programs later tonight.

Here are some graph comparisons(Second graph was too beautiful so I took some extra views of analytic 2nd graph).

Image

Image

Image

Image

Image

Image

Image

Image
You think life is a secret, Life is only love of flying, It has seen many ups and downs, But it likes travel more than the destination. Allama Iqbal
 
User avatar
Amin
Topic Author
Posts: 2586
Joined: July 14th, 2002, 3:00 am

Re: Breakthrough in the theory of stochastic differential equations and their simulation

February 19th, 2024, 1:04 pm

Friends, I am posting a very preliminary version of the main function that optimizes. It has several errors. For many idisosyncratic cases, parameters, loops count, loops order and many other things have to be tweaked. I still have not done the part that perfectly fixes the first column and first row and I am resorting to keeping that constant at ad-hoc calculated values and then running optimization there at the very end. This function will change in many ways but I am still posting it to keep friends in touch.
This is a different version of the function I used yesterday.
Summary of some major changes.

1. I keep objective function analytic.

Here is the objective function I used for graphs yesterday. w2D are weights for cross moments in squared difference of model and target cross moments.

w2D(1:NMomentsY,1:NMomentsX)=1;
for nn=NMomentsY-1 : -1 : 1
    for mm=NMomentsX-1 : -1 : 1
        w2D(nn,mm)=w2D(nn+1,mm+1)*(nn+1).^2*(mm+1).^2.0;
    end
end

Please feel free to use non-integer powers if you want to experiment but better to keep objective function in an analytic form.

2. I used a multiplicative iterative optimization in addition to additive iterative optimization that seems to work very well.

additive optimization is simply updated element-wise a single coefficient at a time as
bnmHCoeffNew(kk,jj)=bnmHCoeff(kk,jj)+delta_bnmHCoeff(kk,jj);

while  multiplicative optimization is multiplied to one entire column and one entire row at a time with weights proportional to their powers of standard deviations as
bnmHCoeffNew(kk,2:6)=bnmHCoeff(kk,2:6).*(1+delta_bnmHCoeff1(kk,2:6));

weights along rows are 
delta_bnmHCoeff1(1:SeriesOrderIter10,mm)=.005.*XmVar.^((mm)/2);
while weights along columns are
delta_bnmHCoeff2(nn,1:SeriesOrderIter01)=.005.*YmVar.^((nn)/2)

In yesterday's graphs, I did not use any multiplicative optimization. I simply used iterative optimization and in second last batch of 500 iterative optimizations, I allowed optimization of first column and in last batch of 500 iterated optimizations, I also allowed optimization of first column.

Mean during optimization cannot be changed from zero for since optimization is done on standardized data. This was not previously properly taken into account in optimization and was fixed at the end after optimization.

There are other small changes. One year and two year with the same parameters that I had in last matlab program can be priced well. I did not check three years and four years. Five years were not working and had problems but I am sure we will soon fix them.

Here is the latest program for reference and it will undergo many more changes in coming days. I am posting the appropriate function only that does optimization.

.
.
function [bnm,aa] = CalculateConditionalProbabilitiesYtoXLinearRegression04IterB(Yin,Xin)

%Yin argument translates to independent random variable Y
%Xin argument translates to dependent variable X.
%This function takes observations of an independent variable Y and
%dependent varaible X. These have to be joint observations in the sense
%that nth observation of Y, given by Y(n) is taken jointly with nth
%observation of X, given by X(n). Two arrays of observations are the same
%length and nth mmber of independent variable Y is jointly observed with nth
%member of depedent variable X.
%We want to find the detailed relationship between Y and X so we can get
%the conditional density of dependent variable X given a particular value
%of independent variable Y. This will be done by calibrating coefficients
%of our 2D hermite series to data so that a very good fit to cross moments
%between X and Y is retrieved.
%We will first find univariate Z-series/hermite series of both random
%variables independently. For joint dynamics of dependent variable given 
%te independnet variable, we will assume a 2D hermite series (This has to 
%be two dimensional to be able to capture the dynamics from independent variable Y
%and have its own dynamics) and form but we do not know the coefficients of 
%this 2D hermite series. In this program, we try to use iterative optimization 
%to find the unknown coefficients of 2D hermite series of dependent variable X 
%in a way that after taking products with independent varaible Y, expectation   
%of these products i.e cross moments are as exactly retrieved as possible.
%Our iterative optimization procedure perturbs each hermite coefficient in 
%2D hermite series  by a very slight amount and checks the objective function.
%If the objective function decreases, we eccept the perturbation otherwise
%reject it and then perturb by a small amount in other opposite direction
%and then again check the objective function. If perturbations in both sides 
%are rejected, we do not change the coefficients but slightly decrease the
%perturbation size. 
%We will first standardize the data of both random variables and then
%calculate univariate hermite series of both variables and also their 
%cross moments in standardized form. We do all the calculations of coefficients
%of independent variable Y and 2D dependent variable X
%in standardized version of variables and moments. After optimization of coefficents on 
%standardized data, at the end, we invert the standardization of both 
%dependent and independent variables appropriately to get the Z-series and
%hermite series of actual varaibles in theri original coordinates back from
%standardized coordinates.
%Before optimization, we place two conditions on 2D dependent variable X so that
%first row and first column of 2D hermite coefficents of X is already
%known before optimization stage and it is not changed in optimization. 
%We do not iteratively optimize over this first row and first colums
%which are analytically known from these two conditions.
%Our first condition is that after integration (of bivaraite density or
%alternatively bivaraite 2D Z-series/2D Hermite series) over independent
%variable, we should get the univaraite marginal density/Z-series/Hermite series of X
%which has already been calculated out of data. This fixes the zeroth
%hermite(of independent varaible Y) related terms in the Z-series/hermite series. 
%Please look at this forum post# 2121 for explanation of this first condition.
% https://forum.wilmott.com/viewtopic.php?t=99702&start=2115#p879042

%We can analytically solve for first order cross moments of X with higher
%order in Y. From the analytical solution of these moments, we find first
%row of coefficents in the hermite form.


% 2D Hermite Series Form used in this program is given as
% 
% X = bnmH(1,1) + bnmH(2,1) H_1(Z_y) + bnmH(3,1) H_2(Z_y) + bnmH(4,1) H_3(Z_y) + bnmH(5,1) H_4(Z_y) + bnmH(6,1) H_5(Z_y) 
% + [ bnmH(1,2) + bnmH(2,2) H_1(Z_y) + bnmH(3,2) H_2(Z_y) + bnmH(4,2) H_3(Z_y) + bnmH(5,2) H_4(Z_y) + bnmH(6,2) H_5(Z_y)] H_1(Zx) 
% + [ bnmH(1,3) + bnmH(2,3) H_1(Z_y) + bnmH(3,3) H_2(Z_y) + bnmH(4,3) H_3(Z_y) + bnmH(5,3) H_4(Z_y) + bnmH(6,3) H_5(Z_y)] H_2(Zx)
% + [ bnmH(1,4) + bnmH(2,4) H_1(Z_y) + bnmH(3,4) H_2(Z_y) + bnmH(4,4) H_3(Z_y) + bnmH(5,4) H_4(Z_y) + bnmH(6,4) H_5(Z_y)] H_3(Zx)
% + [ bnmH(1,5) + bnmH(2,5) H_1(Z_y) + bnmH(3,5) H_2(Z_y) + bnmH(4,5) H_3(Z_y) + bnmH(5,5) H_4(Z_y) + bnmH(6,5) H_5(Z_y)] H_4(Zx)
% + [ bnmH(1,6) + bnmH(2,6) H_1(Z_y) + bnmH(3,6) H_2(Z_y) + bnmH(4,6) H_3(Z_y) + bnmH(5,6) H_4(Z_y) + bnmH(6,6) H_5(Z_y)] H_5(Zx)
 
% 2D Z-Series Form used in this program is given as
% 
% X = bnm(1,1) + bnm(2,1) Z_y + bnm(3,1) (Z_y)^2 + bnm(4,1) (Z_y)^3 + bnm(5,1) (Z_y)^4 + bnm(6,1) (Z_y)^5 
% + [ bnm(1,2) + bnm(2,2) Z_y + bnm(3,2) (Z_y)^2 + bnm(4,2) (Z_y)^3 + bnm(5,2) (Z_y)^4 + bnm(6,2) (Z_y)^5 ] Zx 
% + [ bnm(1,3) + bnm(2,2) Z_y + bnm(3,3) (Z_y)^2 + bnm(4,3) (Z_y)^3 + bnm(5,3) (Z_y)^4 + bnm(6,3) (Z_y)^5 ] Zx^2 
% + [ bnm(1,4) + bnm(2,2) Z_y + bnm(3,4) (Z_y)^2 + bnm(4,4) (Z_y)^3 + bnm(5,4) (Z_y)^4 + bnm(6,4) (Z_y)^5 ] Zx^3 
% + [ bnm(1,5) + bnm(2,2) Z_y + bnm(3,5) (Z_y)^2 + bnm(4,5) (Z_y)^3 + bnm(5,5) (Z_y)^4 + bnm(6,5) (Z_y)^5 ] Zx^4 
% + [ bnm(1,6) + bnm(2,2) Z_y + bnm(3,6) (Z_y)^2 + bnm(4,6) (Z_y)^3 + bnm(5,6) (Z_y)^4 + bnm(6,6) (Z_y)^5 ] Zx^5




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%In the code block below, we standardize the independent variable Y and dependent variable X.
%We do all later calculations of various Z-series and cross moments in 
%standardized framework and then at the end of the program, we convert 
%the calculated coefficients of 2D hermite series/Z-series of dependent 
%variable X into original non-standardized framework.

 Ndata=length(Yin);
 
 MeanY=sum(Yin(1:Ndata))/Ndata;
 MeanX=sum(Xin(1:Ndata))/Ndata;
 
 Ym(1:Ndata)=Yin(1:Ndata)-MeanY;
 Xm(1:Ndata)=Xin(1:Ndata)-MeanX;
 
 YmVar=sum(Ym(1:Ndata).^2)/Ndata;
 XmVar=sum(Xm(1:Ndata).^2)/Ndata;
 
 Y(1:Ndata)=Ym(1:Ndata)/sqrt(YmVar);
 X(1:Ndata)=Xm(1:Ndata)/sqrt(XmVar);

 
 sqrt(YmVar)
 sqrt(XmVar)
 
 str=input("Look at standardization constants");
 

 NMomentsY=6;
 NMomentsX=6;
     for nn=1:NMomentsY
        for mm=1:NMomentsX
            CrossMoments11(nn,mm)=0;
            for pp=1:Ndata
               CrossMoments11(nn,mm)=CrossMoments11(nn,mm)+Yin(pp).^nn.*Xin(pp).^mm/Ndata;
               %CrossMoments11(nn,mm)=CrossMoments11(nn,mm)+Y(pp).^nn.*X(pp).^mm/Ndata;
               %CrossMoments11(nn,mm)=CrossMoments11(nn,mm)+Ym(pp).^nn.*Xm(pp).^mm/Ndata;
            end
        end
     end
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Code block below uses polynomial regression to find univariate Z-series 
%coefficients of independent variable Y.
%To know more about polynomial regression read the following and associated
%posts:  https://forum.wilmott.com/viewtopic.php?t=99702&start=2010#p877143
 
%You can get the text file MomentMatchParams08.txt from the forum post below
%https://forum.wilmott.com/viewtopic.php?f=4&t=99702&start=2040#p877863

Mtable=readtable('C:\Users\Lenovo\Documents\MATLAB\MATLAB1\MomentMatchParams08.txt');

%ZI is moment matched grid along the normal density with number of grid
%points equal to data elements in Y given by Ndata. The grid is constructed
%so that probability mass in each grid cell is 1/Ndata so this matches the
%observation probability of Ndata data elements. Due to equal probability
%mass in each grid cell, we call it equiprobable grid.

[ZI] = MatchMomentParametersOfIdealZhalf04(Ndata,Mtable);

Ys=sort(Y);
Ymu(1:Ndata,1)=Ys(1:Ndata);

W(1:Ndata,1)=1;
W(1:Ndata,2)=ZI(1:Ndata);
W(1:Ndata,3)=ZI(1:Ndata).^2;
W(1:Ndata,4)=ZI(1:Ndata).^3;
W(1:Ndata,5)=ZI(1:Ndata).^4;
W(1:Ndata,6)=ZI(1:Ndata).^5;
% W(1:Ndata,7)=ZI(1:Ndata).^6;
% W(1:Ndata,8)=ZI(1:Ndata).^7;


coeff=inv(W'*W)*(W'*Ymu);

%Above, we get coefficients of univariate Z-series of independent
%variable Y by least square regression.


a0=coeff(1,1);
a(1:5)=coeff(2:6,1);

%Above, we assign zeroth power Z-series coefficient to a0 and rest of
%the coefficients to array a.
%This was older format but we might need it since many old functions are written 
%in this format.

%Below, we assign same Z-series coefficients to a single array. This is
%newer format that we want to use mostly.
aa(1:6)=coeff(1:6);


%uncomment these lines if you want to see shape of Z-series constructed
%density of Y. We had calculated coefficients of this Z-series by
%least square polynomial regression.
%PlotZSeriesDensity(a0,a,'r')
%str=input("Look at the density of volatility");
    
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5    
%In this code block, we calcualate the coefficients of univariate marginal
%density of dependent variable X again by least square polynomial
%regression as we did in previous block for independent variable Y.
    
Xs=sort(X);
Xmu(1:Ndata,1)=Xs(1:Ndata);

W(1:Ndata,1)=1;
W(1:Ndata,2)=ZI(1:Ndata);
W(1:Ndata,3)=ZI(1:Ndata).^2;
W(1:Ndata,4)=ZI(1:Ndata).^3;
W(1:Ndata,5)=ZI(1:Ndata).^4;
W(1:Ndata,6)=ZI(1:Ndata).^5;

coeff=inv(W'*W)*(W'*Xmu);

c0=coeff(1,1);
c(1:5)=coeff(2:6,1);

cc(1:6)=coeff(1:6,1);

[ccH] = ConvertZSeriesToHermiteSeriesNew(cc,5);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Zy= CalculateZgivenXAndZSeriesC5Improved(Y,a0,a);

[Xs,I]=sort(X);

Zys=Zy(I);

Zx=ZI;

Xmu(1:Ndata,1)=Xs(1:Ndata);


W=0;

W(1:Ndata,1)=1.0;
W(1:Ndata,2)=Zx(1:Ndata);
W(1:Ndata,3)=(Zx(1:Ndata).^2-1);
W(1:Ndata,4)=(Zx(1:Ndata).^3-3*Zx(1:Ndata));
W(1:Ndata,5)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3);
W(1:Ndata,6)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata));

W(1:Ndata,7)=1.*Zys(1:Ndata);
W(1:Ndata,8)=Zx(1:Ndata).*Zys(1:Ndata);
W(1:Ndata,9)=(Zx(1:Ndata).^2-1).*Zys(1:Ndata);
W(1:Ndata,10)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*Zys(1:Ndata);
W(1:Ndata,11)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*Zys(1:Ndata);
W(1:Ndata,12)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata)).*Zys(1:Ndata);

W(1:Ndata,13)=(Zys(1:Ndata).^2-1);
W(1:Ndata,14)=Zx(1:Ndata).*(Zys(1:Ndata).^2-1);
W(1:Ndata,15)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^2-1);
W(1:Ndata,16)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^2-1);
W(1:Ndata,17)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^2-1);
W(1:Ndata,18)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata)).*(Zys(1:Ndata).^2-1);

W(1:Ndata,19)=(Zys(1:Ndata).^3-3*Zy(1:Ndata));
W(1:Ndata,20)=Zx(1:Ndata).*(Zys(1:Ndata).^3-3*Zy(1:Ndata));
W(1:Ndata,21)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^3-3*Zy(1:Ndata));
W(1:Ndata,22)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^3-3*Zys(1:Ndata));
W(1:Ndata,23)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^3-3*Zys(1:Ndata));
W(1:Ndata,24)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata)).*(Zys(1:Ndata).^3-3*Zys(1:Ndata));

W(1:Ndata,25)=(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
W(1:Ndata,26)=Zx(1:Ndata).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
W(1:Ndata,27)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
W(1:Ndata,28)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
W(1:Ndata,29)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
W(1:Ndata,30)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata)).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);

W(1:Ndata,31)=(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
W(1:Ndata,32)=Zx(1:Ndata).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
W(1:Ndata,33)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
W(1:Ndata,34)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
W(1:Ndata,35)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
W(1:Ndata,36)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata)).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));

coeff=inv(W'*W)*(W'*Xmu);


bnmH0(1,1:6)=ccH(1:6);  %Replace first line of X-hermites with Marginal density retrieval condition
bnmH0(2,1:6)=coeff(7:12);
bnmH0(3,1:6)=coeff(13:18);
bnmH0(4,1:6)=coeff(19:24);
bnmH0(5,1:6)=coeff(25:30);
bnmH0(6,1:6)=coeff(31:36);

bnmH=bnmH0;





%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


SeriesOrder1=6;
NMomentsY=6;


SeriesOrder10=6; %SeriesOrder10 = 1 + highest power of Zy in 2D Z-series%Here highest power of Zy is five 
SeriesOrder01=6; %SeriesOrder01 = 1 + highest power of Zx in 2D Z-series%Here highest power of Zx is also five
%notation is  bnm(1:SeriesOrder10,1:SeriesOrder01)
%Similalry    bnmH(1:SeriesOrder10,1:SeriesOrder01)
 
NMomentsX=6; %Highest moment of X in cross moments of X and Y
NMomentsY=6; %Highest moment of Y in cross moments of X and Y

%Below we calculate various cross moments between X and Y. These are
%calculated from standardized data.
for nn=1:NMomentsY
   for mm=1:NMomentsX
       CrossMoments(nn,mm)=0;
       for pp=1:Ndata
          CrossMoments(nn,mm)=CrossMoments(nn,mm)+Y(pp).^nn.*X(pp).^mm/Ndata;
       end
   end
end
    
    
%Below are the weights on calculation of objective function. More weight on
%a particular moment means that its better match with target moments gets more emphasized as
%compared to match of other moments.
%Choice of good weights is non-trivial.
%Current choice is only haphazard. Please try improvements/
    
    
 w2D(1:NMomentsY,1:NMomentsX)=1;
for nn=NMomentsY-1:-1:1
    for mm=NMomentsX-1:-1:1
        %w2D(nn,mm)=w2D(nn+1,mm+1)*(nn+1)*(mm+1);
        w2D(nn,mm)=w2D(nn+1,mm+1)*(nn+1).^2*(mm+1).^2.0;
    end
end

% w2D(:,1)=w2D(:,1)*100000000;
% w2D(1,:)=w2D(1,:)*100000000;
% w2D(:,2)=w2D(:,2)*500000;
% w2D(2,:)=w2D(2,:)*500000;
% w2D(1,2)=w2D(1,2)*100;
% w2D(2,2)=w2D(2,2)*10;
% w2D(3,2)=w2D(3,2)*5;
% w2D(:,3)=w2D(:,3)*100000;
% w2D(1,3)=w2D(1,3)*20;
% w2D(2,3)=w2D(2,3)*5;
% w2D(1,:)=w2D(1,:)*10000;
% w2D(2,:)=w2D(2,:)*100;
% w2D(3,:)=w2D(3,:)*10;
% w2D(:,4)=w2D(:,4)*10000;
% w2D(1,4)=w2D(1,4)*10;
% w2D(2,4)=w2D(2,4)*2;
% w2D(:,5)=w2D(:,5)*1000;  
% w2D(:,6)=w2D(:,6)*20;  

%Please look on detailed comments inside function below for more insight about it.
%The function below returns coefficients on first row of hermite series so that all
%cross moments of first order in dependent variable X and various orders in independent
%variable Y are matched.

[ddH] = ProduceFirstRowofConditioal2DZSeries02_6M_A(aa,SeriesOrder1,CrossMoments);

%Below we define a 2D array of hermite series coefficents and populate its
%first row with output from above function so that all cross moments of
%first order in X and different orders in Y are matched.
%We also populate first column with univariate hermite coefficients of 
%marginal density of X because of the condition that upon integration of
%the bivariate hermite form, we should get univariate marginal density as a
%result. %Please look at this forum post# 2121 for explanation of this first condition.
% https://forum.wilmott.com/viewtopic.php?t=99702&start=2115#p879042

% 
% %%%%%%%%%%%%%%%%%%%%%%%%%5
% 
ccH0=ccH;

for nn=2:6
    %ccH(nn)=sign(ccH(nn)-dd(nn)).*sqrt(abs(sign(ccH(nn)).*ccH(nn).^2-sign(dd(nn)).*dd(nn).^2));
    if(abs(ccH(nn))>abs(ddH(nn)))
        ccH(nn)=sign(ccH(nn)).*sqrt(ccH(nn).^2-ddH(nn).^2);
    else
    
        ccH(nn)=0;
    end 
end

% %[ccH1] = SubtractZSeriesRVsByMonteCarlo(ccH0,ddH);
% 
% %[ccH2] = SubtractDensity(ccH0,ddH)
% 
% 
% %ddH
% 
% %ccH0
% 
% ccH
% 
% %ccH1
% 
% %ccH2
% %str=input("Look at comparison of ccH");
% 
  bnmH(1,1:6)=ccH(1:6);     %populate first column with univariate margianl density hermite coefficients of X.
% % %bnmH(1,1)=MeanX;
  bnmH(1:6,1)=ddH(1:6);      %populate first row so that all cross moments of first order in X are matched.
  bnmH(1,1)=0;
% % % 
% %%%%%%%%%%%%%%%%%%%%%%%5

% [Zy] = CalculateZgivenXAndZSeriesC5Improved(Y,a0,a);
% [Zx] = CalculateZgivenXAndZSeriesC5Improved(X,c0,c);
% 
 paths=Ndata;
 [CorrH0] = CalculateCorrelationBivariateHermiteCH(Zx,Zy,paths,5);
% 
% bnmH(1,1)=ddH(1);
% bnmH(1,2)=sqrt(1-CorrH0(1).^2).*ccH(2);
% bnmH(1,3)=sqrt(1-CorrH0(2).^2).*ccH(3);
% bnmH(1,4)=sqrt(1-CorrH0(3).^2).*ccH(4);
% bnmH(1,5)=sqrt(1-CorrH0(4).^2).*ccH(5);
% bnmH(1,6)=sqrt(1-CorrH0(5).^2).*ccH(6);
% 
% bnmH(2,1)=CorrH0(1).*ccH(2);
% bnmH(3,1)=CorrH0(2).*ccH(3);
% bnmH(4,1)=CorrH0(3).*ccH(4);
% bnmH(5,1)=CorrH0(4).*ccH(5);
% bnmH(6,1)=CorrH0(5).*ccH(6);
% 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%In our iterative optimization, we will not alter the above first column and first row of 2D hermite coefficients array.


%In the block below, we convert 2D hermite coefficients array bnmH to 2D
%Z-series array bnm. We calculate the values of cross moments given the values of 
%coefficients in 2D Z-series bnm. We use these model cross moments and
%co1mpare them with target cross moments to evaluate the objective function.

%Convert from 2D Hermite Series Coefficients bnmH to 2D Z-series
%coefficients bnm
[bnm] = Convert2DHermitesInto2DSeries(bnmH);
%Evaluate the model cross moments in the function below.
[Moments2D,Moments1D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
%Evaluate the objective function based on weighted squared difference
%between model cross moments and target cross momensts from data.
[ObjFuncBest] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
    %%%%%%%%%%%%%%%%

SeriesOrderIter10=6;
SeriesOrderIter01=6;
alphaSuccessCount(1:SeriesOrderIter10,1:SeriesOrderIter01)=0;
SuccessPrevalpha(1:SeriesOrderIter10,1:SeriesOrderIter01)=0;


%array of perturbation sizes of coefficients of the 2D Hermite form 
%of dependent variable X in iterative optimization.
for nn=1:SeriesOrderIter10
    for mm=1:SeriesOrderIter01
%         if(bnmH(nn,mm)~=0)
%             delta_bnmHCoeff(nn,mm)=bnmH(nn,mm)./50;
%             if((mm>1)&&(nn>1))
%             delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm).*XmVar.^((mm)/2).*YmVar.^((nn)/2).*CorrH0(nn-1).*sqrt(1-CorrH0(mm-1).^2);
%             end
%             if((mm==1)&&(nn==1))
%             delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm).*XmVar.^((mm)/2).*YmVar.^((nn)/2);
%             end
%             if((mm>1)&&(nn==1))
%             delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm).*XmVar.^((mm)/2).*YmVar.^((nn)/2).*sqrt(1-CorrH0(mm-1).^2);
%             end
%             if((mm==1)&&(nn>1))
%             delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm).*XmVar.^((mm)/2).*YmVar.^((nn)/2).*CorrH0(nn-1);
%             end
%         else
%             delta_bnmHCoeff(nn,mm)=.0000025;
%         end
        
        if(bnmH(nn,mm)~=0)
            delta_bnmHCoeff(nn,mm)=bnmH(nn,mm)./50;
            if((mm>1)&&(nn>1))
            delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm).*YmVar.^((nn)/2);%.*CorrH0(nn-1);
            end
            if((mm==1)&&(nn==1))
            delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm).*YmVar.^((nn)/2);
            end
            if((mm>1)&&(nn==1))
            delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm).*YmVar.^((nn)/2);
            end
            if((mm==1)&&(nn>1))
            delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm).*YmVar.^((nn)/2);%.*CorrH0(nn-1);
            end
        else
            delta_bnmHCoeff(nn,mm)=.0000025;
        end
    end    
end

%Assign initial value of bnmH to workhorse variable bnmHCoeff which will be
%used in iterative ioptimization

%load("bnmHFile02.mat","bnmH");

bnmHCoeff=bnmH;

mul1=.9; %decrease the perturbation step size by multiplying it with .9 when 
%objective function does not decrease upon perturbation on both sides.  
mul2=1.1; %Increase the perturbation step size after several successive 
%successes in decreasing the objective function
Iterations=000;
MM1=2;
NN1=2;
MM2=2
NN2=2;

KK1=2;
JJ1=2;
for iter=1:Iterations
iter
bnmHCoeff
ObjFuncBest

%Below we run a two dimensional loop that loops over all rows and columns
%of 2D array of hermite series coefficients. However, we exclude first row
%and first column from this optimization as values there were already fixed
%analytically.


%     for kk=NN1:MM1 %SeriesOrderIter10 %Optimize over Zy hermites.
%         for jj=NN2:MM2 %Optimize over Zx hermites
%             if(iter>500)
%                 NN1=2;
%                 MM1=3;
%                 NN2=2;
%                 MM2=SeriesOrderIter01;
%             end
%             if(iter>1000)
%                 NN1=2;
%                 MM2=SeriesOrderIter10;
%                 NN2=2;
%                 MM2=3;
%                 
%             end
%             if(iter>1500)
%                 NN1=2;
%                 MM1=4;
%                 NN2=2;
%                 MM2=SeriesOrderIter01;
%             end
%             if(iter>2000)
%                 NN1=2;
%                 MM1=SeriesOrderIter10;
%                 NN2=2;
%                 MM2=4;
%             end
%             if(iter>2500)
%                 NN1=2;
%                 MM1=5;
%                 NN2=2;
%                 MM2=SeriesOrderIter01;
%             end
%             
%             if(iter>3000)
%                 NN1=2;
%                 MM1=SeriesOrderIter01;
%                 NN2=2;
%                 MM2=6;
%             end
%         
%             if(iter>3500)
%                 NN1=2;
%                 MM1=SeriesOrderIter01;
%                 NN2=1;
%                 MM2=6;
%             end
%             if(iter>4000)
%                 NN1=1;
%                 MM1=SeriesOrderIter01;
%                 NN2=1;
%                 MM2=6;
%             end
            
%             if(rem(iter,1002)==0)
%                 for nn=2:6
%                     bnmHCoeff(nn,2)=bnmHCoeff(nn,2).*(.9995);%.^(nn-1);
%                     bnmHCoeff(nn,4)=bnmHCoeff(nn,4).*(.9995);%.^(nn-1);
%                     bnmHCoeff(nn,6)=bnmHCoeff(nn,6).*(.9995);%.^(nn-1);
%                 end
%                 [bnm] = Convert2DHermitesInto2DSeries(bnmHCoeff);
%                 [Moments2D,Moments1D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
%                 %Calculate the objective function value.
%                 [ObjFuncNew] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
%                     
%                 ObjFuncBest=ObjFuncNew;                
%             end
            
            
%      for kk=2:SeriesOrderIter10 %Optimize over Zy hermites.
%          for jj=2:SeriesOrderIter01 %Optimize over Zx hermites
        
      for kk=KK1:SeriesOrderIter10 %Optimize over Zy hermites.
          for jj=JJ1:SeriesOrderIter01 %Optimize over Zx hermites
        
              if(iter>1500)
                  JJ1=1;

              end
              if(iter>1000)
                  KK1=1;

              end
            %Assign 2D hermite coefficients to workhorse variable
            bnmHCoeffNew(1:SeriesOrderIter10,1:SeriesOrderIter01)=bnmHCoeff(1:SeriesOrderIter10,1:SeriesOrderIter01);
            %perturb the (kk,jj) coefficient by magnitude given in its
            %delta array named delta_bnmHCoeff(kk,jj)
            bnmHCoeffNew(kk,jj)=bnmHCoeff(kk,jj)+delta_bnmHCoeff(kk,jj);
            %convert to Z-series to calculate the cross moments
            [bnm] = Convert2DHermitesInto2DSeries(bnmHCoeffNew);
            [Moments2D,Moments1D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
            %Calculate the objective function value.
            [ObjFuncNew] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
        

            if(ObjFuncNew<ObjFuncBest) %If objective function decreases, accept the perturbation 
                %and change it in orginal coefficients array
                bnmHCoeff=bnmHCoeffNew;
                %update objective function
                ObjFuncBest=ObjFuncNew;
                if(SuccessPrevalpha(kk,jj)==1)
                    alphaSuccessCount(kk,jj)=alphaSuccessCount(kk,jj)+1;
                end
                SuccessPrevalpha(kk,jj)=1;
            else %If perturbation in first side is not accepted, 
                 %do it again in opposite direction.
            
                bnmHCoeffNew(1:SeriesOrderIter10,1:SeriesOrderIter01)=bnmHCoeff(1:SeriesOrderIter10,1:SeriesOrderIter01);
           
                bnmHCoeffNew(kk,jj)=bnmHCoeff(kk,jj)-delta_bnmHCoeff(kk,jj);
                        
                [bnm] = Convert2DHermitesInto2DSeries(bnmHCoeffNew);

                [Moments2D,Moments1D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);

                [ObjFuncNew] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
                if(ObjFuncNew<ObjFuncBest)
                    bnmHCoeff=bnmHCoeffNew;
                    ObjFuncBest=ObjFuncNew;
                    if(SuccessPrevalpha(kk,jj)==1)
                        alphaSuccessCount(kk,jj)=alphaSuccessCount(kk,jj)+1;
                    end
                    SuccessPrevalpha(kk,jj)=1;
                else
                    SuccessPrevalpha(kk,jj)=0;
                    alphaSuccessCount(kk,jj)=0;
                    delta_bnmHCoeff(kk,jj)=delta_bnmHCoeff(kk,jj)*mul1;
                end
            end
        
        end
    end

    for kk=2:SeriesOrderIter10
        for jj=2:SeriesOrderIter01
            if(alphaSuccessCount(kk,jj)>3) %After successive successes, increase the perturbation step size.
                delta_bnmHCoeff(kk,jj)=delta_bnmHCoeff(kk,jj).*mul2;
            end
        end
    end
   if(rem(iter,500)==0)
         bnm
         Moments2D
         CrossMoments
         Moments2D(:,1)
         CrossMoments(:,1)
         
         ObjFuncBest
         
         str=input("Look at fit of moments");
         
      end
   
end

bnmH=bnmHCoeff;



%save("bnmHFile03.mat","bnmH");
%load("bnmHFile.mat","bnmH");

%str=input("File has been loaded");
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
alphaSuccessCount1(1:SeriesOrderIter10)=0;
alphaSuccessCount2(1:SeriesOrderIter01)=0;
SuccessPrevalpha1(1:SeriesOrderIter10)=0;
SuccessPrevalpha2(1:SeriesOrderIter01)=0;

mul1=.997; %decrease the perturbation step size by multiplying it with .9 when 
%objective function does not decrease upon perturbation on both sides.  
mul2=1.003; %Increase the perturbation step size after several successive 




for mm=1:SeriesOrderIter01
    if(mm>1)
delta_bnmHCoeff1(1:SeriesOrderIter10,mm)=.005.*XmVar.^((mm)/2);%.*sqrt(1-CorrH0(mm-1).^2);
    else
    delta_bnmHCoeff1(1:SeriesOrderIter10,mm)=.005.*XmVar.^((mm)/2);
    end
end
for nn=1:SeriesOrderIter10
    if(nn>1)
delta_bnmHCoeff2(nn,1:SeriesOrderIter01)=.005.*YmVar.^((nn)/2);%.*CorrH0(nn-1);
    else
        delta_bnmHCoeff2(nn,1:SeriesOrderIter01)=.005.*YmVar.^((nn)/2);
    end
end

%           delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm).*XmVar.^((mm)/2).*YmVar.^((nn)/2).*CorrH0(nn-1).*sqrt(1-CorrH0(mm-1).^2);
% 

bnmHCoeff=bnmH;

Iterations01=1000;
for iter=1:Iterations01
iter
bnmHCoeff
ObjFuncBest

%Below we run a two dimensional loop that loops over all rows and columns
%of 2D array of hermite series coefficients. However, we exclude first row
%and first column from this optimization as values there were already fixed
%analytically.


%     for kk=NN1:MM1 %SeriesOrderIter10 %Optimize over Zy hermites.
%         for jj=NN2:MM2 %Optimize over Zx hermites
%             if(iter>500)
%                 NN1=2;
%                 MM1=3;
%                 NN2=2;
%                 MM2=SeriesOrderIter01;
%             end
%             if(iter>1000)
%                 NN1=2;
%                 MM2=SeriesOrderIter10;
%                 NN2=2;
%                 MM2=3;
%                 
%             end
%             if(iter>1500)
%                 NN1=2;
%                 MM1=4;
%                 NN2=2;
%                 MM2=SeriesOrderIter01;
%             end
%             if(iter>2000)
%                 NN1=2;
%                 MM1=SeriesOrderIter10;
%                 NN2=2;
%                 MM2=4;
%             end
%             if(iter>2500)
%                 NN1=2;
%                 MM1=5;
%                 NN2=2;
%                 MM2=SeriesOrderIter01;
%             end
%             
%             if(iter>3000)
%                 NN1=2;
%                 MM1=SeriesOrderIter01;
%                 NN2=2;
%                 MM2=6;
%             end
%         
%             if(iter>3500)
%                 NN1=2;
%                 MM1=SeriesOrderIter01;
%                 NN2=1;
%                 MM2=6;
%             end
%             if(iter>4000)
%                 NN1=1;
%                 MM1=SeriesOrderIter01;
%                 NN2=1;
%                 MM2=6;
%             end
            
%             if(rem(iter,1002)==0)
%                 for nn=2:6
%                     bnmHCoeff(nn,2)=bnmHCoeff(nn,2).*(.9995);%.^(nn-1);
%                     bnmHCoeff(nn,4)=bnmHCoeff(nn,4).*(.9995);%.^(nn-1);
%                     bnmHCoeff(nn,6)=bnmHCoeff(nn,6).*(.9995);%.^(nn-1);
%                 end
%                 [bnm] = Convert2DHermitesInto2DSeries(bnmHCoeff);
%                 [Moments2D,Moments1D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
%                 %Calculate the objective function value.
%                 [ObjFuncNew] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
%                     
%                 ObjFuncBest=ObjFuncNew;                
%             end
            
            
%      for kk=2:SeriesOrderIter10 %Optimize over Zy hermites.
%          for jj=2:SeriesOrderIter01 %Optimize over Zx hermites
        
      for kk=2:SeriesOrderIter10 %Optimize over Zy hermites.
          %for jj=JJ1:SeriesOrderIter01 %Optimize over Zx hermites
%         
%               if(iter>5000)
%                   JJ1=1;
% 
%               end
%               if(iter>5500)
%                   KK1=1;
% 
%               end
            %Assign 2D hermite coefficients to workhorse variable
            bnmHCoeffNew(1:SeriesOrderIter10,1:SeriesOrderIter01)=bnmHCoeff(1:SeriesOrderIter10,1:SeriesOrderIter01);
            %perturb the (kk,jj) coefficient by magnitude given in its
            %delta array named delta_bnmHCoeff(kk,jj)
            bnmHCoeffNew(kk,2:6)=bnmHCoeff(kk,2:6).*(1+delta_bnmHCoeff1(kk,2:6));
            bnmHCoeffNew(1,1)=0;
            
            %convert to Z-series to calculate the cross moments
            [bnm] = Convert2DHermitesInto2DSeries(bnmHCoeffNew);
            [Moments2D,Moments1D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
            %Calculate the objective function value.
            [ObjFuncNew] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
        

            if(ObjFuncNew<ObjFuncBest) %If objective function decreases, accept the perturbation 
                %and change it in orginal coefficients array
                bnmHCoeff=bnmHCoeffNew;
                %update objective function
                ObjFuncBest=ObjFuncNew;
                if(SuccessPrevalpha1(kk)==1)
                    alphaSuccessCount1(kk)=alphaSuccessCount1(kk)+1;
                end
                SuccessPrevalpha1(kk)=1;
            else %If perturbation in first side is not accepted, 
                 %do it again in opposite direction.
            
                bnmHCoeffNew(1:SeriesOrderIter10,1:SeriesOrderIter01)=bnmHCoeff(1:SeriesOrderIter10,1:SeriesOrderIter01);
           
                %bnmHCoeffNew(kk,jj)=bnmHCoeff(kk,jj)-delta_bnmHCoeff(kk,jj);
                bnmHCoeffNew(kk,2:6)=bnmHCoeff(kk,2:6)./(1+delta_bnmHCoeff1(kk,2:6));
                bnmHCoeffNew(1,1)=0;        
                [bnm] = Convert2DHermitesInto2DSeries(bnmHCoeffNew);

                [Moments2D,Moments1D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);

                [ObjFuncNew] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
                if(ObjFuncNew<ObjFuncBest)
                    bnmHCoeff=bnmHCoeffNew;
                    ObjFuncBest=ObjFuncNew;
                    if(SuccessPrevalpha1(kk)==1)
                        alphaSuccessCount1(kk)=alphaSuccessCount1(kk)+1;
                    end
                    SuccessPrevalpha1(kk)=1;
                else
                    SuccessPrevalpha1(kk)=0;
                    alphaSuccessCount1(kk)=0;
                    delta_bnmHCoeff1(kk,:)=delta_bnmHCoeff1(kk,:)*mul1;
                end
            end
        
        %end
      end
    
            %for kk=KK1:SeriesOrderIter10 %Optimize over Zy hermites.
          for jj=2:SeriesOrderIter01 %Optimize over Zx hermites
        
%               if(iter>5000)
%                   JJ1=1;
% 
%               end
%               if(iter>5500)
%                   KK1=1;
% 
%               end
            %Assign 2D hermite coefficients to workhorse variable
            bnmHCoeffNew(1:SeriesOrderIter10,1:SeriesOrderIter01)=bnmHCoeff(1:SeriesOrderIter10,1:SeriesOrderIter01);
            %perturb the (kk,jj) coefficient by magnitude given in its
            %delta array named delta_bnmHCoeff(kk,jj)
            bnmHCoeffNew(2:6,jj)=bnmHCoeff(2:6,jj).*(1+delta_bnmHCoeff2(2:6,jj));
            bnmHCoeffNew(1,1)=0;
            %convert to Z-series to calculate the cross moments
            [bnm] = Convert2DHermitesInto2DSeries(bnmHCoeffNew);
            [Moments2D,Moments1D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
            %Calculate the objective function value.
            [ObjFuncNew] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
        

            if(ObjFuncNew<ObjFuncBest) %If objective function decreases, accept the perturbation 
                %and change it in orginal coefficients array
                bnmHCoeff=bnmHCoeffNew;
                %update objective function
                ObjFuncBest=ObjFuncNew;
                if(SuccessPrevalpha2(jj)==1)
                    alphaSuccessCount2(jj)=alphaSuccessCount2(jj)+1;
                end
                SuccessPrevalpha2(jj)=1;
            else %If perturbation in first side is not accepted, 
                 %do it again in opposite direction.
            
                bnmHCoeffNew(1:SeriesOrderIter10,1:SeriesOrderIter01)=bnmHCoeff(1:SeriesOrderIter10,1:SeriesOrderIter01);
                
                %bnmHCoeffNew(kk,jj)=bnmHCoeff(kk,jj)-delta_bnmHCoeff(kk,jj);
                bnmHCoeffNew(2:6,jj)=bnmHCoeff(2:6,jj)./(1+delta_bnmHCoeff2(2:6,jj));
                bnmHCoeffNew(1,1)=0;        
                [bnm] = Convert2DHermitesInto2DSeries(bnmHCoeffNew);

                [Moments2D,Moments1D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);

                [ObjFuncNew] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
                if(ObjFuncNew<ObjFuncBest)
                    bnmHCoeff=bnmHCoeffNew;
                    ObjFuncBest=ObjFuncNew;
                    if(SuccessPrevalpha2(jj)==1)
                        alphaSuccessCount2(jj)=alphaSuccessCount2(jj)+1;
                    end
                    SuccessPrevalpha2(jj)=1;
                else
                    SuccessPrevalpha2(jj)=0;
                    alphaSuccessCount2(jj)=0;
                    delta_bnmHCoeff2(:,jj)=delta_bnmHCoeff2(:,jj)*mul1;
                end
            end
        
        %end
      end
    
      
      
      
      

    for kk=2:SeriesOrderIter10
        
            if(alphaSuccessCount1(kk)>4) %After successive successes, increase the perturbation step size.
                delta_bnmHCoeff1(kk,:)=delta_bnmHCoeff1(kk,:).*mul2;
            end
       
    end
    
    for jj=2:SeriesOrderIter01
            if(alphaSuccessCount2(jj)>4) %After successive successes, increase the perturbation step size.
                delta_bnmHCoeff2(:,jj)=delta_bnmHCoeff2(:,jj).*mul2;
            end
        end
   if(rem(iter,500)==0)
         bnm
         Moments2D
         CrossMoments
         Moments2D(:,1)
         CrossMoments(:,1)
         
         ObjFuncBest
         
         str=input("Look at fit of moments");
         
      end
   
end

bnmH=bnmHCoeff;


%In the block below, we convert 2D hermite coefficients array bnmH to 2D
%Z-series array bnm. We calculate the values of cross moments given the values of 
%coefficients in 2D Z-series bnm. We use these model cross moments and
%co1mpare them with target cross moments to evaluate the objective function.

%Convert from 2D Hermite Series Coefficients bnmH to 2D Z-series
%coefficients bnm
[bnm] = Convert2DHermitesInto2DSeries(bnmH);
%Evaluate the model cross moments in the function below.
[Moments2D,Moments1D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
%Evaluate the objective function based on weighted squared difference
%between model cross moments and target cross momensts from data.
[ObjFuncBest] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
    %%%%%%%%%%%%%%%%

SeriesOrderIter10=6;
SeriesOrderIter01=6;
alphaSuccessCount(1:SeriesOrderIter10,1:SeriesOrderIter01)=0;
SuccessPrevalpha(1:SeriesOrderIter10,1:SeriesOrderIter01)=0;


%array of perturbation sizes of coefficients of the 2D Hermite form 
%of dependent variable X in iterative optimization.
for nn=1:SeriesOrderIter10
    for mm=1:SeriesOrderIter01
%         if(bnmH(nn,mm)~=0)
%             delta_bnmHCoeff(nn,mm)=bnmH(nn,mm)./50;
%             if((mm>1)&&(nn>1))
%             delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm).*XmVar.^((mm)/2).*YmVar.^((nn)/2).*CorrH0(nn-1).*sqrt(1-CorrH0(mm-1).^2);
%             end
%             if((mm==1)&&(nn==1))
%             delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm).*XmVar.^((mm)/2).*YmVar.^((nn)/2);
%             end
%             if((mm>1)&&(nn==1))
%             delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm).*XmVar.^((mm)/2).*YmVar.^((nn)/2).*sqrt(1-CorrH0(mm-1).^2);
%             end
%             if((mm==1)&&(nn>1))
%             delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm).*XmVar.^((mm)/2).*YmVar.^((nn)/2).*CorrH0(nn-1);
%             end
%         else
%             delta_bnmHCoeff(nn,mm)=.0000025;
%         end
        
        if(bnmH(nn,mm)~=0)
            delta_bnmHCoeff(nn,mm)=bnmH(nn,mm)./200;
            if((mm>1)&&(nn>1))
            delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm);%.*YmVar.^((nn)/2);%.*CorrH0(nn-1);
            end
            if((mm==1)&&(nn==1))
            delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm);%.*YmVar.^((nn)/2);
            end
            if((mm>1)&&(nn==1))
            delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm);%.*YmVar.^((nn)/2);
            end
            if((mm==1)&&(nn>1))
            delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm);%.*YmVar.^((nn)/2);%.*CorrH0(nn-1);
            end
        else
            delta_bnmHCoeff(nn,mm)=.00000000000025;
        end
        if(delta_bnmHCoeff(nn,mm)<.00000000001)
            delta_bnmHCoeff(nn,mm)<.00000000001;
        end
    end    
end

%Assign initial value of bnmH to workhorse variable bnmHCoeff which will be
%used in iterative ioptimization

%load("bnmHFile02.mat","bnmH");

bnmHCoeff=bnmH;

mul1=.95; %decrease the perturbation step size by multiplying it with .9 when 
%objective function does not decrease upon perturbation on both sides.  
mul2=1.05; %Increase the perturbation step size after several successive 
%successes in decreasing the objective function
Iterations=2000;
MM1=2;
NN1=2;
MM2=2
NN2=2;

KK1=2;
JJ1=2;
for iter=1:Iterations
iter
bnmHCoeff
ObjFuncBest

%Below we run a two dimensional loop that loops over all rows and columns
%of 2D array of hermite series coefficients. However, we exclude first row
%and first column from this optimization as values there were already fixed
%analytically.


%     for kk=NN1:MM1 %SeriesOrderIter10 %Optimize over Zy hermites.
%         for jj=NN2:MM2 %Optimize over Zx hermites
%             if(iter>500)
%                 NN1=2;
%                 MM1=3;
%                 NN2=2;
%                 MM2=SeriesOrderIter01;
%             end
%             if(iter>1000)
%                 NN1=2;
%                 MM2=SeriesOrderIter10;
%                 NN2=2;
%                 MM2=3;
%                 
%             end
%             if(iter>1500)
%                 NN1=2;
%                 MM1=4;
%                 NN2=2;
%                 MM2=SeriesOrderIter01;
%             end
%             if(iter>2000)
%                 NN1=2;
%                 MM1=SeriesOrderIter10;
%                 NN2=2;
%                 MM2=4;
%             end
%             if(iter>2500)
%                 NN1=2;
%                 MM1=5;
%                 NN2=2;
%                 MM2=SeriesOrderIter01;
%             end
%             
%             if(iter>3000)
%                 NN1=2;
%                 MM1=SeriesOrderIter01;
%                 NN2=2;
%                 MM2=6;
%             end
%         
%             if(iter>3500)
%                 NN1=2;
%                 MM1=SeriesOrderIter01;
%                 NN2=1;
%                 MM2=6;
%             end
%             if(iter>4000)
%                 NN1=1;
%                 MM1=SeriesOrderIter01;
%                 NN2=1;
%                 MM2=6;
%             end
            
%             if(rem(iter,1002)==0)
%                 for nn=2:6
%                     bnmHCoeff(nn,2)=bnmHCoeff(nn,2).*(.9995);%.^(nn-1);
%                     bnmHCoeff(nn,4)=bnmHCoeff(nn,4).*(.9995);%.^(nn-1);
%                     bnmHCoeff(nn,6)=bnmHCoeff(nn,6).*(.9995);%.^(nn-1);
%                 end
%                 [bnm] = Convert2DHermitesInto2DSeries(bnmHCoeff);
%                 [Moments2D,Moments1D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
%                 %Calculate the objective function value.
%                 [ObjFuncNew] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
%                     
%                 ObjFuncBest=ObjFuncNew;                
%             end
            
            
%      for kk=2:SeriesOrderIter10 %Optimize over Zy hermites.
%          for jj=2:SeriesOrderIter01 %Optimize over Zx hermites
        
      for kk=KK1:SeriesOrderIter10 %Optimize over Zy hermites.
          for jj=JJ1:SeriesOrderIter01 %Optimize over Zx hermites
        
              if(iter>1500)
                  JJ1=1;

              end
              if(iter>1000)
                  KK1=1;

              end
            %Assign 2D hermite coefficients to workhorse variable
            bnmHCoeffNew(1:SeriesOrderIter10,1:SeriesOrderIter01)=bnmHCoeff(1:SeriesOrderIter10,1:SeriesOrderIter01);
            %perturb the (kk,jj) coefficient by magnitude given in its
            %delta array named delta_bnmHCoeff(kk,jj)
            bnmHCoeffNew(kk,jj)=bnmHCoeff(kk,jj)+delta_bnmHCoeff(kk,jj);
            bnmHCoeffNew(1,1)=0;
            %convert to Z-series to calculate the cross moments
            [bnm] = Convert2DHermitesInto2DSeries(bnmHCoeffNew);
            [Moments2D,Moments1D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
            %Calculate the objective function value.
            [ObjFuncNew] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
        

            if(ObjFuncNew<ObjFuncBest) %If objective function decreases, accept the perturbation 
                %and change it in orginal coefficients array
                bnmHCoeff=bnmHCoeffNew;
                %update objective function
                ObjFuncBest=ObjFuncNew;
                if(SuccessPrevalpha(kk,jj)==1)
                    alphaSuccessCount(kk,jj)=alphaSuccessCount(kk,jj)+1;
                end
                SuccessPrevalpha(kk,jj)=1;
            else %If perturbation in first side is not accepted, 
                 %do it again in opposite direction.
            
                bnmHCoeffNew(1:SeriesOrderIter10,1:SeriesOrderIter01)=bnmHCoeff(1:SeriesOrderIter10,1:SeriesOrderIter01);
                
                bnmHCoeffNew(kk,jj)=bnmHCoeff(kk,jj)-delta_bnmHCoeff(kk,jj);
                bnmHCoeffNew(1,1)=0;        
                [bnm] = Convert2DHermitesInto2DSeries(bnmHCoeffNew);

                [Moments2D,Moments1D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);

                [ObjFuncNew] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
                if(ObjFuncNew<ObjFuncBest)
                    bnmHCoeff=bnmHCoeffNew;
                    ObjFuncBest=ObjFuncNew;
                    if(SuccessPrevalpha(kk,jj)==1)
                        alphaSuccessCount(kk,jj)=alphaSuccessCount(kk,jj)+1;
                    end
                    SuccessPrevalpha(kk,jj)=1;
                else
                    SuccessPrevalpha(kk,jj)=0;
                    alphaSuccessCount(kk,jj)=0;
                    delta_bnmHCoeff(kk,jj)=delta_bnmHCoeff(kk,jj)*mul1;
                end
            end
        
        end
    end

    for kk=2:SeriesOrderIter10
        for jj=2:SeriesOrderIter01
            if(alphaSuccessCount(kk,jj)>3) %After successive successes, increase the perturbation step size.
                delta_bnmHCoeff(kk,jj)=delta_bnmHCoeff(kk,jj).*mul2;
            end
        end
    end
   if(rem(iter,500)==0)
         bnm
         Moments2D
         CrossMoments
         Moments2D(:,1)
         CrossMoments(:,1)
         
         ObjFuncBest
         
         str=input("Look at fit of moments");
         
      end
   
end

bnmH=bnmHCoeff;



%save("bnmHFile03.mat","bnmH");
%load("bnmHFile.mat","bnmH");

%str=input("File has been loaded");
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 
% 
% 
% str=input("Entering Newton Root Search");
% 
% SeriesOrder1=6;
% SeriesOrder10=6;
% SeriesOrder01=6;
% NMomentsY=6;
% NMomentsX=6;
% 
%     %[F,dF] = CalculateMomentsAndDerivativesConditional2DNew02(Ms,aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
%     [F,dF] = CalculateMomentsAndDerivativesConditional2DForNewton02(CrossMoments,aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
% % 
% %         for mm1=2:SeriesOrder01
% %        for nn1=2:SeriesOrder10
% %           da((mm1-2)*(SeriesOrder10-1)+nn1-1,1)=bnmH(nn1,mm1);
% %        end
% %         end
%         
%         for mm1=1:SeriesOrder01
%        for nn1=1:SeriesOrder10
%           da((mm1-1)*(SeriesOrder10)+nn1,1)=bnmH(nn1,mm1);
%        end
%         end
% 
%     da
%     F
%     dF
%     size(F)
%     size(dF)
%     size(da)
%     str=input("Look at sizes of variables F and dF")'
%     
%     
%     
%     %w2D(1:NMomentsY,1:NMomentsX)=1;
%     %for nn=NMomentsY-1:-1:1
%     %    for mm=NMomentsX-1:-1:1
%     %        w2D(nn,mm)=w2D(nn+1,mm+1)*(nn+1)*(mm+1);
%     %    end
%     %end
%     [bnm] = Convert2DHermitesInto2DSeries(bnmH);
%     
%     [Moments2D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
% 
%     [ObjBest] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
%     
%     Moments2D
%     CrossMoments
%     ObjBest
%     str=input("Look at data and model moments");
%     %[ObjMomentOut] = CalculateObjMoment2D(Moment2D0,Moment2D,w2D,MOrder1,MOrder2);
%     
%    bnmHBest=bnmH;
%  nn=0;
%  %while((nn<4)&&((abs(F(1,1))>.000000000001) || (abs(F(2,1))>.000000000001) || (abs(F(3,1))>.000000000001) || (abs(F(4,1))>.00000000001)|| (abs(F(5,1))>.00000000001)|| (abs(F(6,1))>.00000000001)|| (abs(F(7,1))>.00000000001)|| (abs(F(8,1))>.00000000001)  ))
%  for nn=1:500
%      %nn=nn+1;
% % %     %Below Newton matrix equation to improve the Z-series coefficients guess at previous step.
%     
% if(nn==1)
% %da=da-1000000*dF\F;
% %da=da-F/dF;
% 
% da=da-50000.*dF\(F);
% else
% da=da-50000.*dF\F;    
% end
% % for mm1=2:SeriesOrder01
% %        for nn1=2:SeriesOrder10
% %           bnmH(nn1,mm1)=da((mm1-2)*(SeriesOrder10-1)+nn1-1,1);
% %        end
% % end  
%      
% for mm1=1:SeriesOrder01
%        for nn1=1:SeriesOrder10
%           bnmH(nn1,mm1)=da((mm1-1)*(SeriesOrder10)+nn1,1);
%        end
%      end  
%      
%      dF
%      F
%      da
%      bnmH
%      nn
%      
%      str=input("Look at numbers---nn loop");
%      
%      
%      
%      
%     
%      [bnm] = Convert2DHermitesInto2DSeries(bnmH);
%      [Moments2D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
% [ObjNew] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
%      
%      
%      Moments2D
%      CrossMoments
%      ObjBest
%      ObjNew
%      nn
%      str=input("Look at new numbers in the loop after update")
%      
%      
%        
%     
% 
%      if(ObjBest>ObjNew) %%%%&&( IsValidFlag))
%        
%         ObjBest=ObjNew;
%         bnmHBest=bnmH;
%         
%      end
%      
% %    [F,dF] = CalculateMomentsAndDerivativesConditional2DNew02(CrossMoments,aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
%     [F,dF] = CalculateMomentsAndDerivativesConditional2DForNewton02(CrossMoments,aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
% 
%  end
%  bnmH=bnmHBest;
%  
%  [bnm] = Convert2DHermitesInto2DSeries(bnmH);
%      [Moments2D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
% [ObjFinal] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
%  
% ObjFinal
% 
% str=input("Look at ObjFinal");
% 
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% W=0;
% 
% % W(1:Ndata,1)=1.0;
% % W(1:Ndata,2)=Zx(1:Ndata);
% % W(1:Ndata,3)=(Zx(1:Ndata).^2-1);
% % W(1:Ndata,4)=(Zx(1:Ndata).^3-3*Zx(1:Ndata));
% % W(1:Ndata,5)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3);
% % W(1:Ndata,6)=(Zx(1:Ndata).^5-10*Zx(1:Ndata)+15*Zx(1:Ndata));
% 
% W(1:Ndata,1)=1.*Zys(1:Ndata);
% W(1:Ndata,2)=Zx(1:Ndata).*Zys(1:Ndata);
% W(1:Ndata,3)=(Zx(1:Ndata).^2-1).*Zys(1:Ndata);
% W(1:Ndata,4)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*Zys(1:Ndata);
% W(1:Ndata,5)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*Zys(1:Ndata);
% W(1:Ndata,6)=(Zx(1:Ndata).^5-10*Zx(1:Ndata)+15*Zx(1:Ndata)).*Zys(1:Ndata);
% 
% W(1:Ndata,7)=(Zys(1:Ndata).^2-1);
% W(1:Ndata,8)=Zx(1:Ndata).*(Zys(1:Ndata).^2-1);
% W(1:Ndata,9)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^2-1);
% W(1:Ndata,10)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^2-1);
% W(1:Ndata,11)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^2-1);
% W(1:Ndata,12)=(Zx(1:Ndata).^5-10*Zx(1:Ndata)+15*Zx(1:Ndata)).*(Zys(1:Ndata).^2-1);
% 
% W(1:Ndata,13)=(Zys(1:Ndata).^3-3*Zy(1:Ndata));
% W(1:Ndata,14)=Zx(1:Ndata).*(Zys(1:Ndata).^3-3*Zy(1:Ndata));
% W(1:Ndata,15)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^3-3*Zy(1:Ndata));
% W(1:Ndata,16)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^3-3*Zys(1:Ndata));
% W(1:Ndata,17)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^3-3*Zys(1:Ndata));
% W(1:Ndata,18)=(Zx(1:Ndata).^5-10*Zx(1:Ndata )+15*Zx(1:Ndata)).*(Zys(1:Ndata).^3-3*Zys(1:Ndata));
% 
% W(1:Ndata,19)=(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
% W(1:Ndata,20)=Zx(1:Ndata).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
% W(1:Ndata,21)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
% W(1:Ndata,22)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
% W(1:Ndata,23)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
% W(1:Ndata,24)=(Zx(1:Ndata).^5-10*Zx(1:Ndata)+15*Zx(1:Ndata)).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
% 
% W(1:Ndata,25)=(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
% 
% W(1:Ndata,27)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
% W(1:Ndata,28)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
% W(1:Ndata,29)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
% W(1:Ndata,30)=(Zx(1:Ndata).^5-10
% 
% 
% bnmH=bnmH0;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SeriesOrder1=6;
NMomentsY=6;
NMomentsX=6;
    for nn=1:NMomentsY
       for mm=1:NMomentsX
           CrossMoments(nn,mm)=0;
           for pp=1:Ndata
              CrossMoments(nn,mm)=CrossMoments(nn,mm)+Y(pp).^nn.*X(pp).^mm/Ndata;
           end
       end
    end



[chh] = ProduceFirstRowofConditioal2DZSeries02_6M_A(aa,SeriesOrder1,CrossMoments);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[bnm] = Convert2DHermitesInto2DSeries(bnmH);

SeriesOrder1=6;
SeriesOrder10=6;
SeriesOrder01=6;
NMomentsX=6;
NMomentsY=6;
[Moments2D0] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);

Moments2D0

CrossMoments

str=input("Look at comparison of moments--first-standardized");

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%In the code block below, we convert 2D hermite series coefficients of 
%dependent variable X from standardized version to original version.
%For that we first multiply the entire 2D Hermite series by square root of
%variance.
%Later we multiply each column of hermite series of X with particular 
%order of Zy hermite polynomials by square root of volatility(independent variable)
%raised to that power of Zy polynomial order as below.
%bnmH=bnmH.*sqrt(XmVar);
%bnmH(:,1)=bnmH(:,1)*sqrt(XmVar);
%for nn=2:6
%    bnmH(nn,:)=bnmH(nn,:).*(sqrt(YmVar)).^(nn-1);
%end

 bnmH=bnmH*sqrt(XmVar);
% for nn=2:6
%     bnmH(nn,:)=bnmH(nn,:).*(sqrt(YmVar)).^(nn-1);
% end
% for nn=2:6
%     bnmH(:,nn)=bnmH(:,nn).*(sqrt(XmVar)).^(nn-1);
% end

%We convert X from hermite series form to Z-series form.
[bnm] = Convert2DHermitesInto2DSeries(bnmH);
bnm(1,1)=MeanX-bnm(3,1)-3*bnm(5,1)-1*bnm(1,3)-1*3*bnm(1,5)-3*bnm(5,3)-bnm(3,3)-3*bnm(3,5)-9*bnm(5,5);

%Finally in above line, we make sure that mean of the 2D Z-series is


%Below, we convert Z-series of independent variable Y from standard form to
%original variable form.

aa=aa*sqrt(YmVar);
aa(1)=MeanY-aa(3)-3*aa(5);


 SeriesOrder1=6;
 SeriesOrder10=6;
 SeriesOrder01=6;
 NMomentsX=6;
 NMomentsY=6;
 [Moments2D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
 
 Moments2D
 
 CrossMoments11
 
 str=input("Look at comparison of moments");
% 
% 
% for nn=1:NMomentsX
%     for mm=1:NMomentsY
%         
%         Moments2D(mm,nn)
%         Moments2D0(mm,nn).*(sqrt(YmVar)).^(mm).*(sqrt(XmVar)).^(nn)
%         Moments2D0(mm,nn)./(sqrt(YmVar)).^(mm)./(sqrt(XmVar)).^(nn)
%         Moments2D(mm,nn)./(sqrt(YmVar)).^(mm)./(sqrt(XmVar)).^(nn)
%         nn
%         mm
%         str=input("Look at moments again---22---22-222---")
%     end
% end
        




end
 
You think life is a secret, Life is only love of flying, It has seen many ups and downs, But it likes travel more than the destination. Allama Iqbal
 
User avatar
Amin
Topic Author
Posts: 2586
Joined: July 14th, 2002, 3:00 am

Re: Breakthrough in the theory of stochastic differential equations and their simulation

February 19th, 2024, 8:03 pm

Friends, as we see several times in iterative optimization that fit to moments becomes better but the density becomes spiked or rough. I believe that the reason behind it is that conditions for smoothness of the density are violated. The derivatives of Zy terms and Zx terms (as a whole one line or one column) switch signs somewhere in the domain and become negative(if it starts out as positive) or become positive(if it starts out as negative). We encounter this phenomenon in fitting one dimensional densities to moments and many times a sharp fit resulted in awkward density shapes. 
I am trying to embed these conditions for smoothness of density in iterative optimization to see how it goes.
You think life is a secret, Life is only love of flying, It has seen many ups and downs, But it likes travel more than the destination. Allama Iqbal
 
User avatar
Amin
Topic Author
Posts: 2586
Joined: July 14th, 2002, 3:00 am

Re: Breakthrough in the theory of stochastic differential equations and their simulation

February 20th, 2024, 9:37 am

Friends, I have made quite some progress but some quick notes I wanted to share. 
If you exogenously fix first row and first column, please make sure that derivative of Z-series/Hermite Series on first row or first column does not switch signs. Whenever a derivative switches signs on these border row and columns, there are guaranteed to be spikes or discontinuities in the density. I believe the reverse that once these two hermite series do not switch sign, if the optimization is reasonable, it is highly likely that there will be no discontinuities or spikes. 
This derivative of hermite series on first column can possibly be negative but then it should not switch sign and become positive. If it starts out negative, it has to remain negative everywhere. 
We encountered something like this is one dimensional Z-series and we solved the problem by slightly increasing the coefficient that affects the tail so that derivative of Z-series does not switch signs. When I did the same thing to hermite series on borders, the densities are very perfectly smooth.
I have also worked out an algorithm to calculate appropriate values of hermite series on first row and first column when there is correlation and I am currently testing it and will soon share it with friends. Apparently it seems to work well but I want to check a little more. 
You think life is a secret, Life is only love of flying, It has seen many ups and downs, But it likes travel more than the destination. Allama Iqbal
 
User avatar
Amin
Topic Author
Posts: 2586
Joined: July 14th, 2002, 3:00 am

Re: Breakthrough in the theory of stochastic differential equations and their simulation

February 20th, 2024, 9:08 pm

Friends, option prices would be perfectly retrieved from the 2D density of asset if sum of Zy density in first column and sum of Zx density in first row is perfectly equal to 1D marginal density of the asset. 
So once we are given first column of Zy density that we calculated from 1st order cross moments with X, we can find the Zx density on first row by subtracting the earlier calculated Zy density from the marginal density(This is subtraction of density as opposed to subtraction of random variable which is obviously not the case).
There are all sort of minor problems. Density subtraction algorithm might get into problems. Calculated Z-series on Zx axis might have a first derivative that switches sign. So all these problems might have to be solved.
If the density on Zx is valid and its sum with density on Zy (first column) is equal to marginal density, all the call prices will be perfectly retrieved.
In zero correlation cases, density on Zx column was very smaller as compared to marginal density, we were placing on Zx row and it made very little difference so call prices were well retrieved whether we subtracted the first Zy column or not (it did not make much of a difference).
Everything is in flux and I am making a lot of changes so I am not posting another half-baked version and will post a better version in two to three days. However I am posting my density subtraction program that might be helpful for friends. If some supporting function is not posted, please find it on this thread using search.
You can possibly try a subtraction of variances density as opposed to a full-fledged density subtraction from moments as I have done below. Subtraction of variances might be helpful if density subtraction algorithm gets into any problems or does not converge on Newton.
.
.
function [bbH]= SubtractDensity(ccH,aaH)

[c0,c]=ConvertHCoeffsToZCoeffs(ccH(1),ccH(2:6),5);
[a0,a]=ConvertHCoeffsToZCoeffs(aaH(1),aaH(2:6),5);


[muC] = CalculateMomentsOfZSeries(c0,c,5,6);
[muA] = CalculateMomentsOfZSeries(a0,a,5,6);

%muC(1)=muA(1)+muB(1);

muB(1)=muC(1)-muA(1);

%muC(2)=muA(2) + 2 *muA().* muB(1) + muB(2);
muB(2)=muC(2)-(muA(2) + 2 *muA(1).* muB(1));


%muc(3)=muA(3) + 3 .*muA(2).* muB(1) + 3 .*muA(1).* muB(2) + muB(3);
muB(3)=muC(3)-(muA(3) + 3 .*muA(2).* muB(1) + 3 .*muA(1).* muB(2));



%muC(4)=muA(4) + 4 .*muA(3).* muB(1) + 6.* muA(2).* muB(2) + 4* muA(1).* muB(3) + muB(4);
muB(4)=muC(4)-(muA(4) + 4 .*muA(3).* muB(1) + 6.* muA(2).* muB(2) + 4* muA(1).* muB(3));

%muC(5)=muA(5) + 5* muA(4).* muB(1) + 10.* muA(3).* muB(2) + 10*muA(2).* muB(3) + ... 
% 5* muA(1).* muB(4) + muB(5);
muB(5)=muC(5)-(muA(5) + 5* muA(4).* muB(1) + 10.* muA(3).* muB(2) + 10*muA(2).* muB(3) + ... 
 5* muA(1).* muB(4));


%muC(6)=muA(6) + 6 *muA(5).* muB(1) + 15.* muA(4).* muB(2) + 20* muA(3).* muB(3) + ...
% 15 .*muA(2).* muB(4) + 6* muA(1).* muB(5) + muB(6);
muB(6)=muC(6)-(muA(6) + 6 *muA(5).* muB(1) + 15.* muA(4).* muB(2) + 20* muA(3).* muB(3) + ...
 15 .*muA(2).* muB(4) + 6* muA(1).* muB(5));

[b0,b]= CalculateZSeriesDensityFromRawMomentsM6(muB);

[bH0,bH]=ConvertZCoeffsToHCoeffs(b0,b,5);

bbH(1)=bH0;
bbH(2:6)=bH(1:5);

end

.
.
.
function [c0,c] = CalculateZSeriesDensityFromRawMomentsM6(rMu)

    mOrder=6;
    [Mu1,cMu] = ConvertRawMomentsToCentralMoments(rMu,mOrder);

    sMu(1)=0;
    sMu(2)=1;
    sMu(3)=cMu(3)/cMu(2).^1.5;
    sMu(4)=cMu(4)/cMu(2).^2.0;
    sMu(5)=cMu(5)/cMu(2).^2.5;
    sMu(6)=cMu(6)/cMu(2).^3.0;
    %sMu(7)=cMu(7)/cMu(2).^3.5;
    %sMu(8)=cMu(8)/cMu(2).^4.0;
    

    w(mOrder)=1;
for nn=mOrder-1:-1:1
w(nn)=w(nn+1).*(nn+1)*(nn);    
end
%w(2)=w(2)*1024;
%w(8)=w(8)*2;
%w(10)=w(10)*sqrt(2);

    
    iter=2000;
    bGuess(1:5)=0;
    bGuess(1)=1;
    [c0,c] = PreSmoothingGuessAdvancedFromGuessBestNewC5(sMu,bGuess,iter);
    

    
    SeriesOrder=5;
    NMoments=6;    
    
    [F,dF] = CalculateMomentsAndDerivatives_0(sMu,c0,c,SeriesOrder,SeriesOrder,NMoments);

da(1,1)=c0;
da(2:SeriesOrder+1,1)=c(1:SeriesOrder);

[Moments] = CalculateMomentsOfZSeries(c0,c,SeriesOrder,NMoments);
Moments
sMu
str=input('Look at comparison of moments');
%Replace with your own more intelligent objective function if you like.
%ObjBest=100000*(abs(sMu(1)-Moments(1)))+abs(sMu(2)-Moments(2))+abs((sMu(3)-Moments(3))^(1/1.5))+abs((sMu(4)-Moments(4))^(1/2.0)) + ...
%    abs((sMu(5)-Moments(5))^(1/2.0))+abs((sMu(6)-Moments(6))^(1/2.0));
[ObjBest] = CalculateObjMoment(sMu,Moments,w,mOrder)


b0Best=c0;
bBest(1:SeriesOrder)=c(1:SeriesOrder);

nn=0;
while((nn<1000)&&((abs(F(1,1))>.000000000001) || (abs(F(2,1))>.000000000001) || (abs(F(3,1))>.000000000001) || (abs(F(4,1))>.00000000001)|| (abs(F(5,1))>.00000000001)|| (abs(F(6,1))>.00000000001)  ))

    nn=nn+1;
    %Below Newton matrix equation to improve the Z-series coefficients guess at previous step.
    if(nn<10)
        da=da-10*dF\F;
    elseif(nn<20)
        da=da-5*dF\F;
    elseif(nn<40)
        da=da-2*dF\F;
    else
        da=da-dF\F;
    end
    %b0=median
    b0=da(1,1);
    b(1:SeriesOrder)=da(2:SeriesOrder+1,1);

    %[F,dF] = CalculateCumulantsAndDerivativesFromMoments_0(C,b0,b,SeriesOrder,SeriesOrder,NoOfCumulants);
    [F,dF] = CalculateMomentsAndDerivatives_0(sMu,b0,b,SeriesOrder,SeriesOrder,NMoments);
    [IsValidFlag] =1;% CheckIsValidDensity(b0,b);
    [Moments] = CalculateMomentsOfZSeries(b0,b,SeriesOrder,NMoments);

    [ObjNew] = CalculateObjMoment(sMu,Moments,w,mOrder)

    %ObjNew=100000*(abs(sMu(1)-Moments(1)))+abs(sMu(2)-Moments(2))+abs((sMu(3)-Moments(3))^(1/1.5))+abs((sMu(4)-Moments(4))^(1/2.0)) + ...
    %abs((sMu(5)-Moments(5))^(1/2.0))+abs((sMu(6)-Moments(6))^(1/2.0));
  
    if((ObjBest>ObjNew) &&( IsValidFlag))
      
       ObjBest=ObjNew;
       b0Best=b0;
       bBest(1:SeriesOrder)=b(1:SeriesOrder);
    end

    da(1,1)=b0;
    da(2:SeriesOrder+1,1)=b(1:SeriesOrder);

end
c0=b0Best;%Best;
c(1:SeriesOrder)=bBest;%Best(1:SeriesOrder);
[Moments] = CalculateMomentsOfZSeries(c0,c,SeriesOrder,NMoments);
    
b0Best
bBest
Moments
sMu
cMu(2)
str=input('Look at fit of density----0000 ')
    c0=c0*sqrt(cMu(2));
    c=c*sqrt(cMu(2));
    
    c0=c0+Mu1;


end

.
.
.
function [c0,c] = PreSmoothingGuessAdvancedFromGuessBestNewC5(cmu,cin,iter)


%Mul=1.0;
SeriesOrder=5;
NMoments=6;

 EZ(1)=0;
 EZ(2)=1;
 for nn=3:NMoments*SeriesOrder+SeriesOrder+2
     if rem(nn,2)==1
         EZ(nn)=0;
     else
         EZ(nn)=EZ(nn-2)*(nn-1);
         EZ(nn);
     end
 end


c0=-(cin(2)+3*cin(4));  %This is for zero mean condition.
c=cin;
MaxIter=10;

for nn=1:iter     %increase the iterations over coefficients if neeeded


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[M3,dc2] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,3,EZ);

tolerance=.0000001*cmu(3);
mm=0;
while ((abs(M3-cmu(3)) >tolerance ) && (mm<MaxIter))
mm=mm+1;
c(2)=c(2)-(M3-cmu(3))/dc2;

[M3,dc2] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,3,EZ);

end

c0=-(c(2)+3*c(4));

[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);

[c0,c] = IterateSmoothingGuessOverPreviousMomentsC5(cmu,c,3,2,EZ);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
[M4,dc3] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,4,EZ);

tolerance=.0000001*cmu(4);
mm=0;
while ((abs(M4-cmu(4)) >tolerance ) && (mm<MaxIter))
mm=mm+1;
c(3)=c(3)-(M4-cmu(4))/dc3;

[M4,dc3] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,4,EZ);

end

[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);


[c0,c] = IterateSmoothingGuessOverPreviousMomentsC5(cmu,c,4,2,EZ);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


[M5,dc4] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,5,EZ);

tolerance=.0000001*cmu(5);
mm=0;
while ((abs(M5-cmu(5)) >tolerance ) && (mm<MaxIter))
mm=mm+1;

c(4)=c(4)-(M5-cmu(5))/dc4;

[M5,dc4] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,5,EZ);

end
c0=-(c(2)+3*c(4));

[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);


[c0,c] = IterateSmoothingGuessOverPreviousMomentsC5(cmu,c,5,2,EZ);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[M6,dc5] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,6,EZ);


tolerance=.0000001*cmu(6);
mm=0;
while ((abs(M6-cmu(6)) >tolerance ) && (mm<MaxIter))
mm=mm+1;

c(5)=c(5)-(M6-cmu(6))/dc5;
[M6,dc5] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,6,EZ);

end

[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);


[c0,c] = IterateSmoothingGuessOverPreviousMomentsC5(cmu,c,6,2,EZ);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

end


end

.
.
.
function [c0,c] = IterateSmoothingGuessOverPreviousMomentsC5(cmu,c,nMoment,iter,EZ)

MaxIter=7;
SeriesOrder=5;
c0=-(c(2)+3*c(4));
if(nMoment==3)
for nn=1:iter     %increase the iterations over coefficients if neeeded
    
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


c0=-(c(2)+3*c(4));

[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);


[M3,dc2] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,3,EZ);

tolerance=.0000001*cmu(3);
mm=0;
while ((abs(M3-cmu(3)) >tolerance ) && (mm<MaxIter))
mm=mm+1;

c(2)=c(2)-(M3-cmu(3))/dc2;
[M3,dc2] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,3,EZ);

end

c0=-(c(2)+3*c(4));

[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5

if(nMoment==4)
for nn=1:iter     %increase the iterations over coefficients if neeeded
    
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);



[M3,dc2] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,3,EZ);

tolerance=.0000001*cmu(3);
mm=0;
while ((abs(M3-cmu(3)) >tolerance ) && (mm<MaxIter))
mm=mm+1;
c(2)=c(2)-(M3-cmu(3))/dc2;
[M3,dc2] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,3,EZ);

end
c0=-(c(2)+3*c(4));

[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
[M4,dc3] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,4,EZ);

tolerance=.0000001*cmu(4);
mm=0;
while ((abs(M4-cmu(4)) >tolerance ) && (mm<MaxIter))
mm=mm+1;

c(3)=c(3)-(M4-cmu(4))/dc3;
[M4,dc3] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,4,EZ);

end

[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);


end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if(nMoment==5)
for nn=1:iter     %increase the iterations over coefficients if neeeded
    
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);

[M3,dc2] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,3,EZ);

tolerance=.0000001*cmu(3);
mm=0;
while ((abs(M3-cmu(3)) >tolerance ) && (mm<MaxIter))
mm=mm+1;

c(2)=c(2)-(M3-cmu(3))/dc2;
[M3,dc2] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,3,EZ);

end
c0=-(c(2)+3*c(4));

[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
[M4,dc3] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,4,EZ);

tolerance=.0000001*cmu(4);
mm=0;
while ((abs(M4-cmu(4)) >tolerance ) && (mm<MaxIter))
mm=mm+1;


c(3)=c(3)-(M4-cmu(4))/dc3;
[M4,dc3] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,4,EZ);


end
[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


[M5,dc4] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,5,EZ);

tolerance=.0000001*cmu(5);
mm=0;
while ((abs(M5-cmu(5)) >tolerance ) && (mm<MaxIter))
mm=mm+1;

c(4)=c(4)-(M5-cmu(5))/dc4;
[M5,dc4] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,5,EZ);


end
c0=-(c(2)+3*c(4));


[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);


end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


if(nMoment==6)
for nn=1:iter     %increase the iterations over coefficients if neeeded
    
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);


[M3,dc2] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,3,EZ);

tolerance=.0000001*cmu(5);
mm=0;
while ((abs(M3-cmu(3)) >tolerance ) && (mm<MaxIter))
mm=mm+1;

c(2)=c(2)-(M3-cmu(3))/dc2;
[M3,dc2] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,3,EZ);


end
c0=-(c(2)+3*c(4));

[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
[M4,dc3] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,4,EZ);


tolerance=.0000001*cmu(5);
mm=0;
while ((abs(M4-cmu(4)) >tolerance ) && (mm<MaxIter))
mm=mm+1;

c(3)=c(3)-(M4-cmu(4))/dc3;
[M4,dc3] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,4,EZ);


end
[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


[M5,dc4] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,5,EZ);

tolerance=.0000001*cmu(5);
mm=0;
while ((abs(M5-cmu(5)) >tolerance ) && (mm<MaxIter))
mm=mm+1;

c(4)=c(4)-(M5-cmu(5))/dc4;
[M5,dc4] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,5,EZ);


end
c0=-(c(2)+3*c(4));



[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[M6,dc5] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,6,EZ);

tolerance=.0000001*cmu(6);
mm=0;
while ((abs(M6-cmu(6)) >tolerance ) && (mm<MaxIter))
mm=mm+1;


c(5)=c(5)-(M6-cmu(6))/dc5;
[M6,dc5] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,6,EZ);

end

[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%




end


end



end

.
.
.
function [SecondMoment] = CalculateSecondMomentC5(a0,a)


SecondMoment=a0^2+a(1)^2 +2* a0* a(2) +3*(a(2).^2+2* a(1).* a(3) +2* a0* a(4))+ ...
    15*(a(3).^2 +2 *a(2).* a(4) +2 *a(1).* a(5))+105*(a(4).^2 +2* a(3).* a(5) )+ ...
    945*(a(5).^2 );
%a0^2+a1^2+2 a0 a2+3 (a2^2+2 a1 a3+2 a0 a4)+945 a5^2+15 (a3^2+2 a2 a4+2 a1 a5)+105 (a4^2+2 a3 a5)
end

.
.
.
function [EnMoment,dEnMomentdCoeff] = CalculateParticularMomentAndDerivativeOfItsCoeff(a0,a,SeriesOrder,nMoment,EZ)


% if(SeriesOrder>=8)
% a0=-(a(2)+3*a(4)+15*a(6)+105*a(8));% ---1
% end
% if(SeriesOrder<8)
% a0=-(a(2)+3*a(4)+15*a(6));% ---1
% end
% 
% EZ(1)=0;
% EZ(2)=1;
% for nn=3:NMoments*SeriesOrder+NZterms+2
%     if rem(nn,2)==1
%         EZ(nn)=0;
%     else
%         EZ(nn)=EZ(nn-2)*(nn-1);
%         EZ(nn);
%     end
% end
% EZ;

%EXZ(1,1)=1;
%for pp1=1:NZterms
%        EXZ(1,pp1+1)=EZ(pp1);
%end


a(SeriesOrder+1:nMoment*SeriesOrder+1+SeriesOrder)=0;
b0=a0;
b=a;

for mm=2:nMoment
    
    [b0,b] =SeriesProduct(a0,a,b0,b,SeriesOrder*mm+SeriesOrder+1);
     b(SeriesOrder*mm+1:nMoment*SeriesOrder+SeriesOrder+1)=0;
     if(mm==nMoment-1)
         dEnMomentdCoeff=b0.*EZ(nMoment-1);
         for pp2=1:SeriesOrder*nMoment-1
            
            dEnMomentdCoeff=dEnMomentdCoeff+b(pp2).*EZ(pp2+nMoment-1);
        end
        dEnMomentdCoeff=dEnMomentdCoeff*nMoment; 
     end
     if(mm==nMoment)
        EnMoment=b0;
        for pp2=1:SeriesOrder*nMoment
            EnMoment=EnMoment+b(pp2).*EZ(pp2);
    
        end
     end
end   

    

end

.
.
.
function [mu1,cMu] = ConvertRawMomentsToCentralMoments(Mu,mOrder)

%cu
%mu
% %mOrder
%str=input('Look at numbers');
mu1=Mu(1);
for mm=2:mOrder
    cMu(mm)=0;
    for jj=0:mm
        if(jj==0)
            cMu(mm)=cMu(mm)+ (-1)^(mm-jj).*factorial(mm)/factorial(jj)/factorial(mm-jj)*1*mu1.^(mm-jj);
            
        else
            cMu(mm)=cMu(mm)+ (-1)^(mm-jj).*factorial(mm)/factorial(jj)/factorial(mm-jj)*Mu(jj)*mu1.^(mm-jj);
            
        end
    end
end

.
.
.
You think life is a secret, Life is only love of flying, It has seen many ups and downs, But it likes travel more than the destination. Allama Iqbal
 
User avatar
Amin
Topic Author
Posts: 2586
Joined: July 14th, 2002, 3:00 am

Re: Breakthrough in the theory of stochastic differential equations and their simulation

February 20th, 2024, 10:05 pm

Friends, option prices would be perfectly retrieved from the 2D density of asset if sum of Zy density in first column and sum of Zx density in first row is perfectly equal to 1D marginal density of the asset. 
So once we are given first column of Zy density that we calculated from 1st order cross moments with X, we can find the Zx density on first row by subtracting the earlier calculated Zy density from the marginal density(This is subtraction of density as opposed to subtraction of random variable which is obviously not the case).
There are all sort of minor problems. Density subtraction algorithm might get into problems. Calculated Z-series on Zx axis might have a first derivative that switches sign. So all these problems might have to be solved.
If the density on Zx is valid and its sum with density on Zy (first column) is equal to marginal density, all the call prices will be perfectly retrieved.
In zero correlation cases, density on Zx column was very smaller as compared to marginal density, we were placing on Zx row and it made very little difference so call prices were well retrieved whether we subtracted the first Zy column or not (it did not make much of a difference).
Everything is in flux and I am making a lot of changes so I am not posting another half-baked version and will post a better version in two to three days. However I am posting my density subtraction program that might be helpful for friends. If some supporting function is not posted, please find it on this thread using search.
You can possibly try a subtraction of variances density as opposed to a full-fledged density subtraction from moments as I have done below. Subtraction of variances might be helpful if density subtraction algorithm gets into any problems or does not converge on Newton.
.
.
function [bbH]= SubtractDensity(ccH,aaH)

[c0,c]=ConvertHCoeffsToZCoeffs(ccH(1),ccH(2:6),5);
[a0,a]=ConvertHCoeffsToZCoeffs(aaH(1),aaH(2:6),5);


[muC] = CalculateMomentsOfZSeries(c0,c,5,6);
[muA] = CalculateMomentsOfZSeries(a0,a,5,6);

%muC(1)=muA(1)+muB(1);

muB(1)=muC(1)-muA(1);

%muC(2)=muA(2) + 2 *muA().* muB(1) + muB(2);
muB(2)=muC(2)-(muA(2) + 2 *muA(1).* muB(1));


%muc(3)=muA(3) + 3 .*muA(2).* muB(1) + 3 .*muA(1).* muB(2) + muB(3);
muB(3)=muC(3)-(muA(3) + 3 .*muA(2).* muB(1) + 3 .*muA(1).* muB(2));



%muC(4)=muA(4) + 4 .*muA(3).* muB(1) + 6.* muA(2).* muB(2) + 4* muA(1).* muB(3) + muB(4);
muB(4)=muC(4)-(muA(4) + 4 .*muA(3).* muB(1) + 6.* muA(2).* muB(2) + 4* muA(1).* muB(3));

%muC(5)=muA(5) + 5* muA(4).* muB(1) + 10.* muA(3).* muB(2) + 10*muA(2).* muB(3) + ... 
% 5* muA(1).* muB(4) + muB(5);
muB(5)=muC(5)-(muA(5) + 5* muA(4).* muB(1) + 10.* muA(3).* muB(2) + 10*muA(2).* muB(3) + ... 
 5* muA(1).* muB(4));


%muC(6)=muA(6) + 6 *muA(5).* muB(1) + 15.* muA(4).* muB(2) + 20* muA(3).* muB(3) + ...
% 15 .*muA(2).* muB(4) + 6* muA(1).* muB(5) + muB(6);
muB(6)=muC(6)-(muA(6) + 6 *muA(5).* muB(1) + 15.* muA(4).* muB(2) + 20* muA(3).* muB(3) + ...
 15 .*muA(2).* muB(4) + 6* muA(1).* muB(5));

[b0,b]= CalculateZSeriesDensityFromRawMomentsM6(muB);

[bH0,bH]=ConvertZCoeffsToHCoeffs(b0,b,5);

bbH(1)=bH0;
bbH(2:6)=bH(1:5);

end

.
.
.
function [c0,c] = CalculateZSeriesDensityFromRawMomentsM6(rMu)

    mOrder=6;
    [Mu1,cMu] = ConvertRawMomentsToCentralMoments(rMu,mOrder);

    sMu(1)=0;
    sMu(2)=1;
    sMu(3)=cMu(3)/cMu(2).^1.5;
    sMu(4)=cMu(4)/cMu(2).^2.0;
    sMu(5)=cMu(5)/cMu(2).^2.5;
    sMu(6)=cMu(6)/cMu(2).^3.0;
    %sMu(7)=cMu(7)/cMu(2).^3.5;
    %sMu(8)=cMu(8)/cMu(2).^4.0;
    

    w(mOrder)=1;
for nn=mOrder-1:-1:1
w(nn)=w(nn+1).*(nn+1)*(nn);    
end
%w(2)=w(2)*1024;
%w(8)=w(8)*2;
%w(10)=w(10)*sqrt(2);

    
    iter=2000;
    bGuess(1:5)=0;
    bGuess(1)=1;
    [c0,c] = PreSmoothingGuessAdvancedFromGuessBestNewC5(sMu,bGuess,iter);
    

    
    SeriesOrder=5;
    NMoments=6;    
    
    [F,dF] = CalculateMomentsAndDerivatives_0(sMu,c0,c,SeriesOrder,SeriesOrder,NMoments);

da(1,1)=c0;
da(2:SeriesOrder+1,1)=c(1:SeriesOrder);

[Moments] = CalculateMomentsOfZSeries(c0,c,SeriesOrder,NMoments);
Moments
sMu
str=input('Look at comparison of moments');
%Replace with your own more intelligent objective function if you like.
%ObjBest=100000*(abs(sMu(1)-Moments(1)))+abs(sMu(2)-Moments(2))+abs((sMu(3)-Moments(3))^(1/1.5))+abs((sMu(4)-Moments(4))^(1/2.0)) + ...
%    abs((sMu(5)-Moments(5))^(1/2.0))+abs((sMu(6)-Moments(6))^(1/2.0));
[ObjBest] = CalculateObjMoment(sMu,Moments,w,mOrder)


b0Best=c0;
bBest(1:SeriesOrder)=c(1:SeriesOrder);

nn=0;
while((nn<1000)&&((abs(F(1,1))>.000000000001) || (abs(F(2,1))>.000000000001) || (abs(F(3,1))>.000000000001) || (abs(F(4,1))>.00000000001)|| (abs(F(5,1))>.00000000001)|| (abs(F(6,1))>.00000000001)  ))

    nn=nn+1;
    %Below Newton matrix equation to improve the Z-series coefficients guess at previous step.
    if(nn<10)
        da=da-10*dF\F;
    elseif(nn<20)
        da=da-5*dF\F;
    elseif(nn<40)
        da=da-2*dF\F;
    else
        da=da-dF\F;
    end
    %b0=median
    b0=da(1,1);
    b(1:SeriesOrder)=da(2:SeriesOrder+1,1);

    %[F,dF] = CalculateCumulantsAndDerivativesFromMoments_0(C,b0,b,SeriesOrder,SeriesOrder,NoOfCumulants);
    [F,dF] = CalculateMomentsAndDerivatives_0(sMu,b0,b,SeriesOrder,SeriesOrder,NMoments);
    [IsValidFlag] =1;% CheckIsValidDensity(b0,b);
    [Moments] = CalculateMomentsOfZSeries(b0,b,SeriesOrder,NMoments);

    [ObjNew] = CalculateObjMoment(sMu,Moments,w,mOrder)

    %ObjNew=100000*(abs(sMu(1)-Moments(1)))+abs(sMu(2)-Moments(2))+abs((sMu(3)-Moments(3))^(1/1.5))+abs((sMu(4)-Moments(4))^(1/2.0)) + ...
    %abs((sMu(5)-Moments(5))^(1/2.0))+abs((sMu(6)-Moments(6))^(1/2.0));
  
    if((ObjBest>ObjNew) &&( IsValidFlag))
      
       ObjBest=ObjNew;
       b0Best=b0;
       bBest(1:SeriesOrder)=b(1:SeriesOrder);
    end

    da(1,1)=b0;
    da(2:SeriesOrder+1,1)=b(1:SeriesOrder);

end
c0=b0Best;%Best;
c(1:SeriesOrder)=bBest;%Best(1:SeriesOrder);
[Moments] = CalculateMomentsOfZSeries(c0,c,SeriesOrder,NMoments);
    
b0Best
bBest
Moments
sMu
cMu(2)
str=input('Look at fit of density----0000 ')
    c0=c0*sqrt(cMu(2));
    c=c*sqrt(cMu(2));
    
    c0=c0+Mu1;


end

.
.
.
function [c0,c] = PreSmoothingGuessAdvancedFromGuessBestNewC5(cmu,cin,iter)


%Mul=1.0;
SeriesOrder=5;
NMoments=6;

 EZ(1)=0;
 EZ(2)=1;
 for nn=3:NMoments*SeriesOrder+SeriesOrder+2
     if rem(nn,2)==1
         EZ(nn)=0;
     else
         EZ(nn)=EZ(nn-2)*(nn-1);
         EZ(nn);
     end
 end


c0=-(cin(2)+3*cin(4));  %This is for zero mean condition.
c=cin;
MaxIter=10;

for nn=1:iter     %increase the iterations over coefficients if neeeded


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[M3,dc2] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,3,EZ);

tolerance=.0000001*cmu(3);
mm=0;
while ((abs(M3-cmu(3)) >tolerance ) && (mm<MaxIter))
mm=mm+1;
c(2)=c(2)-(M3-cmu(3))/dc2;

[M3,dc2] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,3,EZ);

end

c0=-(c(2)+3*c(4));

[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);

[c0,c] = IterateSmoothingGuessOverPreviousMomentsC5(cmu,c,3,2,EZ);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
[M4,dc3] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,4,EZ);

tolerance=.0000001*cmu(4);
mm=0;
while ((abs(M4-cmu(4)) >tolerance ) && (mm<MaxIter))
mm=mm+1;
c(3)=c(3)-(M4-cmu(4))/dc3;

[M4,dc3] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,4,EZ);

end

[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);


[c0,c] = IterateSmoothingGuessOverPreviousMomentsC5(cmu,c,4,2,EZ);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


[M5,dc4] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,5,EZ);

tolerance=.0000001*cmu(5);
mm=0;
while ((abs(M5-cmu(5)) >tolerance ) && (mm<MaxIter))
mm=mm+1;

c(4)=c(4)-(M5-cmu(5))/dc4;

[M5,dc4] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,5,EZ);

end
c0=-(c(2)+3*c(4));

[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);


[c0,c] = IterateSmoothingGuessOverPreviousMomentsC5(cmu,c,5,2,EZ);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[M6,dc5] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,6,EZ);


tolerance=.0000001*cmu(6);
mm=0;
while ((abs(M6-cmu(6)) >tolerance ) && (mm<MaxIter))
mm=mm+1;

c(5)=c(5)-(M6-cmu(6))/dc5;
[M6,dc5] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,6,EZ);

end

[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);


[c0,c] = IterateSmoothingGuessOverPreviousMomentsC5(cmu,c,6,2,EZ);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

end


end

.
.
.
function [c0,c] = IterateSmoothingGuessOverPreviousMomentsC5(cmu,c,nMoment,iter,EZ)

MaxIter=7;
SeriesOrder=5;
c0=-(c(2)+3*c(4));
if(nMoment==3)
for nn=1:iter     %increase the iterations over coefficients if neeeded
    
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


c0=-(c(2)+3*c(4));

[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);


[M3,dc2] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,3,EZ);

tolerance=.0000001*cmu(3);
mm=0;
while ((abs(M3-cmu(3)) >tolerance ) && (mm<MaxIter))
mm=mm+1;

c(2)=c(2)-(M3-cmu(3))/dc2;
[M3,dc2] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,3,EZ);

end

c0=-(c(2)+3*c(4));

[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5

if(nMoment==4)
for nn=1:iter     %increase the iterations over coefficients if neeeded
    
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);



[M3,dc2] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,3,EZ);

tolerance=.0000001*cmu(3);
mm=0;
while ((abs(M3-cmu(3)) >tolerance ) && (mm<MaxIter))
mm=mm+1;
c(2)=c(2)-(M3-cmu(3))/dc2;
[M3,dc2] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,3,EZ);

end
c0=-(c(2)+3*c(4));

[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
[M4,dc3] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,4,EZ);

tolerance=.0000001*cmu(4);
mm=0;
while ((abs(M4-cmu(4)) >tolerance ) && (mm<MaxIter))
mm=mm+1;

c(3)=c(3)-(M4-cmu(4))/dc3;
[M4,dc3] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,4,EZ);

end

[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);


end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if(nMoment==5)
for nn=1:iter     %increase the iterations over coefficients if neeeded
    
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);

[M3,dc2] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,3,EZ);

tolerance=.0000001*cmu(3);
mm=0;
while ((abs(M3-cmu(3)) >tolerance ) && (mm<MaxIter))
mm=mm+1;

c(2)=c(2)-(M3-cmu(3))/dc2;
[M3,dc2] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,3,EZ);

end
c0=-(c(2)+3*c(4));

[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
[M4,dc3] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,4,EZ);

tolerance=.0000001*cmu(4);
mm=0;
while ((abs(M4-cmu(4)) >tolerance ) && (mm<MaxIter))
mm=mm+1;


c(3)=c(3)-(M4-cmu(4))/dc3;
[M4,dc3] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,4,EZ);


end
[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


[M5,dc4] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,5,EZ);

tolerance=.0000001*cmu(5);
mm=0;
while ((abs(M5-cmu(5)) >tolerance ) && (mm<MaxIter))
mm=mm+1;

c(4)=c(4)-(M5-cmu(5))/dc4;
[M5,dc4] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,5,EZ);


end
c0=-(c(2)+3*c(4));


[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);


end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


if(nMoment==6)
for nn=1:iter     %increase the iterations over coefficients if neeeded
    
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);


[M3,dc2] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,3,EZ);

tolerance=.0000001*cmu(5);
mm=0;
while ((abs(M3-cmu(3)) >tolerance ) && (mm<MaxIter))
mm=mm+1;

c(2)=c(2)-(M3-cmu(3))/dc2;
[M3,dc2] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,3,EZ);


end
c0=-(c(2)+3*c(4));

[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
[M4,dc3] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,4,EZ);


tolerance=.0000001*cmu(5);
mm=0;
while ((abs(M4-cmu(4)) >tolerance ) && (mm<MaxIter))
mm=mm+1;

c(3)=c(3)-(M4-cmu(4))/dc3;
[M4,dc3] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,4,EZ);


end
[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


[M5,dc4] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,5,EZ);

tolerance=.0000001*cmu(5);
mm=0;
while ((abs(M5-cmu(5)) >tolerance ) && (mm<MaxIter))
mm=mm+1;

c(4)=c(4)-(M5-cmu(5))/dc4;
[M5,dc4] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,5,EZ);


end
c0=-(c(2)+3*c(4));



[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[M6,dc5] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,6,EZ);

tolerance=.0000001*cmu(6);
mm=0;
while ((abs(M6-cmu(6)) >tolerance ) && (mm<MaxIter))
mm=mm+1;


c(5)=c(5)-(M6-cmu(6))/dc5;
[M6,dc5] = CalculateParticularMomentAndDerivativeOfItsCoeff(c0,c,SeriesOrder,6,EZ);

end

[SecondMoment] = CalculateSecondMomentC5(c0,c);

c=c/sqrt(SecondMoment);
c0=c0/sqrt(SecondMoment);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%




end


end



end

.
.
.
function [SecondMoment] = CalculateSecondMomentC5(a0,a)


SecondMoment=a0^2+a(1)^2 +2* a0* a(2) +3*(a(2).^2+2* a(1).* a(3) +2* a0* a(4))+ ...
    15*(a(3).^2 +2 *a(2).* a(4) +2 *a(1).* a(5))+105*(a(4).^2 +2* a(3).* a(5) )+ ...
    945*(a(5).^2 );
%a0^2+a1^2+2 a0 a2+3 (a2^2+2 a1 a3+2 a0 a4)+945 a5^2+15 (a3^2+2 a2 a4+2 a1 a5)+105 (a4^2+2 a3 a5)
end

.
.
.
function [EnMoment,dEnMomentdCoeff] = CalculateParticularMomentAndDerivativeOfItsCoeff(a0,a,SeriesOrder,nMoment,EZ)


% if(SeriesOrder>=8)
% a0=-(a(2)+3*a(4)+15*a(6)+105*a(8));% ---1
% end
% if(SeriesOrder<8)
% a0=-(a(2)+3*a(4)+15*a(6));% ---1
% end
% 
% EZ(1)=0;
% EZ(2)=1;
% for nn=3:NMoments*SeriesOrder+NZterms+2
%     if rem(nn,2)==1
%         EZ(nn)=0;
%     else
%         EZ(nn)=EZ(nn-2)*(nn-1);
%         EZ(nn);
%     end
% end
% EZ;

%EXZ(1,1)=1;
%for pp1=1:NZterms
%        EXZ(1,pp1+1)=EZ(pp1);
%end


a(SeriesOrder+1:nMoment*SeriesOrder+1+SeriesOrder)=0;
b0=a0;
b=a;

for mm=2:nMoment
    
    [b0,b] =SeriesProduct(a0,a,b0,b,SeriesOrder*mm+SeriesOrder+1);
     b(SeriesOrder*mm+1:nMoment*SeriesOrder+SeriesOrder+1)=0;
     if(mm==nMoment-1)
         dEnMomentdCoeff=b0.*EZ(nMoment-1);
         for pp2=1:SeriesOrder*nMoment-1
            
            dEnMomentdCoeff=dEnMomentdCoeff+b(pp2).*EZ(pp2+nMoment-1);
        end
        dEnMomentdCoeff=dEnMomentdCoeff*nMoment; 
     end
     if(mm==nMoment)
        EnMoment=b0;
        for pp2=1:SeriesOrder*nMoment
            EnMoment=EnMoment+b(pp2).*EZ(pp2);
    
        end
     end
end   

    

end

.
.
.
function [mu1,cMu] = ConvertRawMomentsToCentralMoments(Mu,mOrder)

%cu
%mu
% %mOrder
%str=input('Look at numbers');
mu1=Mu(1);
for mm=2:mOrder
    cMu(mm)=0;
    for jj=0:mm
        if(jj==0)
            cMu(mm)=cMu(mm)+ (-1)^(mm-jj).*factorial(mm)/factorial(jj)/factorial(mm-jj)*1*mu1.^(mm-jj);
            
        else
            cMu(mm)=cMu(mm)+ (-1)^(mm-jj).*factorial(mm)/factorial(jj)/factorial(mm-jj)*Mu(jj)*mu1.^(mm-jj);
            
        end
    end
end

.
.
.


Friends, please disregard this post. It is working for me a little bit differently but I want to double check it more carefully before posting again.
You think life is a secret, Life is only love of flying, It has seen many ups and downs, But it likes travel more than the destination. Allama Iqbal
 
User avatar
Amin
Topic Author
Posts: 2586
Joined: July 14th, 2002, 3:00 am

Re: Breakthrough in the theory of stochastic differential equations and their simulation

February 20th, 2024, 10:26 pm

I think it might be of some help so I just decided to post the working program as such.
.
.
function [bnm,aa] = CalculateConditionalProbabilitiesYtoXLinearRegression04IterB(Yin,Xin)

%Yin argument translates to independent random variable Y
%Xin argument translates to dependent variable X.
%This function takes observations of an independent variable Y and
%dependent varaible X. These have to be joint observations in the sense
%that nth observation of Y, given by Y(n) is taken jointly with nth
%observation of X, given by X(n). Two arrays of observations are the same
%length and nth mmber of independent variable Y is jointly observed with nth
%member of depedent variable X.
%We want to find the detailed relationship between Y and X so we can get
%the conditional density of dependent variable X given a particular value
%of independent variable Y. This will be done by calibrating coefficients
%of our 2D hermite series to data so that a very good fit to cross moments
%between X and Y is retrieved.
%We will first find univariate Z-series/hermite series of both random
%variables independently. For joint dynamics of dependent variable given 
%te independnet variable, we will assume a 2D hermite series (This has to 
%be two dimensional to be able to capture the dynamics from independent variable Y
%and have its own dynamics) and form but we do not know the coefficients of 
%this 2D hermite series. In this program, we try to use iterative optimization 
%to find the unknown coefficients of 2D hermite series of dependent variable X 
%in a way that after taking products with independent varaible Y, expectation   
%of these products i.e cross moments are as exactly retrieved as possible.
%Our iterative optimization procedure perturbs each hermite coefficient in 
%2D hermite series  by a very slight amount and checks the objective function.
%If the objective function decreases, we eccept the perturbation otherwise
%reject it and then perturb by a small amount in other opposite direction
%and then again check the objective function. If perturbations in both sides 
%are rejected, we do not change the coefficients but slightly decrease the
%perturbation size. 
%We will first standardize the data of both random variables and then
%calculate univariate hermite series of both variables and also their 
%cross moments in standardized form. We do all the calculations of coefficients
%of independent variable Y and 2D dependent variable X
%in standardized version of variables and moments. After optimization of coefficents on 
%standardized data, at the end, we invert the standardization of both 
%dependent and independent variables appropriately to get the Z-series and
%hermite series of actual varaibles in theri original coordinates back from
%standardized coordinates.
%Before optimization, we place two conditions on 2D dependent variable X so that
%first row and first column of 2D hermite coefficents of X is already
%known before optimization stage and it is not changed in optimization. 
%We do not iteratively optimize over this first row and first colums
%which are analytically known from these two conditions.
%Our first condition is that after integration (of bivaraite density or
%alternatively bivaraite 2D Z-series/2D Hermite series) over independent
%variable, we should get the univaraite marginal density/Z-series/Hermite series of X
%which has already been calculated out of data. This fixes the zeroth
%hermite(of independent varaible Y) related terms in the Z-series/hermite series. 
%Please look at this forum post# 2121 for explanation of this first condition.
% https://forum.wilmott.com/viewtopic.php?t=99702&start=2115#p879042

%We can analytically solve for first order cross moments of X with higher
%order in Y. From the analytical solution of these moments, we find first
%row of coefficents in the hermite form.


% 2D Hermite Series Form used in this program is given as
% 
% X = bnmH(1,1) + bnmH(2,1) H_1(Z_y) + bnmH(3,1) H_2(Z_y) + bnmH(4,1) H_3(Z_y) + bnmH(5,1) H_4(Z_y) + bnmH(6,1) H_5(Z_y) 
% + [ bnmH(1,2) + bnmH(2,2) H_1(Z_y) + bnmH(3,2) H_2(Z_y) + bnmH(4,2) H_3(Z_y) + bnmH(5,2) H_4(Z_y) + bnmH(6,2) H_5(Z_y)] H_1(Zx) 
% + [ bnmH(1,3) + bnmH(2,3) H_1(Z_y) + bnmH(3,3) H_2(Z_y) + bnmH(4,3) H_3(Z_y) + bnmH(5,3) H_4(Z_y) + bnmH(6,3) H_5(Z_y)] H_2(Zx)
% + [ bnmH(1,4) + bnmH(2,4) H_1(Z_y) + bnmH(3,4) H_2(Z_y) + bnmH(4,4) H_3(Z_y) + bnmH(5,4) H_4(Z_y) + bnmH(6,4) H_5(Z_y)] H_3(Zx)
% + [ bnmH(1,5) + bnmH(2,5) H_1(Z_y) + bnmH(3,5) H_2(Z_y) + bnmH(4,5) H_3(Z_y) + bnmH(5,5) H_4(Z_y) + bnmH(6,5) H_5(Z_y)] H_4(Zx)
% + [ bnmH(1,6) + bnmH(2,6) H_1(Z_y) + bnmH(3,6) H_2(Z_y) + bnmH(4,6) H_3(Z_y) + bnmH(5,6) H_4(Z_y) + bnmH(6,6) H_5(Z_y)] H_5(Zx)
 
% 2D Z-Series Form used in this program is given as
% 
% X = bnm(1,1) + bnm(2,1) Z_y + bnm(3,1) (Z_y)^2 + bnm(4,1) (Z_y)^3 + bnm(5,1) (Z_y)^4 + bnm(6,1) (Z_y)^5 
% + [ bnm(1,2) + bnm(2,2) Z_y + bnm(3,2) (Z_y)^2 + bnm(4,2) (Z_y)^3 + bnm(5,2) (Z_y)^4 + bnm(6,2) (Z_y)^5 ] Zx 
% + [ bnm(1,3) + bnm(2,2) Z_y + bnm(3,3) (Z_y)^2 + bnm(4,3) (Z_y)^3 + bnm(5,3) (Z_y)^4 + bnm(6,3) (Z_y)^5 ] Zx^2 
% + [ bnm(1,4) + bnm(2,2) Z_y + bnm(3,4) (Z_y)^2 + bnm(4,4) (Z_y)^3 + bnm(5,4) (Z_y)^4 + bnm(6,4) (Z_y)^5 ] Zx^3 
% + [ bnm(1,5) + bnm(2,2) Z_y + bnm(3,5) (Z_y)^2 + bnm(4,5) (Z_y)^3 + bnm(5,5) (Z_y)^4 + bnm(6,5) (Z_y)^5 ] Zx^4 
% + [ bnm(1,6) + bnm(2,2) Z_y + bnm(3,6) (Z_y)^2 + bnm(4,6) (Z_y)^3 + bnm(5,6) (Z_y)^4 + bnm(6,6) (Z_y)^5 ] Zx^5




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%In the code block below, we standardize the independent variable Y and dependent variable X.
%We do all later calculations of various Z-series and cross moments in 
%standardized framework and then at the end of the program, we convert 
%the calculated coefficients of 2D hermite series/Z-series of dependent 
%variable X into original non-standardized framework.

 Ndata=length(Yin);
 
 MeanY=sum(Yin(1:Ndata))/Ndata;
 MeanX=sum(Xin(1:Ndata))/Ndata;
 
 Ym(1:Ndata)=Yin(1:Ndata)-MeanY;
 Xm(1:Ndata)=Xin(1:Ndata)-MeanX;
 
 YmVar=sum(Ym(1:Ndata).^2)/Ndata;
 XmVar=sum(Xm(1:Ndata).^2)/Ndata;
 
 Y(1:Ndata)=Ym(1:Ndata)/sqrt(YmVar);
 X(1:Ndata)=Xm(1:Ndata)/sqrt(XmVar);

 
 sqrt(YmVar)
 sqrt(XmVar)
 
 str=input("Look at standardization constants");
 

 NMomentsY=6;
 NMomentsX=6;
     for nn=1:NMomentsY
        for mm=1:NMomentsX
            CrossMoments11(nn,mm)=0;
            for pp=1:Ndata
               CrossMoments11(nn,mm)=CrossMoments11(nn,mm)+Yin(pp).^nn.*Xin(pp).^mm/Ndata;
               %CrossMoments11(nn,mm)=CrossMoments11(nn,mm)+Y(pp).^nn.*X(pp).^mm/Ndata;
               %CrossMoments11(nn,mm)=CrossMoments11(nn,mm)+Ym(pp).^nn.*Xm(pp).^mm/Ndata;
            end
        end
     end
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Code block below uses polynomial regression to find univariate Z-series 
%coefficients of independent variable Y.
%To know more about polynomial regression read the following and associated
%posts:  https://forum.wilmott.com/viewtopic.php?t=99702&start=2010#p877143
 
%You can get the text file MomentMatchParams08.txt from the forum post below
%https://forum.wilmott.com/viewtopic.php?f=4&t=99702&start=2040#p877863

Mtable=readtable('C:\Users\Lenovo\Documents\MATLAB\MATLAB1\MomentMatchParams08.txt');

%ZI is moment matched grid along the normal density with number of grid
%points equal to data elements in Y given by Ndata. The grid is constructed
%so that probability mass in each grid cell is 1/Ndata so this matches the
%observation probability of Ndata data elements. Due to equal probability
%mass in each grid cell, we call it equiprobable grid.

[ZI] = MatchMomentParametersOfIdealZhalf04(Ndata,Mtable);

Ys=sort(Y);
Ymu(1:Ndata,1)=Ys(1:Ndata);

W(1:Ndata,1)=1;
W(1:Ndata,2)=ZI(1:Ndata);
W(1:Ndata,3)=ZI(1:Ndata).^2;
W(1:Ndata,4)=ZI(1:Ndata).^3;
W(1:Ndata,5)=ZI(1:Ndata).^4;
W(1:Ndata,6)=ZI(1:Ndata).^5;
% W(1:Ndata,7)=ZI(1:Ndata).^6;
% W(1:Ndata,8)=ZI(1:Ndata).^7;


coeff=inv(W'*W)*(W'*Ymu);

%Above, we get coefficients of univariate Z-series of independent
%variable Y by least square regression.


a0=coeff(1,1);
a(1:5)=coeff(2:6,1);

%Above, we assign zeroth power Z-series coefficient to a0 and rest of
%the coefficients to array a.
%This was older format but we might need it since many old functions are written 
%in this format.

%Below, we assign same Z-series coefficients to a single array. This is
%newer format that we want to use mostly.
aa(1:6)=coeff(1:6);


%uncomment these lines if you want to see shape of Z-series constructed
%density of Y. We had calculated coefficients of this Z-series by
%least square polynomial regression.
%PlotZSeriesDensity(a0,a,'r')
%str=input("Look at the density of volatility");
    
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5    
%In this code block, we calcualate the coefficients of univariate marginal
%density of dependent variable X again by least square polynomial
%regression as we did in previous block for independent variable Y.
    
Xs=sort(X);
Xmu(1:Ndata,1)=Xs(1:Ndata);

W(1:Ndata,1)=1;
W(1:Ndata,2)=ZI(1:Ndata);
W(1:Ndata,3)=ZI(1:Ndata).^2;
W(1:Ndata,4)=ZI(1:Ndata).^3;
W(1:Ndata,5)=ZI(1:Ndata).^4;
W(1:Ndata,6)=ZI(1:Ndata).^5;

coeff=inv(W'*W)*(W'*Xmu);

c0=coeff(1,1);
c(1:5)=coeff(2:6,1);

cc(1:6)=coeff(1:6,1);

[ccH] = ConvertZSeriesToHermiteSeriesNew(cc,5);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Zy= CalculateZgivenXAndZSeriesC5Improved(Y,a0,a);

[Xs,I]=sort(X);

Zys=Zy(I);

Zx=ZI;

Xmu(1:Ndata,1)=Xs(1:Ndata);


W=0;

W(1:Ndata,1)=1.0;
W(1:Ndata,2)=Zx(1:Ndata);
W(1:Ndata,3)=(Zx(1:Ndata).^2-1);
W(1:Ndata,4)=(Zx(1:Ndata).^3-3*Zx(1:Ndata));
W(1:Ndata,5)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3);
W(1:Ndata,6)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata));

W(1:Ndata,7)=1.*Zys(1:Ndata);
W(1:Ndata,8)=Zx(1:Ndata).*Zys(1:Ndata);
W(1:Ndata,9)=(Zx(1:Ndata).^2-1).*Zys(1:Ndata);
W(1:Ndata,10)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*Zys(1:Ndata);
W(1:Ndata,11)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*Zys(1:Ndata);
W(1:Ndata,12)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata)).*Zys(1:Ndata);

W(1:Ndata,13)=(Zys(1:Ndata).^2-1);
W(1:Ndata,14)=Zx(1:Ndata).*(Zys(1:Ndata).^2-1);
W(1:Ndata,15)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^2-1);
W(1:Ndata,16)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^2-1);
W(1:Ndata,17)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^2-1);
W(1:Ndata,18)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata)).*(Zys(1:Ndata).^2-1);

W(1:Ndata,19)=(Zys(1:Ndata).^3-3*Zy(1:Ndata));
W(1:Ndata,20)=Zx(1:Ndata).*(Zys(1:Ndata).^3-3*Zy(1:Ndata));
W(1:Ndata,21)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^3-3*Zy(1:Ndata));
W(1:Ndata,22)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^3-3*Zys(1:Ndata));
W(1:Ndata,23)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^3-3*Zys(1:Ndata));
W(1:Ndata,24)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata)).*(Zys(1:Ndata).^3-3*Zys(1:Ndata));

W(1:Ndata,25)=(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
W(1:Ndata,26)=Zx(1:Ndata).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
W(1:Ndata,27)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
W(1:Ndata,28)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
W(1:Ndata,29)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
W(1:Ndata,30)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata)).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);

W(1:Ndata,31)=(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
W(1:Ndata,32)=Zx(1:Ndata).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
W(1:Ndata,33)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
W(1:Ndata,34)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
W(1:Ndata,35)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
W(1:Ndata,36)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata)).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));

coeff=inv(W'*W)*(W'*Xmu);


bnmH0(1,1:6)=ccH(1:6);  %Replace first line of X-hermites with Marginal density retrieval condition
bnmH0(2,1:6)=coeff(7:12);
bnmH0(3,1:6)=coeff(13:18);
bnmH0(4,1:6)=coeff(19:24);
bnmH0(5,1:6)=coeff(25:30);
bnmH0(6,1:6)=coeff(31:36);

bnmH=bnmH0;





%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


SeriesOrder1=6;
NMomentsY=6;


SeriesOrder10=6; %SeriesOrder10 = 1 + highest power of Zy in 2D Z-series%Here highest power of Zy is five 
SeriesOrder01=6; %SeriesOrder01 = 1 + highest power of Zx in 2D Z-series%Here highest power of Zx is also five
%notation is  bnm(1:SeriesOrder10,1:SeriesOrder01)
%Similalry    bnmH(1:SeriesOrder10,1:SeriesOrder01)
 
NMomentsX=6; %Highest moment of X in cross moments of X and Y
NMomentsY=6; %Highest moment of Y in cross moments of X and Y

%Below we calculate various cross moments between X and Y. These are
%calculated from standardized data.
for nn=1:NMomentsY
   for mm=1:NMomentsX
       CrossMoments(nn,mm)=0;
       for pp=1:Ndata
          CrossMoments(nn,mm)=CrossMoments(nn,mm)+Y(pp).^nn.*X(pp).^mm/Ndata;
       end
   end
end
    
    
%Below are the weights on calculation of objective function. More weight on
%a particular moment means that its better match with target moments gets more emphasized as
%compared to match of other moments.
%Choice of good weights is non-trivial.
%Current choice is only haphazard. Please try improvements/
    
    
 w2D(1:NMomentsY,1:NMomentsX)=1;
for nn=NMomentsY-1:-1:1
    for mm=NMomentsX-1:-1:1
        %w2D(nn,mm)=w2D(nn+1,mm+1)*(nn+1)*(mm+1);
        w2D(nn,mm)=w2D(nn+1,mm+1)*(nn+1).^2*(mm+1).^2.0;
    end
end

% w2D(:,1)=w2D(:,1)*100000000;
% w2D(1,:)=w2D(1,:)*100000000;
% w2D(:,2)=w2D(:,2)*500000;
% w2D(2,:)=w2D(2,:)*500000;
% w2D(1,2)=w2D(1,2)*100;
% w2D(2,2)=w2D(2,2)*10;
% w2D(3,2)=w2D(3,2)*5;
% w2D(:,3)=w2D(:,3)*100000;
% w2D(1,3)=w2D(1,3)*20;
% w2D(2,3)=w2D(2,3)*5;
% w2D(1,:)=w2D(1,:)*10000;
% w2D(2,:)=w2D(2,:)*100;
% w2D(3,:)=w2D(3,:)*10;
% w2D(:,4)=w2D(:,4)*10000;
% w2D(1,4)=w2D(1,4)*10;
% w2D(2,4)=w2D(2,4)*2;
% w2D(:,5)=w2D(:,5)*1000;  
% w2D(:,6)=w2D(:,6)*20;  

%Please look on detailed comments inside function below for more insight about it.
%The function below returns coefficients on first row of hermite series so that all
%cross moments of first order in dependent variable X and various orders in independent
%variable Y are matched.

[ddH] = ProduceFirstRowofConditioal2DZSeries02_6M_A(aa,SeriesOrder1,CrossMoments);

%Below we define a 2D array of hermite series coefficents and populate its
%first row with output from above function so that all cross moments of
%first order in X and different orders in Y are matched.
%We also populate first column with univariate hermite coefficients of 
%marginal density of X because of the condition that upon integration of
%the bivariate hermite form, we should get univariate marginal density as a
%result. %Please look at this forum post# 2121 for explanation of this first condition.
% https://forum.wilmott.com/viewtopic.php?t=99702&start=2115#p879042

% 
% %%%%%%%%%%%%%%%%%%%%%%%%%5
% 
ccH0=ccH;

% for nn=2:6
%     %ccH(nn)=sign(ccH(nn)-dd(nn)).*sqrt(abs(sign(ccH(nn)).*ccH(nn).^2-sign(dd(nn)).*dd(nn).^2));
%     if(abs(ccH(nn))>abs(ddH(nn)))
%         ccH(nn)=sign(ccH(nn)).*sqrt(ccH(nn).^2-ddH(nn).^2);
%     else
%     
%         ccH(nn)=0;
%     end 
% end

% %[ccH1] = SubtractZSeriesRVsByMonteCarlo(ccH0,ddH);
% 
% 
% 
% %ddH
% 
% %ccH0
% 
% ccH
% 
% %ccH1
% 
% %ccH2
% %str=input("Look at comparison of ccH");
% 
%  bnmH(1,1:6)=ccH(1:6);     %populate first column with univariate margianl density hermite coefficients of X.
% % %bnmH(1,1)=MeanX;
%  bnmH(1:6,1)=ddH(1:6);      %populate first row so that all cross moments of first order in X are matched.
%  bnmH(1,1)=0;
% % % 
% %%%%%%%%%%%%%%%%%%%%%%%5

 [Zy] = CalculateZgivenXAndZSeriesC5Improved(Y,a0,a);
 [Zx] = CalculateZgivenXAndZSeriesC5Improved(X,c0,c);
% 
 paths=Ndata;
 [CorrH0] = CalculateCorrelationBivariateHermiteCH(Zx,Zy,paths,5);

 
 CorrH0
 ccH
 ddH
 
 str=input("Look at correlation related variables");
 ccH0=ccH;
% ccH0(1)=0;
%ddH(1)=0;
 %ddH_Corr(2:6)=ddH(2:6).*CorrH0(1:5);
 for nn=2:6
     ddH_Corr(nn)=ddH(nn).*CorrH0(nn-1);
 end
 ddH_Corr(1)=ddH(1);%.*CorrH0(nn-1);
 
 
 
[ccH2] = SubtractDensity(ccH0,ddH_Corr);
%[ccH2] = SubtractDensity(ccH0,ddH);


%bnmH(1,2:6)=ccH2(2:6);


CorrH0
 ccH
 ddH
 ccH2
 str=input("Look at correlation related variables----2");

 %[ba01,ba1]=ConvertHCoeffsToZCoeffs(bnmH(1,1),bnmH(1,2:6),5);
 %[ba02,ba2]=ConvertHCoeffsToZCoeffs(bnmH(1,1),bnmH(2:6,1),5);
 
 [ba01,ba1]=ConvertHCoeffsToZCoeffs(ccH2(1),ccH2(2:6),5);
 %[ba02,ba2]=ConvertHCoeffsToZCoeffs(ddH(1),ddH(2:6),5);
 
 [ba02,ba2]=ConvertHCoeffsToZCoeffs(ddH_Corr(1),ddH_Corr(2:6),5);
 %[ba02,ba2]=ConvertHCoeffsToZCoeffs(ddH(1),ddH(2:6),5);
 
 [IsValidFlag1] = CheckIsValidDensity(ba01,ba1);
 [IsValidFlag2] = CheckIsValidDensityPN(ba02,ba2);
 
 IsValidFlag1
 IsValidFlag2
 
 str=input("Look at correlation related variables----3");
%  loopCount=0;
%  if(IsValidFlag1==0)
%      while((IsValidFlag1==0) && (loopCount<25))
%         loopCount=loopCount+1;
%         ba1(5)=ba1(5)+abs(ba1(5))/15;
%         [IsValidFlag1] = CheckIsValidDensity(ba01,ba1);
%      end
%  end
         
 [baH01,baH1]=ConvertZCoeffsToHCoeffs(ba01,ba1(1:5),5);
 
 bnmH(1,2:6)=baH1(1:5);
 
 PlotZSeriesRVGraph(ba01,ba1,'r')
 
 str=input("Look at correlation related variables----4");
 
 
 
 
 
 PlotZSeriesRVGraph(ba02,ba2,'b')
 %Display("Before changing slope"); 
 str=input("Look at correlation related variables--Before Changing Slope--5");
 loopCount=0;
 if(IsValidFlag2==0)
     while((IsValidFlag2==0) && (loopCount<0))
        loopCount=loopCount+1;
        ba2(3)=ba2(3)-abs(ba2(3))/10;
        ba2(5)=ba2(5)-abs(ba2(5))/10;
        [IsValidFlag2] = CheckIsValidDensityPN(ba02,ba2);
     end
 end
         
 [baH02,baH2]=ConvertZCoeffsToHCoeffs(ba02,ba2(1:5),5);
 
 bnmH(2:6,1)=baH2(1:5);
 
 
 
 
 PlotZSeriesRVGraph(ba02,ba2,'b')
 
 str=input("Look at correlation related variables-After changing slope---6");
 
 for nn=2:6
     %bnmH(nn,:)=bnmH(nn,:).*(sqrt(YmVar)).^(nn-1);
%     bnmH(nn,:)=bnmH(nn,:).*(.5).^(nn-1);
 end






%  
%  % 
% % bnmH(1,1)=ddH(1);
% if(abs(ccH(2))>abs(ddH(2)))
%  bnmH(1,2)=sign(ccH(2)-CorrH0(1).*ddH(2)).*sqrt(ccH(2).^2-CorrH0(1).^2.*ddH(2).^2);
%  bnmH(2,1)=ddH(2);
% else
%  bnmH(1,2)=ccH(2);   
%  bnmH(2,1)=sign(ddH(2)-CorrH0(1).*ccH(2)).*sqrt(ddH(2).^2-CorrH0(1).^2.*ccH(2).^2);   
% end
% if(abs(ccH(3))>abs(ddH(3)))
%  bnmH(1,3)=sign(ccH(3)-CorrH0(2).*ddH(3)).*sqrt(ccH(3).^2-CorrH0(2).^2.*ddH(3).^2);
%  bnmH(3,1)=ddH(3);
% else
%  bnmH(1,3)=ccH(3);
%  bnmH(3,1)=sign(ddH(3)-CorrH0(2).*ccH(3)).*sqrt(ddH(3).^2-CorrH0(2).^2.*ccH(3).^2);
%     
% end
% if(abs(ccH(4))>abs(ddH(4)))
%  bnmH(1,4)=sign(ccH(4)-CorrH0(3).*ddH(4)).*sqrt(ccH(4).^2-CorrH0(3).^2.*ddH(4).^2);
%  bnmh(4,1)=ddH(4);
% else
% bnmH(4,1)=sign(ddH(4)-CorrH0(3).*ccH(4)).*sqrt(ddH(4).^2-CorrH0(3).^2.*ccH(4).^2);
%  bnmh(1,4)=ccH(4);    
% end
% if(abs(ccH(5))>abs(ddH(5)))
%  bnmH(1,5)=sign(ccH(5)-CorrH0(4).*ddH(5)).*sqrt(ccH(5).^2-CorrH0(4).^2.*ddH(5).^2);
%  bnmh(5,1)=ddH(5);
% else
% bnmH(5,1)=sign(ddH(5)-CorrH0(4).*ccH(5)).*sqrt(ddH(5).^2-CorrH0(4).^2.*ccH(5).^2);
%  bnmh(1,5)=ccH(5);    
% end
% if(abs(ccH(6))>abs(ddH(6)))
%  bnmH(1,6)=sign(ccH(6)-CorrH0(5).*ddH(6)).*sqrt(ccH(6).^2-CorrH0(5).^2.*ddH(6).^2);
%  bnmh(6,1)=ddH(6);
% else
% bnmH(6,1)=sign(ddH(6)-CorrH0(5).*ccH(6)).*sqrt(ddH(6).^2-CorrH0(5).^2.*ccH(6).^2);
%  bnmh(1,6)=ccH(6);    
% end% 
% % bnmH(2,1)=CorrH0(1).*ccH(2);
% % bnmH(3,1)=CorrH0(2).*ccH(3);
% % bnmH(4,1)=CorrH0(3).*ccH(4);
% % bnmH(5,1)=CorrH0(4).*ccH(5);
% % bnmH(6,1)=CorrH0(5).*ccH(6);
% % 






%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%In our iterative optimization, we will not alter the above first column and first row of 2D hermite coefficients array.


%In the block below, we convert 2D hermite coefficients array bnmH to 2D
%Z-series array bnm. We calculate the values of cross moments given the values of 
%coefficients in 2D Z-series bnm. We use these model cross moments and
%co1mpare them with target cross moments to evaluate the objective function.

%Convert from 2D Hermite Series Coefficients bnmH to 2D Z-series
%coefficients bnm
[bnm] = Convert2DHermitesInto2DSeries(bnmH);
%Evaluate the model cross moments in the function below.
[Moments2D,Moments1D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
%Evaluate the objective function based on weighted squared difference
%between model cross moments and target cross momensts from data.
[ObjFuncBest] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
    %%%%%%%%%%%%%%%%

SeriesOrderIter10=6;
SeriesOrderIter01=6;
alphaSuccessCount(1:SeriesOrderIter10,1:SeriesOrderIter01)=0;
SuccessPrevalpha(1:SeriesOrderIter10,1:SeriesOrderIter01)=0;


%array of perturbation sizes of coefficients of the 2D Hermite form 
%of dependent variable X in iterative optimization.
for nn=1:SeriesOrderIter10
    for mm=1:SeriesOrderIter01
%         if(bnmH(nn,mm)~=0)
%             delta_bnmHCoeff(nn,mm)=bnmH(nn,mm)./50;
%             if((mm>1)&&(nn>1))
%             delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm).*XmVar.^((mm)/2).*YmVar.^((nn)/2).*CorrH0(nn-1).*sqrt(1-CorrH0(mm-1).^2);
%             end
%             if((mm==1)&&(nn==1))
%             delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm).*XmVar.^((mm)/2).*YmVar.^((nn)/2);
%             end
%             if((mm>1)&&(nn==1))
%             delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm).*XmVar.^((mm)/2).*YmVar.^((nn)/2).*sqrt(1-CorrH0(mm-1).^2);
%             end
%             if((mm==1)&&(nn>1))
%             delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm).*XmVar.^((mm)/2).*YmVar.^((nn)/2).*CorrH0(nn-1);
%             end
%         else
%             delta_bnmHCoeff(nn,mm)=.0000025;
%         end
        
        if(bnmH(nn,mm)~=0)
            delta_bnmHCoeff(nn,mm)=bnmH(nn,mm)./50;
            if((mm>1)&&(nn>1))
            delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm).*YmVar.^((nn)/2);%.*CorrH0(nn-1);
            end
            if((mm==1)&&(nn==1))
            delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm).*YmVar.^((nn)/2);
            end
            if((mm>1)&&(nn==1))
            delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm).*YmVar.^((nn)/2);
            end
            if((mm==1)&&(nn>1))
            delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm).*YmVar.^((nn)/2);%.*CorrH0(nn-1);
            end
        else
            delta_bnmHCoeff(nn,mm)=.0000025;
        end
    end    
end

%Assign initial value of bnmH to workhorse variable bnmHCoeff which will be
%used in iterative ioptimization

%load("bnmHFile02.mat","bnmH");

bnmHCoeff=bnmH;

mul1=.9; %decrease the perturbation step size by multiplying it with .9 when 
%objective function does not decrease upon perturbation on both sides.  
mul2=1.1; %Increase the perturbation step size after several successive 
%successes in decreasing the objective function
Iterations=00;
MM1=2;
NN1=2;
MM2=2
NN2=2;

KK1=2;
JJ1=2;
for iter=1:Iterations
iter
bnmHCoeff
ObjFuncBest

%Below we run a two dimensional loop that loops over all rows and columns
%of 2D array of hermite series coefficients. However, we exclude first row
%and first column from this optimization as values there were already fixed
%analytically.


    for kk=NN1:MM1 %SeriesOrderIter10 %Optimize over Zy hermites.
        for jj=NN2:MM2 %Optimize over Zx hermites
            if(iter<300)
                NN1=2;
                MM1=SeriesOrderIter10;
                NN2=SeriesOrderIter01;
                MM2=SeriesOrderIter01;
            end
            if((iter<600)&&(iter>=300))
                NN1=2;
                MM2=SeriesOrderIter10;
                NN2=SeriesOrderIter01-1;
                MM2=SeriesOrderIter01;
                
            end
            if((iter<900) && (iter>=600))
                NN1=2;
                MM2=SeriesOrderIter10;
                NN2=SeriesOrderIter01-2;
                MM2=SeriesOrderIter01;
            end
            if((iter<1200) && (iter>=900))
                NN1=2;
                MM2=SeriesOrderIter10;
                NN2=SeriesOrderIter01-3;
                MM2=SeriesOrderIter01;
            end
            if((iter<1500) && (iter>=1200))
                NN1=2;
                MM2=SeriesOrderIter10;
                NN2=SeriesOrderIter01-4;
                MM2=SeriesOrderIter01;
            end
            
            if(iter>3000)
                NN1=2;
                MM1=SeriesOrderIter01;
                NN2=2;
                MM2=6;
            end
        
            if(iter>3500)
                NN1=2;
                MM1=SeriesOrderIter01;
                NN2=1;
                MM2=6;
            end
            if(iter>4000)
                NN1=1;
                MM1=SeriesOrderIter01;
                NN2=1;
                MM2=6;
            end
            %Assign 2D hermite coefficients to workhorse variable
            bnmHCoeffNew(1:SeriesOrderIter10,1:SeriesOrderIter01)=bnmHCoeff(1:SeriesOrderIter10,1:SeriesOrderIter01);
            %perturb the (kk,jj) coefficient by magnitude given in its
            %delta array named delta_bnmHCoeff(kk,jj)
            bnmHCoeffNew(kk,jj)=bnmHCoeff(kk,jj)+delta_bnmHCoeff(kk,jj);
            %convert to Z-series to calculate the cross moments
            [bnm] = Convert2DHermitesInto2DSeries(bnmHCoeffNew);
            [Moments2D,Moments1D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
            %Calculate the objective function value.
            [ObjFuncNew] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
        

            if(ObjFuncNew<ObjFuncBest) %If objective function decreases, accept the perturbation 
                %and change it in orginal coefficients array
                bnmHCoeff=bnmHCoeffNew;
                %update objective function
                ObjFuncBest=ObjFuncNew;
                if(SuccessPrevalpha(kk,jj)==1)
                    alphaSuccessCount(kk,jj)=alphaSuccessCount(kk,jj)+1;
                end
                SuccessPrevalpha(kk,jj)=1;
            else %If perturbation in first side is not accepted, 
                 %do it again in opposite direction.
            
                bnmHCoeffNew(1:SeriesOrderIter10,1:SeriesOrderIter01)=bnmHCoeff(1:SeriesOrderIter10,1:SeriesOrderIter01);
           
                bnmHCoeffNew(kk,jj)=bnmHCoeff(kk,jj)-delta_bnmHCoeff(kk,jj);
                        
                [bnm] = Convert2DHermitesInto2DSeries(bnmHCoeffNew);

                [Moments2D,Moments1D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);

                [ObjFuncNew] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
                if(ObjFuncNew<ObjFuncBest)
                    bnmHCoeff=bnmHCoeffNew;
                    ObjFuncBest=ObjFuncNew;
                    if(SuccessPrevalpha(kk,jj)==1)
                        alphaSuccessCount(kk,jj)=alphaSuccessCount(kk,jj)+1;
                    end
                    SuccessPrevalpha(kk,jj)=1;
                else
                    SuccessPrevalpha(kk,jj)=0;
                    alphaSuccessCount(kk,jj)=0;
                    delta_bnmHCoeff(kk,jj)=delta_bnmHCoeff(kk,jj)*mul1;
                end
            end
        
        end
    end

    for kk=2:SeriesOrderIter10
        for jj=2:SeriesOrderIter01
            if(alphaSuccessCount(kk,jj)>3) %After successive successes, increase the perturbation step size.
                delta_bnmHCoeff(kk,jj)=delta_bnmHCoeff(kk,jj).*mul2;
            end
        end
    end
   if(rem(iter,500)==0)
         bnm
         Moments2D
         CrossMoments
         Moments2D(:,1)
         CrossMoments(:,1)
         
         ObjFuncBest
         
         str=input("Look at fit of moments");
         
      end
   
end

bnmH=bnmHCoeff;



%save("bnmHFile03.mat","bnmH");
%load("bnmHFile.mat","bnmH");

%str=input("File has been loaded");
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
alphaSuccessCount1(1:SeriesOrderIter10)=0;
alphaSuccessCount2(1:SeriesOrderIter01)=0;
SuccessPrevalpha1(1:SeriesOrderIter10)=0;
SuccessPrevalpha2(1:SeriesOrderIter01)=0;

mul1=.996; %decrease the perturbation step size by multiplying it with .9 when 
%objective function does not decrease upon perturbation on both sides.  
mul2=1.004; %Increase the perturbation step size after several successive 




for mm=1:SeriesOrderIter01
    if(mm>1)
delta_bnmHCoeff1(1:SeriesOrderIter10,mm)=.005.*XmVar.^((mm)/2);%.*sqrt(1-CorrH0(mm-1).^2);
    else
    delta_bnmHCoeff1(1:SeriesOrderIter10,mm)=.005.*XmVar.^((mm)/2);
    end
end
for nn=1:SeriesOrderIter10
    if(nn>1)
delta_bnmHCoeff2(nn,1:SeriesOrderIter01)=.005.*YmVar.^((nn)/2);%.*CorrH0(nn-1);
    else
        delta_bnmHCoeff2(nn,1:SeriesOrderIter01)=.005.*YmVar.^((nn)/2);
    end
end

%           delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm).*XmVar.^((mm)/2).*YmVar.^((nn)/2).*CorrH0(nn-1).*sqrt(1-CorrH0(mm-1).^2);
% 

bnmHCoeff=bnmH;

Iterations01=000;
for iter=1:Iterations01
iter
bnmHCoeff
ObjFuncBest

%Below we run a two dimensional loop that loops over all rows and columns
%of 2D array of hermite series coefficients. However, we exclude first row
%and first column from this optimization as values there were already fixed
%analytically.


%     for kk=NN1:MM1 %SeriesOrderIter10 %Optimize over Zy hermites.
%         for jj=NN2:MM2 %Optimize over Zx hermites
%             if(iter>500)
%                 NN1=2;
%                 MM1=3;
%                 NN2=2;
%                 MM2=SeriesOrderIter01;
%             end
%             if(iter>1000)
%                 NN1=2;
%                 MM2=SeriesOrderIter10;
%                 NN2=2;
%                 MM2=3;
%                 
%             end
%             if(iter>1500)
%                 NN1=2;
%                 MM1=4;
%                 NN2=2;
%                 MM2=SeriesOrderIter01;
%             end
%             if(iter>2000)
%                 NN1=2;
%                 MM1=SeriesOrderIter10;
%                 NN2=2;
%                 MM2=4;
%             end
%             if(iter>2500)
%                 NN1=2;
%                 MM1=5;
%                 NN2=2;
%                 MM2=SeriesOrderIter01;
%             end
%             
%             if(iter>3000)
%                 NN1=2;
%                 MM1=SeriesOrderIter01;
%                 NN2=2;
%                 MM2=6;
%             end
%         
%             if(iter>3500)
%                 NN1=2;
%                 MM1=SeriesOrderIter01;
%                 NN2=1;
%                 MM2=6;
%             end
%             if(iter>4000)
%                 NN1=1;
%                 MM1=SeriesOrderIter01;
%                 NN2=1;
%                 MM2=6;
%             end
            
%             if(rem(iter,1002)==0)
%                 for nn=2:6
%                     bnmHCoeff(nn,2)=bnmHCoeff(nn,2).*(.9995);%.^(nn-1);
%                     bnmHCoeff(nn,4)=bnmHCoeff(nn,4).*(.9995);%.^(nn-1);
%                     bnmHCoeff(nn,6)=bnmHCoeff(nn,6).*(.9995);%.^(nn-1);
%                 end
%                 [bnm] = Convert2DHermitesInto2DSeries(bnmHCoeff);
%                 [Moments2D,Moments1D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
%                 %Calculate the objective function value.
%                 [ObjFuncNew] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
%                     
%                 ObjFuncBest=ObjFuncNew;                
%             end
            
            
%      for kk=2:SeriesOrderIter10 %Optimize over Zy hermites.
%          for jj=2:SeriesOrderIter01 %Optimize over Zx hermites
        
      for kk=2:SeriesOrderIter10 %Optimize over Zy hermites.
          %for jj=JJ1:SeriesOrderIter01 %Optimize over Zx hermites
%         
%               if(iter>5000)
%                   JJ1=1;
% 
%               end
%               if(iter>5500)
%                   KK1=1;
% 
%               end
            %Assign 2D hermite coefficients to workhorse variable
            bnmHCoeffNew(1:SeriesOrderIter10,1:SeriesOrderIter01)=bnmHCoeff(1:SeriesOrderIter10,1:SeriesOrderIter01);
            %perturb the (kk,jj) coefficient by magnitude given in its
            %delta array named delta_bnmHCoeff(kk,jj)
            bnmHCoeffNew(kk,2:6)=bnmHCoeff(kk,2:6).*(1+delta_bnmHCoeff1(kk,2:6));
            bnmHCoeffNew(1,1)=0;
            
            %convert to Z-series to calculate the cross moments
            [bnm] = Convert2DHermitesInto2DSeries(bnmHCoeffNew);
            [Moments2D,Moments1D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
            %Calculate the objective function value.
            [ObjFuncNew] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
        

            if(ObjFuncNew<ObjFuncBest) %If objective function decreases, accept the perturbation 
                %and change it in orginal coefficients array
                bnmHCoeff=bnmHCoeffNew;
                %update objective function
                ObjFuncBest=ObjFuncNew;
                if(SuccessPrevalpha1(kk)==1)
                    alphaSuccessCount1(kk)=alphaSuccessCount1(kk)+1;
                end
                SuccessPrevalpha1(kk)=1;
            else %If perturbation in first side is not accepted, 
                 %do it again in opposite direction.
            
                bnmHCoeffNew(1:SeriesOrderIter10,1:SeriesOrderIter01)=bnmHCoeff(1:SeriesOrderIter10,1:SeriesOrderIter01);
           
                %bnmHCoeffNew(kk,jj)=bnmHCoeff(kk,jj)-delta_bnmHCoeff(kk,jj);
                bnmHCoeffNew(kk,2:6)=bnmHCoeff(kk,2:6)./(1+delta_bnmHCoeff1(kk,2:6));
                bnmHCoeffNew(1,1)=0;        
                [bnm] = Convert2DHermitesInto2DSeries(bnmHCoeffNew);

                [Moments2D,Moments1D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);

                [ObjFuncNew] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
                if(ObjFuncNew<ObjFuncBest)
                    bnmHCoeff=bnmHCoeffNew;
                    ObjFuncBest=ObjFuncNew;
                    if(SuccessPrevalpha1(kk)==1)
                        alphaSuccessCount1(kk)=alphaSuccessCount1(kk)+1;
                    end
                    SuccessPrevalpha1(kk)=1;
                else
                    SuccessPrevalpha1(kk)=0;
                    alphaSuccessCount1(kk)=0;
                    delta_bnmHCoeff1(kk,:)=delta_bnmHCoeff1(kk,:)*mul1;
                end
            end
        
        %end
      end
    
            %for kk=KK1:SeriesOrderIter10 %Optimize over Zy hermites.
          for jj=2:SeriesOrderIter01 %Optimize over Zx hermites
        
%               if(iter>5000)
%                   JJ1=1;
% 
%               end
%               if(iter>5500)
%                   KK1=1;
% 
%               end
            %Assign 2D hermite coefficients to workhorse variable
            bnmHCoeffNew(1:SeriesOrderIter10,1:SeriesOrderIter01)=bnmHCoeff(1:SeriesOrderIter10,1:SeriesOrderIter01);
            %perturb the (kk,jj) coefficient by magnitude given in its
            %delta array named delta_bnmHCoeff(kk,jj)
            bnmHCoeffNew(2:6,jj)=bnmHCoeff(2:6,jj).*(1+delta_bnmHCoeff2(2:6,jj));
            bnmHCoeffNew(1,1)=0;
            %convert to Z-series to calculate the cross moments
            [bnm] = Convert2DHermitesInto2DSeries(bnmHCoeffNew);
            [Moments2D,Moments1D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
            %Calculate the objective function value.
            [ObjFuncNew] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
        

            if(ObjFuncNew<ObjFuncBest) %If objective function decreases, accept the perturbation 
                %and change it in orginal coefficients array
                bnmHCoeff=bnmHCoeffNew;
                %update objective function
                ObjFuncBest=ObjFuncNew;
                if(SuccessPrevalpha2(jj)==1)
                    alphaSuccessCount2(jj)=alphaSuccessCount2(jj)+1;
                end
                SuccessPrevalpha2(jj)=1;
            else %If perturbation in first side is not accepted, 
                 %do it again in opposite direction.
            
                bnmHCoeffNew(1:SeriesOrderIter10,1:SeriesOrderIter01)=bnmHCoeff(1:SeriesOrderIter10,1:SeriesOrderIter01);
                
                %bnmHCoeffNew(kk,jj)=bnmHCoeff(kk,jj)-delta_bnmHCoeff(kk,jj);
                bnmHCoeffNew(2:6,jj)=bnmHCoeff(2:6,jj)./(1+delta_bnmHCoeff2(2:6,jj));
                bnmHCoeffNew(1,1)=0;        
                [bnm] = Convert2DHermitesInto2DSeries(bnmHCoeffNew);

                [Moments2D,Moments1D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);

                [ObjFuncNew] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
                if(ObjFuncNew<ObjFuncBest)
                    bnmHCoeff=bnmHCoeffNew;
                    ObjFuncBest=ObjFuncNew;
                    if(SuccessPrevalpha2(jj)==1)
                        alphaSuccessCount2(jj)=alphaSuccessCount2(jj)+1;
                    end
                    SuccessPrevalpha2(jj)=1;
                else
                    SuccessPrevalpha2(jj)=0;
                    alphaSuccessCount2(jj)=0;
                    delta_bnmHCoeff2(:,jj)=delta_bnmHCoeff2(:,jj)*mul1;
                end
            end
        
        %end
      end
    
      
      
      
      

    for kk=2:SeriesOrderIter10
        
            if(alphaSuccessCount1(kk)>4) %After successive successes, increase the perturbation step size.
                delta_bnmHCoeff1(kk,:)=delta_bnmHCoeff1(kk,:).*mul2;
            end
       
    end
    
    for jj=2:SeriesOrderIter01
            if(alphaSuccessCount2(jj)>4) %After successive successes, increase the perturbation step size.
                delta_bnmHCoeff2(:,jj)=delta_bnmHCoeff2(:,jj).*mul2;
            end
        end
   if(rem(iter,500)==0)
         bnm
         Moments2D
         CrossMoments
         Moments2D(:,1)
         CrossMoments(:,1)
         
         ObjFuncBest
         
         str=input("Look at fit of moments");
         
      end
   
end

bnmH=bnmHCoeff;


%In the block below, we convert 2D hermite coefficients array bnmH to 2D
%Z-series array bnm. We calculate the values of cross moments given the values of 
%coefficients in 2D Z-series bnm. We use these model cross moments and
%co1mpare them with target cross moments to evaluate the objective function.

%Convert from 2D Hermite Series Coefficients bnmH to 2D Z-series
%coefficients bnm
[bnm] = Convert2DHermitesInto2DSeries(bnmH);
%Evaluate the model cross moments in the function below.
[Moments2D,Moments1D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
%Evaluate the objective function based on weighted squared difference
%between model cross moments and target cross momensts from data.
[ObjFuncBest] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
    %%%%%%%%%%%%%%%%

SeriesOrderIter10=6;
SeriesOrderIter01=6;
alphaSuccessCount(1:SeriesOrderIter10,1:SeriesOrderIter01)=0;
SuccessPrevalpha(1:SeriesOrderIter10,1:SeriesOrderIter01)=0;


%array of perturbation sizes of coefficients of the 2D Hermite form 
%of dependent variable X in iterative optimization.
for nn=1:SeriesOrderIter10
    for mm=1:SeriesOrderIter01
%         if(bnmH(nn,mm)~=0)
%             delta_bnmHCoeff(nn,mm)=bnmH(nn,mm)./50;
%             if((mm>1)&&(nn>1))
%             delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm).*XmVar.^((mm)/2).*YmVar.^((nn)/2).*CorrH0(nn-1).*sqrt(1-CorrH0(mm-1).^2);
%             end
%             if((mm==1)&&(nn==1))
%             delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm).*XmVar.^((mm)/2).*YmVar.^((nn)/2);
%             end
%             if((mm>1)&&(nn==1))
%             delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm).*XmVar.^((mm)/2).*YmVar.^((nn)/2).*sqrt(1-CorrH0(mm-1).^2);
%             end
%             if((mm==1)&&(nn>1))
%             delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm).*XmVar.^((mm)/2).*YmVar.^((nn)/2).*CorrH0(nn-1);
%             end
%         else
%             delta_bnmHCoeff(nn,mm)=.0000025;
%         end
        
        if(bnmH(nn,mm)~=0)
            delta_bnmHCoeff(nn,mm)=bnmH(nn,mm)./200;
            if((mm>1)&&(nn>1))
            delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm);%.*YmVar.^((nn)/2);%.*CorrH0(nn-1);
            end
            if((mm==1)&&(nn==1))
            delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm);%.*YmVar.^((nn)/2);
            end
            if((mm>1)&&(nn==1))
            delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm);%.*YmVar.^((nn)/2);
            end
            if((mm==1)&&(nn>1))
            delta_bnmHCoeff(nn,mm)=delta_bnmHCoeff(nn,mm);%.*YmVar.^((nn)/2);%.*CorrH0(nn-1);
            end
        else
            delta_bnmHCoeff(nn,mm)=.00000000000025;
        end
        if(delta_bnmHCoeff(nn,mm)<.00000000001)
            delta_bnmHCoeff(nn,mm)<.00000000001;
        end
    end    
end

%Assign initial value of bnmH to workhorse variable bnmHCoeff which will be
%used in iterative ioptimization

%load("bnmHFile02.mat","bnmH");

bnmHCoeff=bnmH;

mul1=.95; %decrease the perturbation step size by multiplying it with .9 when 
%objective function does not decrease upon perturbation on both sides.  
mul2=1.05; %Increase the perturbation step size after several successive 
%successes in decreasing the objective function
Iterations02=00;
MM1=2;
NN1=2;
MM2=2
NN2=2;

KK1=2;
JJ1=2;
for iter=1:Iterations02
iter
bnmHCoeff
ObjFuncBest

%Below we run a two dimensional loop that loops over all rows and columns
%of 2D array of hermite series coefficients. However, we exclude first row
%and first column from this optimization as values there were already fixed
%analytically.


%     for kk=NN1:MM1 %SeriesOrderIter10 %Optimize over Zy hermites.
%         for jj=NN2:MM2 %Optimize over Zx hermites
%             if(iter>500)
%                 NN1=2;
%                 MM1=3;
%                 NN2=2;
%                 MM2=SeriesOrderIter01;
%             end
%             if(iter>1000)
%                 NN1=2;
%                 MM2=SeriesOrderIter10;
%                 NN2=2;
%                 MM2=3;
%                 
%             end
%             if(iter>1500)
%                 NN1=2;
%                 MM1=4;
%                 NN2=2;
%                 MM2=SeriesOrderIter01;
%             end
%             if(iter>2000)
%                 NN1=2;
%                 MM1=SeriesOrderIter10;
%                 NN2=2;
%                 MM2=4;
%             end
%             if(iter>2500)
%                 NN1=2;
%                 MM1=5;
%                 NN2=2;
%                 MM2=SeriesOrderIter01;
%             end
%             
%             if(iter>3000)
%                 NN1=2;
%                 MM1=SeriesOrderIter01;
%                 NN2=2;
%                 MM2=6;
%             end
%         
%             if(iter>3500)
%                 NN1=2;
%                 MM1=SeriesOrderIter01;
%                 NN2=1;
%                 MM2=6;
%             end
%             if(iter>4000)
%                 NN1=1;
%                 MM1=SeriesOrderIter01;
%                 NN2=1;
%                 MM2=6;
%             end
            
%             if(rem(iter,1002)==0)
%                 for nn=2:6
%                     bnmHCoeff(nn,2)=bnmHCoeff(nn,2).*(.9995);%.^(nn-1);
%                     bnmHCoeff(nn,4)=bnmHCoeff(nn,4).*(.9995);%.^(nn-1);
%                     bnmHCoeff(nn,6)=bnmHCoeff(nn,6).*(.9995);%.^(nn-1);
%                 end
%                 [bnm] = Convert2DHermitesInto2DSeries(bnmHCoeff);
%                 [Moments2D,Moments1D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
%                 %Calculate the objective function value.
%                 [ObjFuncNew] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
%                     
%                 ObjFuncBest=ObjFuncNew;                
%             end
            
            
%      for kk=2:SeriesOrderIter10 %Optimize over Zy hermites.
%          for jj=2:SeriesOrderIter01 %Optimize over Zx hermites
        
      for kk=KK1:SeriesOrderIter10 %Optimize over Zy hermites.
          for jj=JJ1:SeriesOrderIter01 %Optimize over Zx hermites
        
              if(iter>1500)
                  JJ1=1;

              end
              if(iter>1000)
                  KK1=1;

              end
            %Assign 2D hermite coefficients to workhorse variable
            bnmHCoeffNew(1:SeriesOrderIter10,1:SeriesOrderIter01)=bnmHCoeff(1:SeriesOrderIter10,1:SeriesOrderIter01);
            %perturb the (kk,jj) coefficient by magnitude given in its
            %delta array named delta_bnmHCoeff(kk,jj)
            bnmHCoeffNew(kk,jj)=bnmHCoeff(kk,jj)+delta_bnmHCoeff(kk,jj);
            bnmHCoeffNew(1,1)=0;
            %convert to Z-series to calculate the cross moments
            [bnm] = Convert2DHermitesInto2DSeries(bnmHCoeffNew);
            [Moments2D,Moments1D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
            %Calculate the objective function value.
            [ObjFuncNew] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
        

            if(ObjFuncNew<ObjFuncBest) %If objective function decreases, accept the perturbation 
                %and change it in orginal coefficients array
                bnmHCoeff=bnmHCoeffNew;
                %update objective function
                ObjFuncBest=ObjFuncNew;
                if(SuccessPrevalpha(kk,jj)==1)
                    alphaSuccessCount(kk,jj)=alphaSuccessCount(kk,jj)+1;
                end
                SuccessPrevalpha(kk,jj)=1;
            else %If perturbation in first side is not accepted, 
                 %do it again in opposite direction.
            
                bnmHCoeffNew(1:SeriesOrderIter10,1:SeriesOrderIter01)=bnmHCoeff(1:SeriesOrderIter10,1:SeriesOrderIter01);
                
                bnmHCoeffNew(kk,jj)=bnmHCoeff(kk,jj)-delta_bnmHCoeff(kk,jj);
                bnmHCoeffNew(1,1)=0;        
                [bnm] = Convert2DHermitesInto2DSeries(bnmHCoeffNew);

                [Moments2D,Moments1D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);

                [ObjFuncNew] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
                if(ObjFuncNew<ObjFuncBest)
                    bnmHCoeff=bnmHCoeffNew;
                    ObjFuncBest=ObjFuncNew;
                    if(SuccessPrevalpha(kk,jj)==1)
                        alphaSuccessCount(kk,jj)=alphaSuccessCount(kk,jj)+1;
                    end
                    SuccessPrevalpha(kk,jj)=1;
                else
                    SuccessPrevalpha(kk,jj)=0;
                    alphaSuccessCount(kk,jj)=0;
                    delta_bnmHCoeff(kk,jj)=delta_bnmHCoeff(kk,jj)*mul1;
                end
            end
        
        end
    end

    for kk=2:SeriesOrderIter10
        for jj=2:SeriesOrderIter01
            if(alphaSuccessCount(kk,jj)>3) %After successive successes, increase the perturbation step size.
                delta_bnmHCoeff(kk,jj)=delta_bnmHCoeff(kk,jj).*mul2;
            end
        end
    end
   if(rem(iter,500)==0)
         bnm
         Moments2D
         CrossMoments
         Moments2D(:,1)
         CrossMoments(:,1)
         
         ObjFuncBest
         
         str=input("Look at fit of moments");
         
      end
   
end

bnmH=bnmHCoeff;



%save("bnmHFile03.mat","bnmH");
%load("bnmHFile.mat","bnmH");

%str=input("File has been loaded");
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 
% 
% 
% str=input("Entering Newton Root Search");
% 
% SeriesOrder1=6;
% SeriesOrder10=6;
% SeriesOrder01=6;
% NMomentsY=6;
% NMomentsX=6;
% 
%     %[F,dF] = CalculateMomentsAndDerivativesConditional2DNew02(Ms,aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
%     [F,dF] = CalculateMomentsAndDerivativesConditional2DForNewton02(CrossMoments,aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
% % 
% %         for mm1=2:SeriesOrder01
% %        for nn1=2:SeriesOrder10
% %           da((mm1-2)*(SeriesOrder10-1)+nn1-1,1)=bnmH(nn1,mm1);
% %        end
% %         end
%         
%         for mm1=1:SeriesOrder01
%        for nn1=1:SeriesOrder10
%           da((mm1-1)*(SeriesOrder10)+nn1,1)=bnmH(nn1,mm1);
%        end
%         end
% 
%     da
%     F
%     dF
%     size(F)
%     size(dF)
%     size(da)
%     str=input("Look at sizes of variables F and dF")'
%     
%     
%     
%     %w2D(1:NMomentsY,1:NMomentsX)=1;
%     %for nn=NMomentsY-1:-1:1
%     %    for mm=NMomentsX-1:-1:1
%     %        w2D(nn,mm)=w2D(nn+1,mm+1)*(nn+1)*(mm+1);
%     %    end
%     %end
%     [bnm] = Convert2DHermitesInto2DSeries(bnmH);
%     
%     [Moments2D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
% 
%     [ObjBest] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
%     
%     Moments2D
%     CrossMoments
%     ObjBest
%     str=input("Look at data and model moments");
%     %[ObjMomentOut] = CalculateObjMoment2D(Moment2D0,Moment2D,w2D,MOrder1,MOrder2);
%     
%    bnmHBest=bnmH;
%  nn=0;
%  %while((nn<4)&&((abs(F(1,1))>.000000000001) || (abs(F(2,1))>.000000000001) || (abs(F(3,1))>.000000000001) || (abs(F(4,1))>.00000000001)|| (abs(F(5,1))>.00000000001)|| (abs(F(6,1))>.00000000001)|| (abs(F(7,1))>.00000000001)|| (abs(F(8,1))>.00000000001)  ))
%  for nn=1:500
%      %nn=nn+1;
% % %     %Below Newton matrix equation to improve the Z-series coefficients guess at previous step.
%     
% if(nn==1)
% %da=da-1000000*dF\F;
% %da=da-F/dF;
% 
% da=da-50000.*dF\(F);
% else
% da=da-50000.*dF\F;    
% end
% % for mm1=2:SeriesOrder01
% %        for nn1=2:SeriesOrder10
% %           bnmH(nn1,mm1)=da((mm1-2)*(SeriesOrder10-1)+nn1-1,1);
% %        end
% % end  
%      
% for mm1=1:SeriesOrder01
%        for nn1=1:SeriesOrder10
%           bnmH(nn1,mm1)=da((mm1-1)*(SeriesOrder10)+nn1,1);
%        end
%      end  
%      
%      dF
%      F
%      da
%      bnmH
%      nn
%      
%      str=input("Look at numbers---nn loop");
%      
%      
%      
%      
%     
%      [bnm] = Convert2DHermitesInto2DSeries(bnmH);
%      [Moments2D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
% [ObjNew] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
%      
%      
%      Moments2D
%      CrossMoments
%      ObjBest
%      ObjNew
%      nn
%      str=input("Look at new numbers in the loop after update")
%      
%      
%        
%     
% 
%      if(ObjBest>ObjNew) %%%%&&( IsValidFlag))
%        
%         ObjBest=ObjNew;
%         bnmHBest=bnmH;
%         
%      end
%      
% %    [F,dF] = CalculateMomentsAndDerivativesConditional2DNew02(CrossMoments,aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
%     [F,dF] = CalculateMomentsAndDerivativesConditional2DForNewton02(CrossMoments,aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
% 
%  end
%  bnmH=bnmHBest;
%  
%  [bnm] = Convert2DHermitesInto2DSeries(bnmH);
%      [Moments2D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
% [ObjFinal] = CalculateObjMoment2D1D(CrossMoments,Moments2D,w2D,NMomentsX,NMomentsY);
%  
% ObjFinal
% 
% str=input("Look at ObjFinal");
% 
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% W=0;
% 
% % W(1:Ndata,1)=1.0;
% % W(1:Ndata,2)=Zx(1:Ndata);
% % W(1:Ndata,3)=(Zx(1:Ndata).^2-1);
% % W(1:Ndata,4)=(Zx(1:Ndata).^3-3*Zx(1:Ndata));
% % W(1:Ndata,5)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3);
% % W(1:Ndata,6)=(Zx(1:Ndata).^5-10*Zx(1:Ndata)+15*Zx(1:Ndata));
% 
% W(1:Ndata,1)=1.*Zys(1:Ndata);
% W(1:Ndata,2)=Zx(1:Ndata).*Zys(1:Ndata);
% W(1:Ndata,3)=(Zx(1:Ndata).^2-1).*Zys(1:Ndata);
% W(1:Ndata,4)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*Zys(1:Ndata);
% W(1:Ndata,5)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*Zys(1:Ndata);
% W(1:Ndata,6)=(Zx(1:Ndata).^5-10*Zx(1:Ndata)+15*Zx(1:Ndata)).*Zys(1:Ndata);
% 
% W(1:Ndata,7)=(Zys(1:Ndata).^2-1);
% W(1:Ndata,8)=Zx(1:Ndata).*(Zys(1:Ndata).^2-1);
% W(1:Ndata,9)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^2-1);
% W(1:Ndata,10)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^2-1);
% W(1:Ndata,11)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^2-1);
% W(1:Ndata,12)=(Zx(1:Ndata).^5-10*Zx(1:Ndata)+15*Zx(1:Ndata)).*(Zys(1:Ndata).^2-1);
% 
% W(1:Ndata,13)=(Zys(1:Ndata).^3-3*Zy(1:Ndata));
% W(1:Ndata,14)=Zx(1:Ndata).*(Zys(1:Ndata).^3-3*Zy(1:Ndata));
% W(1:Ndata,15)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^3-3*Zy(1:Ndata));
% W(1:Ndata,16)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^3-3*Zys(1:Ndata));
% W(1:Ndata,17)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^3-3*Zys(1:Ndata));
% W(1:Ndata,18)=(Zx(1:Ndata).^5-10*Zx(1:Ndata )+15*Zx(1:Ndata)).*(Zys(1:Ndata).^3-3*Zys(1:Ndata));
% 
% W(1:Ndata,19)=(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
% W(1:Ndata,20)=Zx(1:Ndata).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
% W(1:Ndata,21)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
% W(1:Ndata,22)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
% W(1:Ndata,23)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
% W(1:Ndata,24)=(Zx(1:Ndata).^5-10*Zx(1:Ndata)+15*Zx(1:Ndata)).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
% 
% W(1:Ndata,25)=(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
% 
% W(1:Ndata,27)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
% W(1:Ndata,28)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
% W(1:Ndata,29)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
% W(1:Ndata,30)=(Zx(1:Ndata).^5-10
% 
% 
% bnmH=bnmH0;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SeriesOrder1=6;
NMomentsY=6;
NMomentsX=6;
    for nn=1:NMomentsY
       for mm=1:NMomentsX
           CrossMoments(nn,mm)=0;
           for pp=1:Ndata
              CrossMoments(nn,mm)=CrossMoments(nn,mm)+Y(pp).^nn.*X(pp).^mm/Ndata;
           end
       end
    end



[chh] = ProduceFirstRowofConditioal2DZSeries02_6M_A(aa,SeriesOrder1,CrossMoments);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[bnm] = Convert2DHermitesInto2DSeries(bnmH);

SeriesOrder1=6;
SeriesOrder10=6;
SeriesOrder01=6;
NMomentsX=6;
NMomentsY=6;
[Moments2D0] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);

Moments2D0

CrossMoments

str=input("Look at comparison of moments--first-standardized");

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%In the code block below, we convert 2D hermite series coefficients of 
%dependent variable X from standardized version to original version.
%For that we first multiply the entire 2D Hermite series by square root of
%variance.
%Later we multiply each column of hermite series of X with particular 
%order of Zy hermite polynomials by square root of volatility(independent variable)
%raised to that power of Zy polynomial order as below.
%bnmH=bnmH.*sqrt(XmVar);
%bnmH(:,1)=bnmH(:,1)*sqrt(XmVar);
%for nn=2:6
%    bnmH(nn,:)=bnmH(nn,:).*(sqrt(YmVar)).^(nn-1);
%end

 bnmH=bnmH*sqrt(XmVar);
% for nn=2:6
%     bnmH(nn,:)=bnmH(nn,:).*(sqrt(YmVar)).^(nn-1);
% end
% for nn=2:6
%     bnmH(:,nn)=bnmH(:,nn).*(sqrt(XmVar)).^(nn-1);
% end

%We convert X from hermite series form to Z-series form.
[bnm] = Convert2DHermitesInto2DSeries(bnmH);
bnm(1,1)=MeanX-bnm(3,1)-3*bnm(5,1)-1*bnm(1,3)-1*3*bnm(1,5)-3*bnm(5,3)-bnm(3,3)-3*bnm(3,5)-9*bnm(5,5);

%Finally in above line, we make sure that mean of the 2D Z-series is


%Below, we convert Z-series of independent variable Y from standard form to
%original variable form.

aa=aa*sqrt(YmVar);
aa(1)=MeanY-aa(3)-3*aa(5);


 SeriesOrder1=6;
 SeriesOrder10=6;
 SeriesOrder01=6;
 NMomentsX=6;
 NMomentsY=6;
 [Moments2D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
 
 Moments2D
 
 CrossMoments11
 
 str=input("Look at comparison of moments");
% 
% 
% for nn=1:NMomentsX
%     for mm=1:NMomentsY
%         
%         Moments2D(mm,nn)
%         Moments2D0(mm,nn).*(sqrt(YmVar)).^(mm).*(sqrt(XmVar)).^(nn)
%         Moments2D0(mm,nn)./(sqrt(YmVar)).^(mm)./(sqrt(XmVar)).^(nn)
%         Moments2D(mm,nn)./(sqrt(YmVar)).^(mm)./(sqrt(XmVar)).^(nn)
%         nn
%         mm
%         str=input("Look at moments again---22---22-222---")
%     end
% end
        




end
You think life is a secret, Life is only love of flying, It has seen many ups and downs, But it likes travel more than the destination. Allama Iqbal
 
User avatar
Amin
Topic Author
Posts: 2586
Joined: July 14th, 2002, 3:00 am

Re: Breakthrough in the theory of stochastic differential equations and their simulation

February 21st, 2024, 8:00 am

Friends, I went to drawing board again and tried to see if I can improve the basic regression algorithm. And it works far better now after improvement of the algorithm. In the earlier algorithm Zx is sorted with respect to the asset but in new algorithm Zx is sorted with respect to uncorrelated part of the asset (as it actually should be) and it seems to work very well. Sorry that I did not have a very good understanding when I first wrote this regression algorithm.
Here I give the graph with numerical density followed by graph from new algorithm and followed again by graph from old bad regression algorithm. I have not changed any coefficient after they were given out by the regression algorithm.
Graphs are here. I will upload the new program in next post. I hope that we will fix all errors and problems one by one.
.
.
.
NUMERICAL DENSITY

Image

DENSITY FROM NEW CORRECT REGRESSION ALGORITHM



Image

DENSITY FROM OLD REGRESSION ALGORITHM
Image
You think life is a secret, Life is only love of flying, It has seen many ups and downs, But it likes travel more than the destination. Allama Iqbal
 
User avatar
Amin
Topic Author
Posts: 2586
Joined: July 14th, 2002, 3:00 am

Re: Breakthrough in the theory of stochastic differential equations and their simulation

February 21st, 2024, 8:05 am

Here is the new regression algorithm function that I used to create the 2nd graph in previous post.
.
.
.
function [bnm,aa] = CalculateConditionalProbabilitiesYtoXLinearRegression04IterC(Yin,Xin)

%Yin argument translates to independent random variable Y
%Xin argument translates to dependent variable X.
%This function takes observations of an independent variable Y and
%dependent varaible X. These have to be joint observations in the sense
%that nth observation of Y, given by Y(n) is taken jointly with nth
%observation of X, given by X(n). Two arrays of observations are the same
%length and nth mmber of independent variable Y is jointly observed with nth
%member of depedent variable X.
%We want to find the detailed relationship between Y and X so we can get
%the conditional density of dependent variable X given a particular value
%of independent variable Y. This will be done by calibrating coefficients
%of our 2D hermite series to data so that a very good fit to cross moments
%between X and Y is retrieved.
%We will first find univariate Z-series/hermite series of both random
%variables independently. For joint dynamics of dependent variable given 
%te independnet variable, we will assume a 2D hermite series (This has to 
%be two dimensional to be able to capture the dynamics from independent variable Y
%and have its own dynamics) and form but we do not know the coefficients of 
%this 2D hermite series. In this program, we try to use iterative optimization 
%to find the unknown coefficients of 2D hermite series of dependent variable X 
%in a way that after taking products with independent varaible Y, expectation   
%of these products i.e cross moments are as exactly retrieved as possible.
%Our iterative optimization procedure perturbs each hermite coefficient in 
%2D hermite series  by a very slight amount and checks the objective function.
%If the objective function decreases, we eccept the perturbation otherwise
%reject it and then perturb by a small amount in other opposite direction
%and then again check the objective function. If perturbations in both sides 
%are rejected, we do not change the coefficients but slightly decrease the
%perturbation size. 
%We will first standardize the data of both random variables and then
%calculate univariate hermite series of both variables and also their 
%cross moments in standardized form. We do all the calculations of coefficients
%of independent variable Y and 2D dependent variable X
%in standardized version of variables and moments. After optimization of coefficents on 
%standardized data, at the end, we invert the standardization of both 
%dependent and independent variables appropriately to get the Z-series and
%hermite series of actual varaibles in theri original coordinates back from
%standardized coordinates.
%Before optimization, we place two conditions on 2D dependent variable X so that
%first row and first column of 2D hermite coefficents of X is already
%known before optimization stage and it is not changed in optimization. 
%We do not iteratively optimize over this first row and first colums
%which are analytically known from these two conditions.
%Our first condition is that after integration (of bivaraite density or
%alternatively bivaraite 2D Z-series/2D Hermite series) over independent
%variable, we should get the univaraite marginal density/Z-series/Hermite series of X
%which has already been calculated out of data. This fixes the zeroth
%hermite(of independent varaible Y) related terms in the Z-series/hermite series. 
%Please look at this forum post# 2121 for explanation of this first condition.
% https://forum.wilmott.com/viewtopic.php?t=99702&start=2115#p879042

%We can analytically solve for first order cross moments of X with higher
%order in Y. From the analytical solution of these moments, we find first
%row of coefficents in the hermite form.


% 2D Hermite Series Form used in this program is given as
% 
% X = bnmH(1,1) + bnmH(2,1) H_1(Z_y) + bnmH(3,1) H_2(Z_y) + bnmH(4,1) H_3(Z_y) + bnmH(5,1) H_4(Z_y) + bnmH(6,1) H_5(Z_y) 
% + [ bnmH(1,2) + bnmH(2,2) H_1(Z_y) + bnmH(3,2) H_2(Z_y) + bnmH(4,2) H_3(Z_y) + bnmH(5,2) H_4(Z_y) + bnmH(6,2) H_5(Z_y)] H_1(Zx) 
% + [ bnmH(1,3) + bnmH(2,3) H_1(Z_y) + bnmH(3,3) H_2(Z_y) + bnmH(4,3) H_3(Z_y) + bnmH(5,3) H_4(Z_y) + bnmH(6,3) H_5(Z_y)] H_2(Zx)
% + [ bnmH(1,4) + bnmH(2,4) H_1(Z_y) + bnmH(3,4) H_2(Z_y) + bnmH(4,4) H_3(Z_y) + bnmH(5,4) H_4(Z_y) + bnmH(6,4) H_5(Z_y)] H_3(Zx)
% + [ bnmH(1,5) + bnmH(2,5) H_1(Z_y) + bnmH(3,5) H_2(Z_y) + bnmH(4,5) H_3(Z_y) + bnmH(5,5) H_4(Z_y) + bnmH(6,5) H_5(Z_y)] H_4(Zx)
% + [ bnmH(1,6) + bnmH(2,6) H_1(Z_y) + bnmH(3,6) H_2(Z_y) + bnmH(4,6) H_3(Z_y) + bnmH(5,6) H_4(Z_y) + bnmH(6,6) H_5(Z_y)] H_5(Zx)
 
% 2D Z-Series Form used in this program is given as
% 
% X = bnm(1,1) + bnm(2,1) Z_y + bnm(3,1) (Z_y)^2 + bnm(4,1) (Z_y)^3 + bnm(5,1) (Z_y)^4 + bnm(6,1) (Z_y)^5 
% + [ bnm(1,2) + bnm(2,2) Z_y + bnm(3,2) (Z_y)^2 + bnm(4,2) (Z_y)^3 + bnm(5,2) (Z_y)^4 + bnm(6,2) (Z_y)^5 ] Zx 
% + [ bnm(1,3) + bnm(2,2) Z_y + bnm(3,3) (Z_y)^2 + bnm(4,3) (Z_y)^3 + bnm(5,3) (Z_y)^4 + bnm(6,3) (Z_y)^5 ] Zx^2 
% + [ bnm(1,4) + bnm(2,2) Z_y + bnm(3,4) (Z_y)^2 + bnm(4,4) (Z_y)^3 + bnm(5,4) (Z_y)^4 + bnm(6,4) (Z_y)^5 ] Zx^3 
% + [ bnm(1,5) + bnm(2,2) Z_y + bnm(3,5) (Z_y)^2 + bnm(4,5) (Z_y)^3 + bnm(5,5) (Z_y)^4 + bnm(6,5) (Z_y)^5 ] Zx^4 
% + [ bnm(1,6) + bnm(2,2) Z_y + bnm(3,6) (Z_y)^2 + bnm(4,6) (Z_y)^3 + bnm(5,6) (Z_y)^4 + bnm(6,6) (Z_y)^5 ] Zx^5




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%In the code block below, we standardize the independent variable Y and dependent variable X.
%We do all later calculations of various Z-series and cross moments in 
%standardized framework and then at the end of the program, we convert 
%the calculated coefficients of 2D hermite series/Z-series of dependent 
%variable X into original non-standardized framework.

 Ndata=length(Yin);
 
 MeanY=sum(Yin(1:Ndata))/Ndata;
 MeanX=sum(Xin(1:Ndata))/Ndata;
 
 Ym(1:Ndata)=Yin(1:Ndata)-MeanY;
 Xm(1:Ndata)=Xin(1:Ndata)-MeanX;
 
 YmVar=sum(Ym(1:Ndata).^2)/Ndata;
 XmVar=sum(Xm(1:Ndata).^2)/Ndata;
 
 Y(1:Ndata)=Ym(1:Ndata)/sqrt(YmVar);
 X(1:Ndata)=Xm(1:Ndata)/sqrt(XmVar);

 
 sqrt(YmVar)
 sqrt(XmVar)
 
 str=input("Look at standardization constants");
 

 NMomentsY=6;
 NMomentsX=6;
     for nn=1:NMomentsY
        for mm=1:NMomentsX
            CrossMoments11(nn,mm)=0;
            for pp=1:Ndata
               CrossMoments11(nn,mm)=CrossMoments11(nn,mm)+Yin(pp).^nn.*Xin(pp).^mm/Ndata;
               %CrossMoments11(nn,mm)=CrossMoments11(nn,mm)+Y(pp).^nn.*X(pp).^mm/Ndata;
               %CrossMoments11(nn,mm)=CrossMoments11(nn,mm)+Ym(pp).^nn.*Xm(pp).^mm/Ndata;
            end
        end
     end
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Code block below uses polynomial regression to find univariate Z-series 
%coefficients of independent variable Y.
%To know more about polynomial regression read the following and associated
%posts:  https://forum.wilmott.com/viewtopic.php?t=99702&start=2010#p877143
 
%You can get the text file MomentMatchParams08.txt from the forum post below
%https://forum.wilmott.com/viewtopic.php?f=4&t=99702&start=2040#p877863

Mtable=readtable('C:\Users\Lenovo\Documents\MATLAB\MATLAB1\MomentMatchParams08.txt');

%ZI is moment matched grid along the normal density with number of grid
%points equal to data elements in Y given by Ndata. The grid is constructed
%so that probability mass in each grid cell is 1/Ndata so this matches the
%observation probability of Ndata data elements. Due to equal probability
%mass in each grid cell, we call it equiprobable grid.

[ZI] = MatchMomentParametersOfIdealZhalf04(Ndata,Mtable);

Ys=sort(Y);
Ymu(1:Ndata,1)=Ys(1:Ndata);

W(1:Ndata,1)=1;
W(1:Ndata,2)=ZI(1:Ndata);
W(1:Ndata,3)=ZI(1:Ndata).^2;
W(1:Ndata,4)=ZI(1:Ndata).^3;
W(1:Ndata,5)=ZI(1:Ndata).^4;
W(1:Ndata,6)=ZI(1:Ndata).^5;
% W(1:Ndata,7)=ZI(1:Ndata).^6;
% W(1:Ndata,8)=ZI(1:Ndata).^7;


coeff=inv(W'*W)*(W'*Ymu);

%Above, we get coefficients of univariate Z-series of independent
%variable Y by least square regression.


a0=coeff(1,1);
a(1:5)=coeff(2:6,1);

%Above, we assign zeroth power Z-series coefficient to a0 and rest of
%the coefficients to array a.
%This was older format but we might need it since many old functions are written 
%in this format.

%Below, we assign same Z-series coefficients to a single array. This is
%newer format that we want to use mostly.
aa(1:6)=coeff(1:6);


%uncomment these lines if you want to see shape of Z-series constructed
%density of Y. We had calculated coefficients of this Z-series by
%least square polynomial regression.
%PlotZSeriesDensity(a0,a,'r')
%str=input("Look at the density of volatility");
    
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5    
%In this code block, we calcualate the coefficients of univariate marginal
%density of dependent variable X again by least square polynomial
%regression as we did in previous block for independent variable Y.
    
Xs=sort(X);
Xmu(1:Ndata,1)=Xs(1:Ndata);

W(1:Ndata,1)=1;
W(1:Ndata,2)=ZI(1:Ndata);
W(1:Ndata,3)=ZI(1:Ndata).^2;
W(1:Ndata,4)=ZI(1:Ndata).^3;
W(1:Ndata,5)=ZI(1:Ndata).^4;
W(1:Ndata,6)=ZI(1:Ndata).^5;

coeff=inv(W'*W)*(W'*Xmu);

c0=coeff(1,1);
c(1:5)=coeff(2:6,1);

cc(1:6)=coeff(1:6,1);

[ccH] = ConvertZSeriesToHermiteSeriesNew(cc,5);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

 [Zy] = CalculateZgivenXAndZSeriesC5Improved(Y,a0,a);
 [Zx] = CalculateZgivenXAndZSeriesC5Improved(X,c0,c);
% 
 paths=Ndata;
 [CorrH0] = CalculateCorrelationBivariateHermiteCH(Zx,Zy,paths,5);

Xdcorr(1:Ndata)=X(1:Ndata) ...
    -c(1).*CorrH0(1).*Zy(1:Ndata) ...
    -c(2).*CorrH0(2).*(Zy(1:Ndata).^2-1) ...
    -c(3).*CorrH0(3).*(Zy(1:Ndata).^3-3*Zy(1:Ndata)) ...
    -c(4).*CorrH0(4).*(Zy(1:Ndata).^4-6*Zy(1:Ndata)+3) ...
    -c(5).*CorrH0(5).*(Zy(1:Ndata).^5-10*Zy(1:Ndata).^3+15*Zy(1:Ndata));
    

[Xdcorrs,I]=sort(Xdcorr);
Zys=Zy(I);
Zx=ZI;
Xs=X(I);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


Xmu(1:Ndata,1)=Xs(1:Ndata);


W=0;

W(1:Ndata,1)=1.0;
W(1:Ndata,2)=Zx(1:Ndata);
W(1:Ndata,3)=(Zx(1:Ndata).^2-1);
W(1:Ndata,4)=(Zx(1:Ndata).^3-3*Zx(1:Ndata));
W(1:Ndata,5)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3);
W(1:Ndata,6)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata));

W(1:Ndata,7)=1.*Zys(1:Ndata);
W(1:Ndata,8)=Zx(1:Ndata).*Zys(1:Ndata);
W(1:Ndata,9)=(Zx(1:Ndata).^2-1).*Zys(1:Ndata);
W(1:Ndata,10)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*Zys(1:Ndata);
W(1:Ndata,11)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*Zys(1:Ndata);
W(1:Ndata,12)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata)).*Zys(1:Ndata);

W(1:Ndata,13)=(Zys(1:Ndata).^2-1);
W(1:Ndata,14)=Zx(1:Ndata).*(Zys(1:Ndata).^2-1);
W(1:Ndata,15)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^2-1);
W(1:Ndata,16)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^2-1);
W(1:Ndata,17)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^2-1);
W(1:Ndata,18)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata)).*(Zys(1:Ndata).^2-1);

W(1:Ndata,19)=(Zys(1:Ndata).^3-3*Zy(1:Ndata));
W(1:Ndata,20)=Zx(1:Ndata).*(Zys(1:Ndata).^3-3*Zy(1:Ndata));
W(1:Ndata,21)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^3-3*Zy(1:Ndata));
W(1:Ndata,22)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^3-3*Zys(1:Ndata));
W(1:Ndata,23)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^3-3*Zys(1:Ndata));
W(1:Ndata,24)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata)).*(Zys(1:Ndata).^3-3*Zys(1:Ndata));

W(1:Ndata,25)=(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
W(1:Ndata,26)=Zx(1:Ndata).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
W(1:Ndata,27)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
W(1:Ndata,28)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
W(1:Ndata,29)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
W(1:Ndata,30)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata)).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);

W(1:Ndata,31)=(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
W(1:Ndata,32)=Zx(1:Ndata).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
W(1:Ndata,33)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
W(1:Ndata,34)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
W(1:Ndata,35)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
W(1:Ndata,36)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata)).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));

coeff=inv(W'*W)*(W'*Xmu);


%bnmH0(1,1:6)=ccH(1:6);  %Replace first line of X-hermites with Marginal density retrieval condition
bnmH0(1,1:6)=coeff(1:6);
bnmH0(2,1:6)=coeff(7:12);
bnmH0(3,1:6)=coeff(13:18);
bnmH0(4,1:6)=coeff(19:24);
bnmH0(5,1:6)=coeff(25:30);
bnmH0(6,1:6)=coeff(31:36);

bnmH=bnmH0;





%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SeriesOrder1=6;
NMomentsY=6;
NMomentsX=6;
    for nn=1:NMomentsY
       for mm=1:NMomentsX
           CrossMoments(nn,mm)=0;
           for pp=1:Ndata
              CrossMoments(nn,mm)=CrossMoments(nn,mm)+Y(pp).^nn.*X(pp).^mm/Ndata;
           end
       end
    end



[chh] = ProduceFirstRowofConditioal2DZSeries02_6M_A(aa,SeriesOrder1,CrossMoments);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[bnm] = Convert2DHermitesInto2DSeries(bnmH);

SeriesOrder1=6;
SeriesOrder10=6;
SeriesOrder01=6;
NMomentsX=6;
NMomentsY=6;
[Moments2D0] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);

Moments2D0

CrossMoments

str=input("Look at comparison of moments--first-standardized");

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%In the code block below, we convert 2D hermite series coefficients of 
%dependent variable X from standardized version to original version.
%For that we first multiply the entire 2D Hermite series by square root of
%variance.

 bnmH=bnmH*sqrt(XmVar);

%We convert X from hermite series form to Z-series form.
[bnm] = Convert2DHermitesInto2DSeries(bnmH);
bnm(1,1)=MeanX-bnm(3,1)-3*bnm(5,1)-1*bnm(1,3)-1*3*bnm(1,5)-3*bnm(5,3)-bnm(3,3)-3*bnm(3,5)-9*bnm(5,5);

%Finally in above line, we make sure that mean of the 2D Z-series is


%Below, we convert Z-series of independent variable Y from standard form to
%original variable form.

aa=aa*sqrt(YmVar);
aa(1)=MeanY-aa(3)-3*aa(5);


 SeriesOrder1=6;
 SeriesOrder10=6;
 SeriesOrder01=6;
 NMomentsX=6;
 NMomentsY=6;
 [Moments2D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
 
 Moments2D
 
 CrossMoments11
 
 str=input("Look at comparison of moments");

end
You think life is a secret, Life is only love of flying, It has seen many ups and downs, But it likes travel more than the destination. Allama Iqbal
 
User avatar
Amin
Topic Author
Posts: 2586
Joined: July 14th, 2002, 3:00 am

Re: Breakthrough in the theory of stochastic differential equations and their simulation

February 21st, 2024, 7:14 pm

Friends, very sorry, I still have another error in the new regression algorithm.
While calculating uncorrelated part of X, I was multiplying correlations with Z-series coefficients. I had to multiply hermite series coefficients with correlations. This was an error and could be throwing results off in some cases.
Here is the corrected part

Xdcorr(1:Ndata)=X(1:Ndata) ...
    -ccH(2).*CorrH0(1).*Zy(1:Ndata) ...
    -ccH(3).*CorrH0(2).*(Zy(1:Ndata).^2-1) ...
    -ccH(4).*CorrH0(3).*(Zy(1:Ndata).^3-3*Zy(1:Ndata)) ...
    -ccH(5).*CorrH0(4).*(Zy(1:Ndata).^4-6*Zy(1:Ndata)+3) ...
    -ccH(6).*CorrH0(5).*(Zy(1:Ndata).^5-10*Zy(1:Ndata).^3+15*Zy(1:Ndata));

Here I am attaching the corrected function.
function [bnm,aa] = CalculateConditionalProbabilitiesYtoXLinearRegression04IterC(Yin,Xin)

%Yin argument translates to independent random variable Y
%Xin argument translates to dependent variable X.
%This function takes observations of an independent variable Y and
%dependent varaible X. These have to be joint observations in the sense
%that nth observation of Y, given by Y(n) is taken jointly with nth
%observation of X, given by X(n). Two arrays of observations are the same
%length and nth mmber of independent variable Y is jointly observed with nth
%member of depedent variable X.
%We want to find the detailed relationship between Y and X so we can get
%the conditional density of dependent variable X given a particular value
%of independent variable Y. This will be done by calibrating coefficients
%of our 2D hermite series to data so that a very good fit to cross moments
%between X and Y is retrieved.
%We will first find univariate Z-series/hermite series of both random
%variables independently. For joint dynamics of dependent variable given 
%te independnet variable, we will assume a 2D hermite series (This has to 
%be two dimensional to be able to capture the dynamics from independent variable Y
%and have its own dynamics) and form but we do not know the coefficients of 
%this 2D hermite series. In this program, we try to use iterative optimization 
%to find the unknown coefficients of 2D hermite series of dependent variable X 
%in a way that after taking products with independent varaible Y, expectation   
%of these products i.e cross moments are as exactly retrieved as possible.
%Our iterative optimization procedure perturbs each hermite coefficient in 
%2D hermite series  by a very slight amount and checks the objective function.
%If the objective function decreases, we eccept the perturbation otherwise
%reject it and then perturb by a small amount in other opposite direction
%and then again check the objective function. If perturbations in both sides 
%are rejected, we do not change the coefficients but slightly decrease the
%perturbation size. 
%We will first standardize the data of both random variables and then
%calculate univariate hermite series of both variables and also their 
%cross moments in standardized form. We do all the calculations of coefficients
%of independent variable Y and 2D dependent variable X
%in standardized version of variables and moments. After optimization of coefficents on 
%standardized data, at the end, we invert the standardization of both 
%dependent and independent variables appropriately to get the Z-series and
%hermite series of actual varaibles in theri original coordinates back from
%standardized coordinates.
%Before optimization, we place two conditions on 2D dependent variable X so that
%first row and first column of 2D hermite coefficents of X is already
%known before optimization stage and it is not changed in optimization. 
%We do not iteratively optimize over this first row and first colums
%which are analytically known from these two conditions.
%Our first condition is that after integration (of bivaraite density or
%alternatively bivaraite 2D Z-series/2D Hermite series) over independent
%variable, we should get the univaraite marginal density/Z-series/Hermite series of X
%which has already been calculated out of data. This fixes the zeroth
%hermite(of independent varaible Y) related terms in the Z-series/hermite series. 
%Please look at this forum post# 2121 for explanation of this first condition.
% https://forum.wilmott.com/viewtopic.php?t=99702&start=2115#p879042

%We can analytically solve for first order cross moments of X with higher
%order in Y. From the analytical solution of these moments, we find first
%row of coefficents in the hermite form.


% 2D Hermite Series Form used in this program is given as
% 
% X = bnmH(1,1) + bnmH(2,1) H_1(Z_y) + bnmH(3,1) H_2(Z_y) + bnmH(4,1) H_3(Z_y) + bnmH(5,1) H_4(Z_y) + bnmH(6,1) H_5(Z_y) 
% + [ bnmH(1,2) + bnmH(2,2) H_1(Z_y) + bnmH(3,2) H_2(Z_y) + bnmH(4,2) H_3(Z_y) + bnmH(5,2) H_4(Z_y) + bnmH(6,2) H_5(Z_y)] H_1(Zx) 
% + [ bnmH(1,3) + bnmH(2,3) H_1(Z_y) + bnmH(3,3) H_2(Z_y) + bnmH(4,3) H_3(Z_y) + bnmH(5,3) H_4(Z_y) + bnmH(6,3) H_5(Z_y)] H_2(Zx)
% + [ bnmH(1,4) + bnmH(2,4) H_1(Z_y) + bnmH(3,4) H_2(Z_y) + bnmH(4,4) H_3(Z_y) + bnmH(5,4) H_4(Z_y) + bnmH(6,4) H_5(Z_y)] H_3(Zx)
% + [ bnmH(1,5) + bnmH(2,5) H_1(Z_y) + bnmH(3,5) H_2(Z_y) + bnmH(4,5) H_3(Z_y) + bnmH(5,5) H_4(Z_y) + bnmH(6,5) H_5(Z_y)] H_4(Zx)
% + [ bnmH(1,6) + bnmH(2,6) H_1(Z_y) + bnmH(3,6) H_2(Z_y) + bnmH(4,6) H_3(Z_y) + bnmH(5,6) H_4(Z_y) + bnmH(6,6) H_5(Z_y)] H_5(Zx)
 
% 2D Z-Series Form used in this program is given as
% 
% X = bnm(1,1) + bnm(2,1) Z_y + bnm(3,1) (Z_y)^2 + bnm(4,1) (Z_y)^3 + bnm(5,1) (Z_y)^4 + bnm(6,1) (Z_y)^5 
% + [ bnm(1,2) + bnm(2,2) Z_y + bnm(3,2) (Z_y)^2 + bnm(4,2) (Z_y)^3 + bnm(5,2) (Z_y)^4 + bnm(6,2) (Z_y)^5 ] Zx 
% + [ bnm(1,3) + bnm(2,2) Z_y + bnm(3,3) (Z_y)^2 + bnm(4,3) (Z_y)^3 + bnm(5,3) (Z_y)^4 + bnm(6,3) (Z_y)^5 ] Zx^2 
% + [ bnm(1,4) + bnm(2,2) Z_y + bnm(3,4) (Z_y)^2 + bnm(4,4) (Z_y)^3 + bnm(5,4) (Z_y)^4 + bnm(6,4) (Z_y)^5 ] Zx^3 
% + [ bnm(1,5) + bnm(2,2) Z_y + bnm(3,5) (Z_y)^2 + bnm(4,5) (Z_y)^3 + bnm(5,5) (Z_y)^4 + bnm(6,5) (Z_y)^5 ] Zx^4 
% + [ bnm(1,6) + bnm(2,2) Z_y + bnm(3,6) (Z_y)^2 + bnm(4,6) (Z_y)^3 + bnm(5,6) (Z_y)^4 + bnm(6,6) (Z_y)^5 ] Zx^5




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%In the code block below, we standardize the independent variable Y and dependent variable X.
%We do all later calculations of various Z-series and cross moments in 
%standardized framework and then at the end of the program, we convert 
%the calculated coefficients of 2D hermite series/Z-series of dependent 
%variable X into original non-standardized framework.

 Ndata=length(Yin);
 
 MeanY=sum(Yin(1:Ndata))/Ndata;
 MeanX=sum(Xin(1:Ndata))/Ndata;
 
 Ym(1:Ndata)=Yin(1:Ndata)-MeanY;
 Xm(1:Ndata)=Xin(1:Ndata)-MeanX;
 
 YmVar=sum(Ym(1:Ndata).^2)/Ndata;
 XmVar=sum(Xm(1:Ndata).^2)/Ndata;
 
 Y(1:Ndata)=Ym(1:Ndata)/sqrt(YmVar);
 X(1:Ndata)=Xm(1:Ndata)/sqrt(XmVar);

 
 sqrt(YmVar)
 sqrt(XmVar)
 
 str=input("Look at standardization constants");
 

 NMomentsY=6;
 NMomentsX=6;
     for nn=1:NMomentsY
        for mm=1:NMomentsX
            CrossMoments11(nn,mm)=0;
            for pp=1:Ndata
               CrossMoments11(nn,mm)=CrossMoments11(nn,mm)+Yin(pp).^nn.*Xin(pp).^mm/Ndata;
               %CrossMoments11(nn,mm)=CrossMoments11(nn,mm)+Y(pp).^nn.*X(pp).^mm/Ndata;
               %CrossMoments11(nn,mm)=CrossMoments11(nn,mm)+Ym(pp).^nn.*Xm(pp).^mm/Ndata;
            end
        end
     end
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Code block below uses polynomial regression to find univariate Z-series 
%coefficients of independent variable Y.
%To know more about polynomial regression read the following and associated
%posts:  https://forum.wilmott.com/viewtopic.php?t=99702&start=2010#p877143
 
%You can get the text file MomentMatchParams08.txt from the forum post below
%https://forum.wilmott.com/viewtopic.php?f=4&t=99702&start=2040#p877863

Mtable=readtable('C:\Users\Lenovo\Documents\MATLAB\MATLAB1\MomentMatchParams08.txt');

%ZI is moment matched grid along the normal density with number of grid
%points equal to data elements in Y given by Ndata. The grid is constructed
%so that probability mass in each grid cell is 1/Ndata so this matches the
%observation probability of Ndata data elements. Due to equal probability
%mass in each grid cell, we call it equiprobable grid.

[ZI] = MatchMomentParametersOfIdealZhalf04(Ndata,Mtable);

Ys=sort(Y);
Ymu(1:Ndata,1)=Ys(1:Ndata);

W(1:Ndata,1)=1;
W(1:Ndata,2)=ZI(1:Ndata);
W(1:Ndata,3)=ZI(1:Ndata).^2;
W(1:Ndata,4)=ZI(1:Ndata).^3;
W(1:Ndata,5)=ZI(1:Ndata).^4;
W(1:Ndata,6)=ZI(1:Ndata).^5;
% W(1:Ndata,7)=ZI(1:Ndata).^6;
% W(1:Ndata,8)=ZI(1:Ndata).^7;


coeff=inv(W'*W)*(W'*Ymu);

%Above, we get coefficients of univariate Z-series of independent
%variable Y by least square regression.


a0=coeff(1,1);
a(1:5)=coeff(2:6,1);

%Above, we assign zeroth power Z-series coefficient to a0 and rest of
%the coefficients to array a.
%This was older format but we might need it since many old functions are written 
%in this format.

%Below, we assign same Z-series coefficients to a single array. This is
%newer format that we want to use mostly.
aa(1:6)=coeff(1:6);


%uncomment these lines if you want to see shape of Z-series constructed
%density of Y. We had calculated coefficients of this Z-series by
%least square polynomial regression.
%PlotZSeriesDensity(a0,a,'r')
%str=input("Look at the density of volatility");
    
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5    
%In this code block, we calcualate the coefficients of univariate marginal
%density of dependent variable X again by least square polynomial
%regression as we did in previous block for independent variable Y.
    
Xs=sort(X);
Xmu(1:Ndata,1)=Xs(1:Ndata);

W(1:Ndata,1)=1;
W(1:Ndata,2)=ZI(1:Ndata);
W(1:Ndata,3)=ZI(1:Ndata).^2;
W(1:Ndata,4)=ZI(1:Ndata).^3;
W(1:Ndata,5)=ZI(1:Ndata).^4;
W(1:Ndata,6)=ZI(1:Ndata).^5;

coeff=inv(W'*W)*(W'*Xmu);

c0=coeff(1,1);
c(1:5)=coeff(2:6,1);

cc(1:6)=coeff(1:6,1);

[ccH] = ConvertZSeriesToHermiteSeriesNew(cc,5);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

 [Zy] = CalculateZgivenXAndZSeriesC5Improved(Y,a0,a);
 [Zx] = CalculateZgivenXAndZSeriesC5Improved(X,c0,c);
% 
 paths=Ndata;
 [CorrH0] = CalculateCorrelationBivariateHermiteCH(Zx,Zy,paths,5);

Xdcorr(1:Ndata)=X(1:Ndata) ...
    -ccH(2).*CorrH0(1).*Zy(1:Ndata) ...
    -ccH(3).*CorrH0(2).*(Zy(1:Ndata).^2-1) ...
    -ccH(4).*CorrH0(3).*(Zy(1:Ndata).^3-3*Zy(1:Ndata)) ...
    -ccH(5).*CorrH0(4).*(Zy(1:Ndata).^4-6*Zy(1:Ndata)+3) ...
    -ccH(6).*CorrH0(5).*(Zy(1:Ndata).^5-10*Zy(1:Ndata).^3+15*Zy(1:Ndata));
    

[Xdcorrs,I]=sort(Xdcorr);
Zys=Zy(I);
Zx=ZI;
Xs=X(I);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


Xmu(1:Ndata,1)=Xs(1:Ndata);


W=0;

W(1:Ndata,1)=1.0;
W(1:Ndata,2)=Zx(1:Ndata);
W(1:Ndata,3)=(Zx(1:Ndata).^2-1);
W(1:Ndata,4)=(Zx(1:Ndata).^3-3*Zx(1:Ndata));
W(1:Ndata,5)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3);
W(1:Ndata,6)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata));

W(1:Ndata,7)=1.*Zys(1:Ndata);
W(1:Ndata,8)=Zx(1:Ndata).*Zys(1:Ndata);
W(1:Ndata,9)=(Zx(1:Ndata).^2-1).*Zys(1:Ndata);
W(1:Ndata,10)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*Zys(1:Ndata);
W(1:Ndata,11)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*Zys(1:Ndata);
W(1:Ndata,12)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata)).*Zys(1:Ndata);

W(1:Ndata,13)=(Zys(1:Ndata).^2-1);
W(1:Ndata,14)=Zx(1:Ndata).*(Zys(1:Ndata).^2-1);
W(1:Ndata,15)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^2-1);
W(1:Ndata,16)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^2-1);
W(1:Ndata,17)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^2-1);
W(1:Ndata,18)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata)).*(Zys(1:Ndata).^2-1);

W(1:Ndata,19)=(Zys(1:Ndata).^3-3*Zy(1:Ndata));
W(1:Ndata,20)=Zx(1:Ndata).*(Zys(1:Ndata).^3-3*Zy(1:Ndata));
W(1:Ndata,21)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^3-3*Zy(1:Ndata));
W(1:Ndata,22)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^3-3*Zys(1:Ndata));
W(1:Ndata,23)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^3-3*Zys(1:Ndata));
W(1:Ndata,24)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata)).*(Zys(1:Ndata).^3-3*Zys(1:Ndata));

W(1:Ndata,25)=(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
W(1:Ndata,26)=Zx(1:Ndata).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
W(1:Ndata,27)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
W(1:Ndata,28)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
W(1:Ndata,29)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);
W(1:Ndata,30)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata)).*(Zys(1:Ndata).^4-6*Zys(1:Ndata).^2+3);

W(1:Ndata,31)=(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
W(1:Ndata,32)=Zx(1:Ndata).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
W(1:Ndata,33)=(Zx(1:Ndata).^2-1).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
W(1:Ndata,34)=(Zx(1:Ndata).^3-3*Zx(1:Ndata)).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
W(1:Ndata,35)=(Zx(1:Ndata).^4-6*Zx(1:Ndata).^2+3).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));
W(1:Ndata,36)=(Zx(1:Ndata).^5-10*Zx(1:Ndata).^3+15*Zx(1:Ndata)).*(Zys(1:Ndata).^5-10*Zys(1:Ndata).^3+15*Zys(1:Ndata));

coeff=inv(W'*W)*(W'*Xmu);


%bnmH0(1,1:6)=ccH(1:6);  %Replace first line of X-hermites with Marginal density retrieval condition
bnmH0(1,1:6)=coeff(1:6);
bnmH0(2,1:6)=coeff(7:12);
bnmH0(3,1:6)=coeff(13:18);
bnmH0(4,1:6)=coeff(19:24);
bnmH0(5,1:6)=coeff(25:30);
bnmH0(6,1:6)=coeff(31:36);

bnmH=bnmH0;





%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SeriesOrder1=6;
NMomentsY=6;
NMomentsX=6;
    for nn=1:NMomentsY
       for mm=1:NMomentsX
           CrossMoments(nn,mm)=0;
           for pp=1:Ndata
              CrossMoments(nn,mm)=CrossMoments(nn,mm)+Y(pp).^nn.*X(pp).^mm/Ndata;
           end
       end
    end



[chh] = ProduceFirstRowofConditioal2DZSeries02_6M_A(aa,SeriesOrder1,CrossMoments);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[bnm] = Convert2DHermitesInto2DSeries(bnmH);

SeriesOrder1=6;
SeriesOrder10=6;
SeriesOrder01=6;
NMomentsX=6;
NMomentsY=6;
[Moments2D0] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);

Moments2D0

CrossMoments

str=input("Look at comparison of moments--first-standardized");

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%In the code block below, we convert 2D hermite series coefficients of 
%dependent variable X from standardized version to original version.
%For that we first multiply the entire 2D Hermite series by square root of
%variance.

 bnmH=bnmH*sqrt(XmVar);

%We convert X from hermite series form to Z-series form.
[bnm] = Convert2DHermitesInto2DSeries(bnmH);
bnm(1,1)=MeanX-bnm(3,1)-3*bnm(5,1)-1*bnm(1,3)-1*3*bnm(1,5)-3*bnm(5,3)-bnm(3,3)-3*bnm(3,5)-9*bnm(5,5);

%Finally in above line, we make sure that mean of the 2D Z-series is


%Below, we convert Z-series of independent variable Y from standard form to
%original variable form.

aa=aa*sqrt(YmVar);
aa(1)=MeanY-aa(3)-3*aa(5);


 SeriesOrder1=6;
 SeriesOrder10=6;
 SeriesOrder01=6;
 NMomentsX=6;
 NMomentsY=6;
 [Moments2D] = CalculateCrossMomentsConditional2DNew02(aa,bnm,SeriesOrder1,SeriesOrder10,SeriesOrder01,NMomentsX,NMomentsY);
 
 Moments2D
 
 CrossMoments11
 
 str=input("Look at comparison of moments");

end
You think life is a secret, Life is only love of flying, It has seen many ups and downs, But it likes travel more than the destination. Allama Iqbal
 
User avatar
Amin
Topic Author
Posts: 2586
Joined: July 14th, 2002, 3:00 am

Re: Breakthrough in the theory of stochastic differential equations and their simulation

February 23rd, 2024, 10:37 am

Friends, I took some time off a day ago. I have been thinking hard about the problem. And I am inclined to think that there could be an analytical solution to the problem. I have to take a few hours off since I have run out of my supply of water and I have to go into the city to buy water and food. I want to do calculations on paper tonight and will let friends how it goes after that. I hope that we may be able to find an analytical solution to the problem but let us see how it goes.
You think life is a secret, Life is only love of flying, It has seen many ups and downs, But it likes travel more than the destination. Allama Iqbal