integral2Calc>integral2t/tensor & Warning: Reached the maximum number of function evaluations (10000) - matlab

I am trying to do a set of integrations for a particular value of psi and theta. These integrations are then combined into a formula to give P. The idea is then to do this for a set of psi and theta from 0 to pi/2 and then plot the results of P against a function of theta and psi.
I get two errors, firstly
integral2Calc>integral2t/tensor
not sure how to change the integral to make it the right dimensions to psi no longer being a scalar.
I also get Warning: Reached the maximum number of function evaluations (10000) for i3, is this a serious error, (as in has the integration not been computed) I tried changing the type of integration or changing the error tolerance and this seemed to have no effect on removing the actual error..
eta = input('Enter Dielectric Constant 1.5-4: ');
sdev = input('Enter STD DEV (roughness) maybe 0.1: ');
psi = [0:0.01:pi/2];
theta = [0:0.01:pi/2];
r = sqrt((sin(psi)).^2+(sin(theta).*(cos(psi))).^2);
calpha = (cos(theta+dtheta)).*(cos(psi+dpsi));
rp01 = calpha-sqrt(eta-1+((calpha).^2));
rp02 = calpha+sqrt(eta-1+((calpha).^2));
rperp = (rp01./rp02).^2;
rp11 = ((eta.*calpha)-sqrt(eta-1+((calpha).^2)));
rp12 = ((eta.*calpha)+sqrt(eta-1+((calpha).^2)));
rpar = (rp11./rp12).^2;
qthingy1 = ((sin(psi+dpsi)).^2)-((sin(theta+dtheta)).^2).*((cos(psi+dpsi)).^2);
qthingy2 = ((sin(psi+dpsi)).^2)+((sin(theta+dtheta)).^2).*((cos(psi+dpsi)).^2);
qthingy = qthingy1./qthingy2;
wthingy1 = (sin(2*(psi+dpsi))).*(sin(theta+dtheta));
wthingy2 = ((sin(psi+dpsi)).^2)+(sin((theta+dtheta)).^2).*((sin(psi+dpsi)).^2);
wthingy = wthingy1./wthingy2;
roughness = (cos(psi)./(2*pi*(sdev.^2))).*exp(-((cos(psi).*dtheta).^2+(dpsi).^2)/(2*sdev.^2));
fun = matlabFunction((rpar+rperp).*roughness,'vars',{dtheta,dpsi});
fun2 = matlabFunction(roughness,'vars',{dtheta,dpsi});
fun3 = matlabFunction((rpar+rperp).*roughness.*qthingy,'vars',{dtheta,dpsi});
fun4 = matlabFunction((rpar+rperp).*roughness.*wthingy,'vars',{dtheta,dpsi});
thetamax = (pi/2) - theta;
psimax = (pi/2) - psi;
A = integral2(fun2,-pi/2,pi/2,-pi/2,pi/2);
i1 = (integral2(fun,-pi/2,thetamax,-pi/2,psimax))./A;
q = 2 - i1;
i2 = (integral2(fun3,-pi/2,thetamax,-pi/2,psimax))./A;
i3 = (integral2(fun4,-pi/2,thetamax,-pi/2,psimax))./A;
P = sqrt(i2.^2+i3.^2)./i1
plot(P, r);

Related

How to perform adaptive step size using Runge-Kutta fourth order (Matlab)?

