I have a function dφ/dt = γ - F(φ) (where F(φ) -- a is 2π-periodic function) and the graph of the function F(φ).
I need to create a program that outputs 6 plots of φ(t) for different values of γ (γ = 0.1, 0.5, 0.95, 1.05, 2, 5), and t∈[0,100].
Here is the definition of the F(φ) function:
-φ/a - π/a, if φ ∈ [-π, -π + a]
-1, if φ ∈ [-π + a, - a]
F(φ) = φ/a, if φ ∈ [- a, a]
1, if φ ∈ [a, π - a]
-φ/a + π/a, if φ ∈ [π - a, π]
^ F(φ)
|
|1 ______
| /| \
| / | \
| / | \ φ
__-π_______-a____|/___|________\π____>
\ | /|0 a
\ | / |
\ | / |
\ |/ |
¯¯¯¯¯¯ |-1
My problem is I don't know what inputs to give ode45 in terms of the bounds and the initial condition. What I do know is that the evolution of φ(t) must be continuous.
This is the code for case of γ = 0.1:
hold on;
df1dt = #(t,f1) 0.1 - f1 - 3.14;
df2dt = #(t,f2)- 1;
df3dt = #(t,f3) 0.1 + f3;
df4dt = #(t,f4)+1;
df5dt = #(t,f5) 0.1 - f5 + 3.14;
[T1,Y1] = ode45(df1dt, ...);
[T2,Y2] = ode45(df2dt, ...);
[T3,Y3] = ode45(df3dt, ...);
[T4,Y4] = ode45(df4dt, ...);
[T5,Y5] = ode45(df5dt, ...);
plot(T1,Y1);
plot(T2,Y2);
plot(T3,Y3);
plot(T4,Y4);
plot(T5,Y5);
hold off;
title('\gamma = 0.1')
Let us first define F(φ,a):
function out = F(p, a)
phi = mod(p,2*pi);
out = (0 <= phi & phi < a ).*(phi/a) ...
+ (a <= phi & phi < pi-a ).*(1) ...
+ (pi-a <= phi & phi < pi+a ).*(-phi/a + pi/a) ...
+ (pi+a <= phi & phi < 2*pi-a).*(-1) ...
+ (2*pi-a <= phi & phi < 2*pi ).*(phi/a - 2*pi/a);
end
Which for some example inputs gives:
using the plotting code:
x = linspace(-3*pi, 3*pi, 200);
a = pi/6;
figure(); plot(x,F(x, a));
xlim([-3*pi,3*pi]);
xticks(-3*pi:pi:3*pi);
xticklabels((-3:3)+ "\pi");
grid on; grid minor
ax = gca;
ax.XAxis.MinorTick = 'on';
ax.XAxis.MinorTickValues = ax.XAxis.Limits(1):pi/6:ax.XAxis.Limits(2);
From there you don't need to bother with the ranges anymore, and simply call ode45:
% Preparations:
a = pi/6;
g = [0.1, 0.5, 0.95, 1.05, 2, 5]; % γ
phi0 = 0; % you need to specify the correct initial condition (!)
tStart = 0;
tEnd = 100;
% Calling the solver:
[t, phi] = arrayfun(#(x)ode45(#(t,p)x-F(p,a), [tStart, tEnd], phi0), g, 'UniformOutput', false);
% Plotting:
plotData = [t; phi];
figure(); plot(plotData{:});
legend("γ=" + g, 'Location', 'northwest');
Resulting in:
I am experiencing some struggles in solving a system of 4 equations with 4 unknows. The equations are non-linear and contain a bivariate normal cumulative distribution function. I tried multiple numerical optimization packages (fmincon, fminsearch, fsolve,..) but they all return the 'simple solution' of L = 1, sigma_A = 0, alpha1 = 1 and alpha2=1. Which is not a realistic solution. I would expect L to be in the range of 0.1 to 0.95, and siga_A to be nonzero.
Many thanks in advance
function [L_t,sig_A,s,p,DTD] = Hull_Clean(Impl_Vol1, Impl_Vol2, tau1, tau2, Px_Last1, Px_Last2, STRIKE1, STRIKE2,t,T,r)
%Impl_Vol1=0.21; Impl_Vol2=0.31; tau1=30/252; tau2=30/252; Px_Last1=76.16; Px_Last2=76.16; STRIKE1=70; STRIKE2=65;t=0;T=5;r=0.03;
%% RESHAPE VARIABLES TO 3D TO FACILITATE MATRIXWISE BIVAR NEWTON-REPHSON
[n,m] = size(Impl_Vol1);
nm = n*m;
Impl_Vol1 = reshape(Impl_Vol1,1,1,nm); Impl_Vol2 = reshape(Impl_Vol2,1,1,nm); STRIKE1 = reshape(STRIKE1,1,1,nm); STRIKE2 = reshape(STRIKE2,1,1,nm);
tau1 = reshape(tau1,1,1,nm); tau2 = reshape(tau2,1,1,nm); Px_Last1 = reshape(Px_Last1,1,1,nm); Px_Last2 = reshape(Px_Last2,1,1,nm);
%% Calculate known variables CONTROLEER ALLES NOG, OOK MET GESKE 1979 ARTIKEL OP CORRECTHEID FORMULES!!!!
Kappa1 = STRIKE1 .* exp(-r .* tau1) ./ Px_Last1; % GEBRUIK ALTIJD STRIKE EN Px_Last per stock of hele bedrijf
Kappa2 = STRIKE2 .* exp(-r .* tau2) ./ Px_Last2;
d1_star1 = (-log(Kappa1) ./ (Impl_Vol1 .* sqrt(tau1))) + (0.5 .* Impl_Vol1 .* sqrt(tau1)); d2_star1 = d1_star1 - (Impl_Vol1 .* sqrt(tau1));
d1_star2 = (-log(Kappa2) ./ (Impl_Vol2 .* sqrt(tau2))) + (0.5 .* Impl_Vol2 .* sqrt(tau2)); d2_star2 = d1_star2 - (Impl_Vol2 .* sqrt(tau2));
FNN1 = (Kappa1 .* fcnN(-d2_star1)) - fcnN(-d1_star1);
FNN2 = (Kappa2 .* fcnN(-d2_star2)) - fcnN(-d1_star2);
%% Define functions of unknown variables
d1 = #(L_t,sig_A,C)((1./(sig_A(:,:,C).*sqrt(T(:,:,C)-t))).*(-log(L_t(:,:,C)) + ((0.5.*sig_A(:,:,C).^2).*(T(:,:,C)-t))));
d2 = #(L_t,sig_A,C)((1./(sig_A(:,:,C).*sqrt(T(:,:,C)-t))).*(-log(L_t(:,:,C)) - ((0.5.*sig_A(:,:,C).^2).*(T(:,:,C)-t))));
a1 = #(alpha, sig_A, tau, C)((1./(sig_A(:,:,C).*sqrt(tau(:,:,C)-t))).*(-log(alpha(:,:,C)) + ((0.5.*sig_A(:,:,C).^2).*(tau(:,:,C)-t)))); % MOETEN HIER ZEKER - en + zo? ?CHECK
a2 = #(alpha, sig_A, tau, C)((1./(sig_A(:,:,C).*sqrt(tau(:,:,C)-t))).*(-log(alpha(:,:,C)) - ((0.5.*sig_A(:,:,C).^2).*(tau(:,:,C)-t))));
d1_tau = #(L_t, alpha, sig_A, tau, C)((1./(sig_A(:,:,C).*sqrt(T(:,:,C)-tau(:,:,C)))).*(-log(L_t(:,:,C) ./ alpha(:,:,C)) + ((0.5.*sig_A(:,:,C).^2).*(T(:,:,C)-tau(:,:,C)))));
d2_tau = #(L_t, alpha, sig_A, tau, C)((1./(sig_A(:,:,C).*sqrt(T(:,:,C)-tau(:,:,C)))).*(-log(L_t(:,:,C) ./ alpha(:,:,C)) - ((0.5.*sig_A(:,:,C).^2).*(T(:,:,C)-tau(:,:,C)))));
%% System of nonlinear equations
Eq1 = #(L_t, sig_A, alpha, tau, C)(((alpha.*fcnN(d1_tau(L_t, alpha, sig_A, tau, C))) - (L_t(:,:,C).*fcnN(d2_tau(L_t, alpha, sig_A, tau, C)) )...
)./(fcnN(d1(L_t,sig_A,C))-(L_t(:,:,C).*fcnN(d2(L_t,sig_A,C)) ))); % Of -1 kappa hier zodat hij == 0 kan solven?
Eq1_1 = #(L_t, sig_A, alpha1, C)((((alpha1(:,:,C).*fcnN(d1_tau(L_t, alpha1, sig_A, tau1, C))) - (L_t(:,:,C).*fcnN(d2_tau(L_t, alpha1, sig_A, tau1, C)) )...
)./(fcnN(d1(L_t,sig_A,C))-(L_t(:,:,C).*fcnN(d2(L_t,sig_A,C)) ))) - Kappa1(:,:,C)) ;
Eq1_2 = #(L_t, sig_A, alpha2, C)((((alpha2(:,:,C).*fcnN(d1_tau(L_t, alpha2, sig_A, tau2, C))) - (L_t(:,:,C).*fcnN(d2_tau(L_t, alpha2, sig_A, tau2, C)) )...
)./(fcnN(d1(L_t,sig_A,C))-(L_t(:,:,C).*fcnN(d2(L_t,sig_A,C)) ))) - Kappa2(:,:,C)) ;
Eq2_1 = #(L_t, sig_A, alpha1, C)(((L_t(:,:,C)*fcnM(-a2(alpha1, sig_A, tau1, C),d2(L_t,sig_A,C), - sqrt(tau1(:,:,C) ./ T(:,:,C)) )) - ...
fcnM(-a1(alpha1, sig_A, tau1, C), d1(L_t,sig_A,C), - sqrt(tau1(:,:,C) ./T(:,:,C))) + ...
(Kappa1(:,:,C) .* fcnN(-a2(alpha1, sig_A, tau1, C)) .* (fcnN(d1(L_t, sig_A, C)) - (L_t(:,:,C).*fcnN(d2(L_t, sig_A,C))) ))) - ...
(FNN1(:,:,C) .* (fcnN(d1(L_t, sig_A, C)) - (L_t(:,:,C).*fcnN(d2(L_t, sig_A,C))) ) )) ;
Eq2_2 = #(L_t, sig_A, alpha2, C)(((L_t(:,:,C)*fcnM(-a2(alpha2, sig_A, tau2, C),d2(L_t,sig_A,C), - sqrt(tau2(:,:,C) ./ T(:,:,C)) )) - ...
fcnM(-a1(alpha2, sig_A, tau2, C), d1(L_t,sig_A,C), - sqrt(tau2(:,:,C) ./T(:,:,C))) + ...
(Kappa1(:,:,C) .* fcnN(-a2(alpha2, sig_A, tau2, C)) .* (fcnN(d1(L_t, sig_A, C)) - (L_t(:,:,C).*fcnN(d2(L_t, sig_A,C))) ))) - ...
(FNN2(:,:,C) .* (fcnN(d1(L_t, sig_A, C)) - (L_t(:,:,C).*fcnN(d2(L_t, sig_A,C))) ) )) ;
%% Solve system on non linearr equiations
opts = optimset('tolfun',0,'tolx',0,'maxfun',Inf);
opts=optimset('Algorithm','Levenberg-Marquardt');
x0 = [0.1, 0.5 ,0.8,0.9];
fun = #(x)[Eq1_1(x(1), x(2), x(3), true); Eq1_2(x(1), x(2), x(4), true); Eq2_1(x(1), x(2), x(3), true); Eq2_2(x(1), x(2), x(4), true)];
[VALUES,fval] = fsolve(fun, x0, opts)
L_t = VALUES(1); sig_A = VALUES(2); alpha1 = VALUES(3); alpha2 = VALUES(4);
%% SOLVE FOR CREDIT SPREAD [s]
d1 = #(L_t,sig_A,C)((1/(sig_A *sqrt(T -t)))*(-log(L_t ) + ((0.5*sig_A^2)*(T -t))));
d2 = #(L_t,sig_A,C)((1/(sig_A *sqrt(T -t)))*(-log(L_t ) - ((0.5*sig_A^2)*(T -t))));
s = - log(fcnN(d2(L_t, sig_A, true)) + (fcnN(-d1(L_t, sig_A, true)) / L_t)) / (T - t);
p = fcnN(-d2(L_t,sig_A,true)); % P(A_t < K) = N(-d_m)
DTD = d2(L_t,sig_A,true);
end
%
%% SUBFUNCTIONS
function p=fcnN(x)
p=0.5*(1.+erf(x/sqrt(2)));
end
%
function p=fcnn(x)
p=exp(-0.5*x^2)/sqrt(2*pi);
end
function Y = inv3d(X)
Y = -X;
Y(2,2,:) = X(1,1,:);
Y(1,1,:) = X(2,2,:);
detMat = 1/(X(1,1,:)*X(2,2,:) - X(1,2,:)*X(2,1,:));
detMat = detMat(ones(1,2),ones(2,1),:);
Y = detMat*Y;
end
function p=fcnM(a,b,rho)
X = [a;b];
mu = [0;0];
sigma = [1, rho; rho, 1];
p = mvncdf(X,mu,sigma);
end
function p=fcnM1(a,b,rho)
if(a <= 0 && b <= 0 && rho <= 0)
aprime = a/(sqrt(2*(1-(rho^2))));
bprime = b/(sqrt(2*(1-(rho^2))));
A = [0.3253030 0.4211071 0.1334425 0.006374323];
B = [0.1337764 0.6243247 1.3425378 2.2626645];
F = 'exp(aprime*(2*x - aprime)+ (bprime*(2*y - bprime)) + (2*rho *(x - aprime)*(y-bprime)))';
t = 0;
for i=1:4
for j=1:4
x = B(i);
y = B(j);
t = t + A(i)*A(j)*eval(F);
end
end
p = (sqrt(1-rho^2)/pi) * t;
elseif (a * b * rho <= 0)
if (a <=0 && b >=0 && rho >=0)
p = normcdf(a) - fcnM1(a,-b,-rho);
elseif (a >=0 && b <=0 && rho >=0)
p = normcdf(b) - fcnM1(-a,b,-rho);
elseif (a >=0 && b >=0 && rho <=0) %modified here at 1:45 AM
p = normcdf(a) + normcdf(b) - 1 + fcnM1(-a,-b,rho);
end
elseif a*b*rho > 0;
%Could not use the In-Built function sign(x) because it is +1 if x>=0
%not just x>0 as in Matlab.
if(a >= 0),
asign =1 ;
else
asign = -1;
end
if(b >= 0),
bsign =1 ;
else
bsign = -1;
end
rho1 = (rho*a - b)*asign/(sqrt(a^2 - (2*rho*a*b) + b^2));
rho2 = (rho*b - a)*bsign/(sqrt(a^2 - (2*rho*a*b) + b^2));
delta = (1-(asign*bsign))/4;
p = fcnM1(a,0,rho1) + fcnM1(b,0,rho2) - delta ;
end
end
Use lsqnonlin since your function output is a scalar
Let sigma_A be a free variable
sigma_A_lb = -inf; sigma_A_ub = inf
The code is as follow
% Given initials
Impl_Vol1=0.21; Impl_Vol2=0.31; tau1=30/252; tau2=30/252; Px_Last1=76.16; Px_Last2=76.16; STRIKE1=70; STRIKE2=65;t=0;T=5;r=0.03;
% Change this section
x0 = [0.1, 0.02 ,0.8,0.9];
lb = [0.1, -inf, 0, 0];
ub = [0.98, inf, inf, inf];
fun = #(x)[Eq1_1(x(1), x(2), x(3), true); Eq1_2(x(1), x(2), x(4), true); Eq2_1(x(1), x(2), x(3), true); Eq2_2(x(1), x(2), x(4), true)];
options = optimoptions('lsqnonlin','FunctionTolerance',1e-10);
[VALUES,fval] = lsqnonlin(fun,x0,lb,ub, options) ;
Result
VALUES =
|-------------------------------------|
| L | sigma_A| alpha1 | alpha2 |
|-------------------------------------|
|0.9757 | 0.0052 | 0.9979 | 0.9963|
|-------------------------------------|
fval =
8.5170e-10
Checking with conditions given in comments
% Initial conditions given in comments
x0 = [0.1, 0.1 ,0.8,0.9];
lb = [0.1, -inf, 0, 0];
ub = [0.98, inf, inf, inf];
Result
VALUES =
|-------------------------------------|
| L | sigma_A| alpha1 | alpha2 |
|-------------------------------------|
|0.8770 | 0.0265 | 0.9895 | 0.9813|
|-------------------------------------|
fval =
2.2257e-08
I make a square around/below a given point with given width (w) and length (l) like shown below
But now I have to induce the direction of the point (or heading so to say). I want to create a rectangle directed towards that direction like shown below. I have never worked with headings before, if anyone can point me in the right directions, that would be helpful.
-----------------EDIT---------------
Thank you #MBo & #HansHirse, I implemented as suggested by your people. for simplicity, I chose the point to be on the top line of the rectangle rather to be away from the rectangle. my code is as shown below:
% Point coordinates
P = [5; 5];
% Direction vector
d = [1; -5];
%normalizing
Len = sqrt(d(1)*d(1)+d(2)*d(2));
cs = d(1)/Len;
sn = d(2)/Len;
% Dimensions of rectangle
l = 200;
w = 100;
% Original corner points of rectangle
x1 = P(1) -w/2;
y1 = P(2);
x2 = P(1)+ w/2;
y2 = P(2);
x3 = P(1)+ w/2;
y3 = P(2) - l;
x4 = P(1) -w/2;
y4 = P(2) - l;
rect = [x1 x2 x3 x4; y1 y2 y3 y4];
%rotated rectangles coordinates:
x1_new = P(1)+ (x1 - P(1))* cs - (y1 - P(2))*sn;
y1_new = P(2) +(x1-P(1))*sn + (y1-P(2))*cs;
x2_new = P(1)+ (x2 - P(1))* cs - (y2 - P(2))*sn;
y2_new = P(2) +(x2-P(1))*sn + (y2-P(2))*cs;
x3_new = P(1)+ (x3 - P(1))* cs - (y3 - P(2))*sn;
y3_new = P(2) +(x3-P(1))*sn + (y3-P(2))*cs;
x4_new = P(1)+ (x4 - P(1))* cs - (y4 - P(2))*sn;
y4_new = P(2) +(x4-P(1))*sn + (y4-P(2))*cs;
new_rect = [x1_new x2_new x3_new x4_new; y1_new y2_new y3_new y4_new];
%plot:
figure(1);
plot(P(1), P(2), 'k.', 'MarkerSize', 21);
hold on;
plot([P(1) P(1)+d(1)*10], [P(2) P(2)+d(2)*10], 'b');
patch(new_rect(1,:),new_rect(2,:), 'b', 'FaceAlpha', 0.2);
patch(rect(1,:),rect(2,:),'b')
hold off
The way it is rotating is not what I wanted: I am not able to upload a pic, imgur is acting weird. You can run the exact code, you will get the output I am getting.
So you have point P, and rectangle R (defined by coordinates).
Now you want to rotate rectangle by angle A around point P (as far as I understand)
New coordinates for every vertex are:
NewV[i].X = P.X + (V[i].X - P.X) * Cos(A) - (V[i].Y - P.Y) * Sin(A)
NewV[i].Y = P.Y + (V[i].X - P.X) * Sin(A) + (V[i].Y - P.Y) * Cos(A)
If you have direction vector D = [d1, d2], you don't need to operate with sin and cos functions: just exploit components of normalized vector (perhaps matlab contains function for normalizing):
Len = magnitude(D) = sqrt(d1*d1+d2*d2)
//normalized (unit vector)
dx = d1 / Len
dy = d2 / Len
NewV[i].X = P.X + (V[i].X - P.X) * dx - (V[i].Y - P.Y) * dy
NewV[i].Y = P.Y + (V[i].X - P.X) * dy + (V[i].Y - P.Y) * dx
Also you can omit creating coordinates of axis-aligned rectangle and calculate vertices immediately (perhaps more possibilities for mistakes)
//unit vector perpendicula to direction
perpx = - dy
perpy = dx
V[0].X = P.X - dist * dx + w/2 * perpx
V[1].X = P.X - dist * dx - w/2 * perpx
V[2].X = P.X - dist * dx - w/2 * perpx - l * dx
V[3].X = P.X - dist * dx + w/2 * perpx - l * dx
and similar for y-components
The general concept was already mentioned in MBo's answer. Nevertheless, since I was working on some code, here is my solution:
% Point coordinates
P = [5; 5];
% Direction vector
d = [1; -5];
% Dimensions of rectangle
l = 200;
w = 100;
% Distance P <-> rectangle
dist = 20;
% Determine rotation angle from direction vector
% (Omitting handling of corner/extreme cases, e.g. d(2) = 0)
theta = atand(d(1) / d(2));
if ((d(1) > 0) && (d(2) < 0))
theta = theta + 180;
elseif ((d(1) < 0) && (d(2) < 0))
theta = theta - 180;
end
% Original corner points of rectangle
xMin = P(1) - w/2;
xMax = P(1) + w/2;
yMin = P(2) - dist;
yMax = P(2) - dist - l;
rect = [xMin xMax xMax xMin; yMin yMin yMax yMax];
% Auxiliary matrix for rotation
center = repmat(P, 1, 4);
% Rotation matrix
R = [cosd(-theta) -sind(-theta); sind(-theta) cosd(-theta)];
% Rotation
rotrect = (R * (rect - center)) + center;
% Plot
figure(1);
hold on;
plot(P(1), P(2), 'k.', 'MarkerSize', 21); % Point
plot([P(1) P(1)+d(1)*10], [P(2) P(2)+d(2)*10], 'b'); % Direction vector
patch(rect(1, :), rect(2, :), 'b', 'FaceAlpha', 0.2); % Original rectangle
patch(rotrect(1, :), rotrect(2, :), 'b'); % Rotated rectangle
hold off;
xlim([-250 250]);
ylim([-250 250]);
This will produce an output image like this:
Caveat: In my rotation matrix R, you'll find -theta, since the way, how theta was determined is just some simple approach. This might be improved, so that R could also be set up properly.