For me, it seems like the estimated hstep takes quite a long time and long iteration to converge.
I tried it with this first ODE.
Basically, you perform the difference between RK4 with stepsize of h with h/2.Please note that to reach the same timestep value, you will have to use the y value after two timestep of h/2 so that it reaches h also.
frhs=#(x,y) x.^2*y;
Is my code correct?
clear all;close all;clc
c=[]; i=1; U_saved=[]; y_array=[]; y_array_alt=[];
y_arr=1; y_arr_2=1;
frhs=#(x,y) 20*cos(x);
tol=0.001;
y_ini= 1;
y_ini_2= 1;
c=abs(y_ini-y_ini_2)
hc=1
all_y_values=[];
for m=1:500
if (c>tol || m==1)
fprintf('More')
y_arr
[Unew]=vpa(Runge_Kutta(0,y_arr,frhs,hc))
if (m>1)
y_array(m)=vpa(Unew);
y_array=y_array(logical(y_array));
end
[Unew_alt]=Runge_Kutta(0,y_arr_2,frhs,hc/2);
[Unew_alt]=vpa(Runge_Kutta(hc/2,Unew_alt,frhs,hc/2))
if (m>1)
y_array_alt(m)=vpa(Unew_alt);
y_array_alt=y_array_alt(logical(y_array_alt));
end
fprintf('More')
%y_array_alt(m)=vpa(Unew_alt);
c=vpa(abs(Unew_alt-Unew) )
hc=abs(tol/c)^0.25*hc
if (c<tol)
fprintf('Less')
y_arr=vpa(y_array(end) )
y_arr_2=vpa(y_array_alt(end) )
[Unew]=Runge_Kutta(0,y_arr,frhs,hc)
all_y_values(m)=Unew;
[Unew_alt]=Runge_Kutta(0,y_arr_2,frhs,hc/2);
[Unew_alt]=Runge_Kutta(hc/2,Unew_alt,frhs,hc/2)
c=vpa( abs(Unew_alt-Unew) )
hc=abs(tol/c)^0.2*hc
end
end
end
all_y_values
A better structure for the time loop has only one place where the time step is computed.
x_array = [x0]; y_array = [y0]; h = h_init;
x = x0; y = y0;
while x < x_end
[y_new, err] = RK4_step_w_error(x,y,rhs,h);
factor = abs(tol/err)^0.2;
if factor >= 1
y_array(end+1) = y = y_new;
x_array(end+1) = x = x+h;
end
h = factor*h;
end
For the data given in the code
rhs = #(x,y) 20*cos(x);
x0 = 0; y0 = 1; x_end = 6.5; tol = 1e-3; h_init = 1;
this gives the result against the exact solution
The computed points lie exactly on the exact solution, for the segments between them one would need to use a "dense output" interpolation. Or as a first improvement, just include the middle value from the half-step computation.
function [ y_next, err] = RK4_step_w_error(x,y,rhs,h)
y2 = RK4_step(x,y,rhs,h);
y1 = RK4_step(x,y,rhs,h/2);
y1 = RK4_step(x+h/2,y1,rhs,h/2);
y_next = y1;
err = (y2-y1)/15;
end
function y_next = RK4_step(x,y,rhs,h)
k1 = h*rhs(x,y);
k2 = h*rhs(x+h/2,y+k1);
k3 = h*rhs(x+h/2,y+k2);
k4 = h*rhs(x+h,y+k3);
y_next = y + (k1+2*k2+2*k3+k4)/6;
end
Revision 1
The error returned is the actual step error. The error that is required for the step size control however is the unit step error or error density, which is the step error with divided by h
function [ y_next, err] = RK4_step_w_error(x,y,rhs,h)
y2 = RK4_step(x,y,rhs,h);
y1 = RK4_step(x,y,rhs,h/2);
y1 = RK4_step(x+h/2,y1,rhs,h/2);
y_next = y1;
err = (y2-y1)/15/h;
end
Changing the example to a simple bi-stable model oscillating between two branches of stable equilibria
rhs = #(x,y) 3*y-y^3 + 3*cos(x);
x0 = 0; y0 = 1; x_end = 13.5; tol = 5e-3; h_init = 5e-2;
gives plots of solution, error (against an ode45 integration) and step sizes
Red crosses are the step sizes of rejected steps.
Revision 2
The error in the function values can be used as an error guidance for the extrapolation value which is of 5th order, making the method a 5th order method in extrapolation mode. As it uses the 4th order error to predict the 5th order optimal step size, a caution factor is recommended, the code changes in the appropriate places to
factor = 0.75*abs(tol/err)^0.2;
...
function [ y_next, err] = RK4_step_w_error(x,y,rhs,h)
y2 = RK4_step(x,y,rhs,h);
y1 = RK4_step(x,y,rhs,h/2);
y1 = RK4_step(x+h/2,y1,rhs,h/2);
y_next = y1+(y1-y2)/15;
err = (y1-y2)/15;
end
In the plots the step size is appropriately larger, but the error shows sharper and larger spikes, this version of the method is apparently less stable.

Calculating numerical integral using integral or quadgk

I am using MATLAB to calculate the numerical integral of a complex function including natural exponent.
I get a warning:
Infinite or Not-a-Number value encountered
if I use the function integral, while another error is thrown:
Output of the function must be the same size as the input
if I use the function quadgk.
I think the reason could be that the integrand is infinite when the variable ep is near zero.
Code shown below. Hope you guys can help me figure it out.
close all
clear
clc
%%
N = 10^5;
edot = 10^8;
yita = N/edot;
kB = 8.6173324*10^(-5);
T = 300;
gamainf = 0.115;
dTol = 3;
K0 = 180;
K = K0/160.21766208;
nu = 3*10^12;
i = 1;
data = [];
%% lambda = ec/ef < 1
for ef = 0.01:0.01:0.1
for lambda = 0.01:0.01:0.08
ec = lambda*ef;
f = #(ep) exp(-((32/3)*pi*gamainf^3*(0.5+0.5*sqrt(1+2*dTol*K*(ep-ec)/gamainf)-dTol*K*(ep-ec)/gamainf).^3/(K*(ep-ec)).^2-16*pi*gamainf^3*(0.5+0.5*sqrt(1+2*dTol*K*(ep-ec)/gamainf)-dTol*K*(ep-ec)/gamainf).^2/((1+dTol*K*(ep-ec)/(gamainf*(0.5+0.5*sqrt(1+2*dTol*K*(ep-ec)/gamainf)-dTol*K*(ep-ec)/gamainf)))*(K*(ep-ec)).^2))/(kB*T));
q = integral(f,0,ef,'ArrayValued',true);
% q = quadgk(f,0,ef);
prob = 1-exp(-yita*nu*q);
data(i,1) = ef;
data(i,2) = lambda;
data(i,3) = q;
i = i+1;
end
end
I've rewritten your equations so that a human can actually understand it:
function integration
N = 1e5;
edot = 1e8;
yita = N/edot;
kB = 8.6173324e-5;
T = 300;
gamainf = 0.115;
dTol = 3;
K0 = 180;
K = K0/160.21766208;
nu = 3e12;
i = 1;
data = [];
%% lambda = ec/ef < 1
for ef = 0.01:0.01:0.1
for lambda = 0.01:0.01:0.08
ec = lambda*ef;
q = integral(#f,0,ef,'ArrayValued',true);
% q = quadgk(f,0,ef);
prob = 1 - exp(-yita*nu*q);
data(i,:) = [ef lambda q];
i = i+1;
end
end
function y = f(ep)
G = K*(ep - ec);
r = dTol*G/gamainf;
S = sqrt(1 + 2*r);
x = (1 + S)/2 - r;
Z = 16*pi*gamainf^3;
y = exp( -Z*x.^2.*( 2*x/(3*G.^2) - 1/(G.^2*(1 + r/x))) ) /...
(kB*T));
end
end
Now, for the first iteration, ep = 0.01, the value of the argument of the exp() function inside f is huge. In fact, if I rework the function to return the argument to the exponent (not the value):
function y = f(ep)
% ... all of the above
% NOTE: removed the exp() to return the argument
y = -Z*x.^2.*( 2*x/(3*G.^2) - 1/(G.^2*(1 + r/x))) ) /...
(kB*T);
end
and print its value at some example nodes like so:
for ef = 0.01 : 0.01 : 0.1
for lambda = 0.01 : 0.01 : 0.08
ec = lambda*ef;
zzz(i,:) = [f(0) f(ef/4) f(ef)];
i = i+1;
end
end
zzz
I get this:
% f(0) f(ef/4) f(ef)
zzz =
7.878426438111721e+07 1.093627454284284e+05 3.091140080273912e+03
1.986962280947140e+07 1.201698288371587e+05 3.187767404903769e+03
8.908646053687230e+06 1.325435523124976e+05 3.288027743119838e+03
5.055141696747510e+06 1.467952125661714e+05 3.392088351112798e+03
...
3.601790797707676e+04 2.897200140791236e+02 2.577170427480841e+01
2.869829209254144e+04 3.673888685004256e+02 2.404148067956737e+01
2.381082059148755e+04 4.671147785149462e+02 2.238181495716831e+01
So, integral() has to deal with things like exp(10^7). This may not be a problem per se if the argument would fall off quickly enough, but as shown above, it doesn't.
So basically you're asking for the integral of a function that ranges in value between exp(~10^7) and exp(~10^3). Needless to say, The d(ef) in the order of 0.01 isn't going to compensate for that, and it'll be non-finite in floating point arithmetic.
I suspect you have a scaling problem. Judging from the names of your variables as well as the equations, I would think that this has something to do with thermodynamics; a reworked form of Planck's law? In that case, I'd check if you're working in nanometers; a few factors of 10^(-9) will creep in, rescaling your integrand to the compfortably computable range.
In any case, it'll be wise to check all your units, because it's something like that that's messing up the numbers.
NB: the maximum exp() you can compute is around exp(709.7827128933840)

Weird results in approximation of a function with neural networks

I am trying to approximate a function (the right hand side of a differential equation) of the form ddx=F(x,dx,u) (where x,dx,u are scalars and u is constant) with an RBF neural network. I have the function F as a black box (I can feed it with initial x,dx and u and take x and dx for a timespan I want) and during training (using sigma-modification) I am getting the following response plotting the real dx vs the approximated dx.
Then I save the parameters of the NN (the centers and the stds of the gaussians, and the final weights) and perform a simulation using the same initial x,dx and u as before and keeping, of course, the weights stable this time. But I get the following plot.
Is that logical? Am I missing something?
The training code is as follows:
%load the results I got from the real function
load sim_data t p pd dp %p is x,dp is dx and pd is u
real_states = [p,dp];
%down and upper limits of the variables
p_dl = 0;
p_ul = 2;
v_dl = -1;
v_ul = 4;
pd_dl = 0;%pd is constant each time,but the function should work for different pds
pd_ul = 2;
%number of gaussians
nc = 15;
x = p_dl:(p_ul-p_dl)/(nc-1):p_ul;
dx = v_dl:(v_ul-v_dl)/(nc-1):v_ul;
pdx = pd_dl:(pd_ul-pd_dl)/(nc-1):pd_ul;
%centers of gaussians
Cx = combvec(x,dx,pdx);
%stds of the gaussians
B = ones(1,3)./[2.5*(p_ul-p_dl)/(nc-1),2.5*(v_ul-v_dl)/(nc-1),2.5*(pd_ul-pd_dl)/(nc-1)];
nw = size(Cx,2);
wdx = zeros(nw,1);
state = real_states(1,[1,4]);%there are also y,dy,dz and z in real_states (ignored here)
states = zeros(length(t),2);
timestep = 0.005;
for step=1:length(t)
states(step,:) = state;
%compute the values of the sigmoids
Sx = exp(-1/2 * sum(((([real_states(step,1);real_states(step,4);pd(1)]*ones(1,nw))'-Cx').*(ones(nw,1)*B)).^2,2));
ddx = -530*state(2) + wdx'*Sx;
edx = state(2) - real_states(step,4);
dwdx = -1200*edx * Sx - 4 * wdx;
wdx = wdx + dwdx*timestep;
state = [state(1)+state(2)*timestep,state(2)+ddx*timestep];
end
save weights wdx Cx B
figure
plot(t,[dp(:,1),states(:,2)])
legend('x_d_o_t','x_d_o_t_h_a_t')
The code used to verify the approximation is the following:
load sim_data t p pd dp
real_states = [p,dp];
load weights wdx Cx B
nw = size(Cx,2);
state = real_states(1,[1,4]);
states = zeros(length(t),2);
timestep = 0.005;
for step=1:length(t)
states(step,:) = state;
Sx = exp(-1/2 * sum(((([real_states(step,1);real_states(step,4);pd(1)]*ones(1,nw))'-Cx').*(ones(nw,1)*B)).^2,2));
ddx = -530*state(2) + wdx'*Sx;
state = [state(1)+state(2)*timestep,state(2)+ddx*timestep];
end
figure
plot(t,[dp(:,1),states(:,2)])
legend('x_d_o_t','x_d_o_t_h_a_t')

Has fminsearch too many parameters?

I run this code in matlab to minimize the parameters of my function real_egarchpartial with fminsearch:
data = xlsread('return_cc_in.xlsx');
SPY = data(:,25);
dailyrange = xlsread('DR_in.xlsx');
drSPY= dailyrange(:,28);
startingVals = [mean(SPY); 0.041246; 0.70121; 0.05; 0.04; 0.45068; -0.1799; 1.0375; 0.06781; 0.070518];
T = size(SPY,1);
options = optimset('fminsearch');
options.Display = 'iter';
estimates = fminsearch(#real_egarchpartial, startingVals, options, SPY, drSPY);
[ll, lls, u]=real_egarchpartial(estimates, SPY, drSPY);
And I get this message:
Exiting: Maximum number of function evaluations has been exceeded
- increase MaxFunEvals option.
I put the original starting values. So I assumed they are corrects. I used fminsearch and not fmincon because my function hasn't constraints and with fminunc my function gets a lot of red messages.
the real_egarchpartial function is the following:
function [ll,lls,lh] = real_egarchpartial(parameters, data, x_rk)
mu = parameters(1);
omega = parameters(2);
beta = parameters(3);
tau1 = parameters(4);
tau2 = parameters(5);
gamma = parameters(6);
csi = parameters(7);
phi = parameters(8);
delta1 = parameters(9);
delta2 = parameters(10);
%Data and h are T by 1 vectors
T = size(data,1);
eps = data-mu;
lh = zeros(T,1);
h = zeros(T,1);
u = zeros(T,1);
%Must use a back Cast to start the algorithm
h(1)=var(data);
lh(1) = log(h(1));
z= eps/sqrt(h(1));
u(1) = rand(1);
lxRK = log(x_rk);
for t = 2:T;
lh(t) = omega + beta*lh(t-1) + tau1*z(t-1) + tau2*((z(t-1).^2)-1)+ gamma*u(t-1);
h(t)=exp(lh(t));
z = eps/sqrt(h(t));
end
for t = 2:T
u(t)= lxRK(t) - csi - phi*h(t) - delta1*z(t) - delta2*((z(t).^2)-1);
end
lls = 0.5*(log(2*pi) + lh + eps.^2./h);
ll = sum(lls);
Could someone explain what is wrong? Is there another function more efficient for my estimation? Any help will be appreciated! Thank you.

blockwise image rotation in matlab

I am working on ridge frequency estimation for which I have to obtain an blockwise oriented image. I have developed the code but unable to remove an error.
the process goes like this. Input image is G(m,n) and theta(m,n) is an image containing theta. Input image G is divide into w*w block (w = 17) and for each block centred at pixel(i,j) compute an oriented window of size l*w (33*17). For each block we have to compute the x signature as
x[0],x[1],x[2].....x[l-1]...
x[k] = 1/w * summation(d=0 to w-1)G(u,v)
u = i+ (d-(w/2))cos(theta(i,j))+(k-(l/2))sin(theta(i,j))
v = i+ (d-(w/2))sin(theta(i,j))+((l/2)-k)cos(theta(i,j))
here is my code
% To compute ridge frequency
theta_image; theta image as input
im = imread('cameraman.tif');
[m,n] = size(im);
l = (2*w-1);
w = 17;
ww = floor(w/2);
for i1 = 9:w:m
for j1 = 9:w:n
G = im(i1-ww:i1+ww,j1-ww:j1+ww);
O = theta(i1-ww:i1+ww,j1-ww:j1+ww);
G = padarray(G,[10 10],'both'); not sure its correct?
for k = 0:l-1
for d = 0:w-1
cnst_1 = (d-floor(w/2));
cnst_2 = (k-floor(l/2));
cnst_3 = (floor((l/2)-k);
u = i1+(cnst_1.*cos(O(i1,j1)) + cnst_2.*sin(O(i1,j1)));
v = j1+(cnst_1.*sin(O(i1,j1)) + cnst_3.*cos(O(i1,j1)));
u = fix(u);
v = fix(v);
store(k,d) = G(u,v);
x(k) = (sum(G(u,v)))/w; not sure will it be stored block-wise?
end;
end;
end;
end;
the error is
Attempted to access G(22,0); index must be a positive integer or logical.
Error in ridge_frequency (line 76)
store(k,d) = G(u,v);