Matlab plot for exponential decay function - matlab

I have empirical data of 9 sets of patients the data looks in this format
input = [10 -1 1
20 17956 1
30 61096 1
40 31098 1
50 18446 1
60 12969 1
95 7932 1
120 6213 1
188 4414 1
240 3310 1
300 3329 1
610 2623 1
1200 1953 1
1800 1617 1
2490 1559 1
3000 1561 1
3635 1574 1
4205 1438 1
4788 1448 1
];
calibrationfactor_wellcounter =1.841201569;
Here, the first column describes values of time and next one is concentration. As you can see, the concentration increases until a certain time and then decreases exponentially with increase in time.
If I plot the following characteristics, I obtain following curve
I would like to create a script which represents the same behavior cited above. following is the script which i have formulated where concentration linearly increases till certain time period and aftermath it decays exponentially, but when i plot this function i am obtaining linear characteristics , kindly let me know if my logic is appropriate
function c_o = Sample_function(td,t_max,a1,a2,a3,b1,b2,b3)
t =(0: 100 :5000); % time of the sample post injection in mins
c =(0 : 2275.3 :113765);
A_max= max(c);%Max value of Concentration (Peak of the curve)
c_o = zeros(size(t));
c_o(t>td & t<=t_max) = A_max*(t(t>td & t<=t_max)-td);
c_o(t>t_max)=(a1*exp(-b1*(t(t>t_max)-t_max)))+(a2*exp(-b2*(t(t>t_max)-t_max)))+(a3*exp(-b3*(t(t>t_max)-t_max)));
fprintf('plotting Data ...\n');
hold on;
%figure ;
plot(c_o,'erasemode','background');
xlabel('time of the sample in minutes ');
ylabel('Activity of the sample Ba/ml');
title (' Input function: Activity sample VS time ');
pause;
end
The figure i obtained is
In the above plot the decay is linear instead of exponential, let me know how to obtain 3rd order decay this is the line of code i have written to obtain 3rd order decay
c_o(t>t_max)=(a1*exp(-b1*(t(t>t_max)-t_max)))+(a2*exp(-b2*(t(t>t_max)-t_max)))+(a3*exp(-b3*(t(t>t_max)-t_max)));

I've come up with a solution using the functionality of Matlab's Curve Fitting Toolbox. The fitting result looks very good. However, I've found that it strongly depends on the right choice of starting values for the parameters, which therefore have to be carefully chosen manually.
Starting from you variable input, let's define the independent and dependent variables for the fit, time and concentration,
t = input(:, 1);
c = input(:, 2);
and plot them:
plot(t, c, 'x')
axis([-100 5000 -2000 80000])
xlabel time
ylabel concentration
These data are to be modeled with a function with three pieces: 1) constantly 0 up to a time td, 2) linearly increasing between td and tmax, 3) decreasing as a sum of three different exponentials after time tmax. In addition, the function is continuous, so that the three pieces have to fit together seamlessly. The implementation of this model as a Matlab function:
function c = model(t, a1, a2, a3, b1, b2, b3, td, tmax)
c = zeros(size(t));
ind = (t > td) & (t < tmax);
c(ind) = (t(ind) - td) ./ (tmax - td) * (a1 + a2 + a3);
ind = (t >= tmax);
c(ind) = a1 * exp(-b1 * (t(ind) - tmax)) ...
+ a2 * exp(-b2 * (t(ind) - tmax)) + a3 * exp(-b3 * (t(ind) - tmax));
Model parameters appear to be treated internally by the Curve Fitting Toolbox as a vector ordered alphabetically by the parameter names, so to avoid confusion I sorted the parameters alphabetically in the definition of this function, too. a1 to a3 and b1 to b3 are the amplitudes and inverse time constants of the three exponentials, respectively.
Let's fit the model to the data:
ft = fittype('model(t, a1, a2, a3, b1, b2, b3, td, tmax)', 'independent', 't');
fo = fit(t, c, ft, ...
'StartPoint', [20000, 20000, 20000, 0.01, 0.01, 0.01, 10, 30], ...
'Lower', [0, 0, 0, 0, 0, 0, 0, 0])
As mentioned before, the fitting works well only if the algorithm gets decent starting values. I here chose for the amplitudes a1 to a3 the number 20000, which is about one third of the maximum of the data, for b1 to b3 a value of 0.01 corresponding to a time constant of about 100, the time of the data maximum, 30, for tmax, and 10 as a rough estimate of the starting constant time td.
The output of fit:
fo =
General model:
fo(t) = model(t, a1, a2, a3, b1, b2, b3, td, tmax)
Coefficients (with 95% confidence bounds):
a1 = 2510 (-2.48e+07, 2.481e+07)
a2 = 1.044e+04 (-7.393e+09, 7.393e+09)
a3 = 6.506e+04 (-4.01e+11, 4.01e+11)
b1 = 0.0001465 (7.005e-05, 0.0002229)
b2 = 0.01049 (0.006933, 0.01405)
b3 = 0.09134 (0.08623, 0.09644)
td = 17.97 (-3.396e+07, 3.396e+07)
tmax = 26.78 (-6.748e+07, 6.748e+07)
I can't decide whether these values make sense physiologically. The estimates also don't appear to be too well defined, since many of the confidence intervals are huge and actually include 0. The documentation isn't clear on this, but I assume the confidence bounds are nonsimultaneous, which means it is possible that the huge intervals simply indicate strong correlations between the estimates of different parameters.
Plotting the data together with the fitted model
plot(t, c, 'x')
hold all
ts = 0 : 5000;
plot(ts, model(ts, fo.a1, fo.a2, fo.a3, fo.b1, fo.b2, fo.b3, fo.td, fo.tmax))
axis([-100 5000 -2000 80000])
xlabel time
ylabel concentration
shows that the fit is excellent:
A close-up of the more interesting initial part:
Note that the estimated time and value of the true maximal concentration (27, 78000) depends only on the fit to the following decreasing part of the data, since the linear increase is characterized only by one data point, which does not pose a constraint.
The results indicate that the data are not sufficient to obtain precise estimates of the model parameters. You should consider either to increase the sampling rate of the data, particularly up to time 500, or to decrease the complexity of the model, e.g. by using a sum of two exponentials only; or both.

Try this code from this question:
x = input(:,1);
c = input(:,2);
c_0 = piecewiseFunction(x, max(c), td,t_max,a1,a2,a3,b1,b2,b3)
with:
function y = piecewiseFunction(x,A_max,td,t_max,a1,a2,a3,b1,b2,b3)
y = zeros(size(x));
for i = 1:length(x)
if x(i) < td
y(i) = 0;
elseif(x(i) < t_max)
y(i) = A_max*(x(i)-td);
else
y(i) = (a1*exp(-b1*(x(i)-t_max)))+(a2*exp(-b2*(x(i)- t_max)))+(a3*exp(-b3*(x(i)-t_max)))
end
end
end

Related

Laguerre's method to obtain poly roots (Matlab)

I must write using Laguerre's method a piece of code to find the real and complex roots of poly:
P=X^5-5*X^4-6*X^3+6*X^2-3*X+1
I have little doubt. I did the algorithm in the matlab, but 3 out of 5 roots are the same and I don't think that is correct.
syms X %Declearing x as a variabl
P=X^5-5*X^4-6*X^3+6*X^2-3*X+1; %Equation we interest to solve
n=5; % The eq. order
Pd1 = diff(P,X,1); % first differitial of f
Pd2 = diff(P,X,2); %second differitial of f
err=0.00001; %Answear tollerance
N=100; %Max. # of Iterations
x(1)=1e-3; % Initial Value
for k=1:N
G=double(vpa(subs(Pd1,X,x(k))/subs(P,X,x(k))));
H=G^2 - double(subs(Pd2,X,x(k))) /subs(P,X,x(k));
D1= (G+sqrt((n-1)*(n*H-G^2)));
D2= (G-sqrt((n-1)*(n*H-G^2)));
D = max(D1,D2);
a=n/D;
x(k+1)=x(k)-a
Err(k) = abs(x(k+1)-x(k));
if Err(k) <=err
break
end
end
output (roots of polynomial):
x =
0.0010 + 0.0000i 0.1434 + 0.4661i 0.1474 + 0.4345i 0.1474 + 0.4345i 0.1474 + 0.4345i
What you actually see are all the values x(k) which arose in the loop. The last one, 0.1474 + 0.4345i is the end result of this loop - the approximation of the root which is in your given tolerance threshold. The code
syms X %Declaring x as a variable
P = X^5 - 5 * X^4 - 6 * X^3 + 6 * X^2 - 3 * X + 1; %Polynomial
n=5; %Degree of the polynomial
Pd1 = diff(P,X,1); %First derivative of P
Pd2 = diff(P,X,2); %Second derivative of P
err = 0.00001; %Answer tolerance
N = 100; %Maximal number of iterations
x(1) = 0; %Initial value
for k = 1:N
G = double(vpa(subs(Pd1,X,x(k)) / subs(P,X,x(k))));
H = G^2 - double(subs(Pd2,X,x(k))) / subs(P,X,x(k));
D1 = (G + sqrt((n-1) * (n * H-G^2)));
D2 = (G - sqrt((n-1) * (n * H-G^2)));
D = max(D1,D2);
a = n/D;
x(k+1) = x(k) - a;
Err(k) = abs(x(k+1)-x(k));
if Err(k) <=err
fprintf('Initial value %f, result %f%+fi', x(1), real(x(k)), imag(x(k)))
break
end
end
results in
Initial value -2.000000, result -1.649100+0.000000i
If you want to get other roots, you have to use other initial values. For example one can obtain
Initial value 10.000000, result 5.862900+0.000000i
Initial value -2.000000, result -1.649100+0.000000i
Initial value 3.000000, result 0.491300+0.000000i
Initial value 0.000000, result 0.147400+0.434500i
Initial value 1.000000, result 0.147400-0.434500i
These are all zeros of the polynomial.
A method for calculating the next root when you have found another one would be that you divide through the corresponding linear factor and use your loop for the resulting new polynomial. Note that this is in general not very easy to handle since rounding errors can have a big influence on the result.
Problems with the existing code
You do not implement the Laguerre method properly as a method in complex numbers. The denominator candidates D1,D2 are in general complex numbers, it is inadvisable to use the simple max which only has sensible results for real inputs. The aim is to have a=n/D be the smaller of both variants, so that one has to look for the D in [D1,D2] with the larger absolute value. If there were a conditional assignment as in C, this would look like
D = (abs(D_1)>abs(D2)) ? D1 : D2;
As that does not exist, one has to use commands with a similar result
D = D1; if (abs(D_1)<abs(D2)) D=D2; end
The resulting sequence of approximation points is
x(0) = 0.0010000
x(1) = 0.143349512707684+0.466072958423667i
x(2) = 0.164462212064089+0.461399841949893i
x(3) = 0.164466373475316+0.461405404094130i
There is a point where one can not expect the (residual) polynomial value at the root approximation to substantially decrease. The value close to zero is obtained by adding and subtracting rather large terms in the sum expression of the polynomial. The accuracy lost in these catastrophic cancellation events can not be recovered.
The threshold for polynomial values that are effectively zero can be estimated as the machine constant of the double type times the polynomial value where all coefficients and the evaluation point are replaced by their absolute values. This test serves in the code primarily to avoid divisions by zero or near-zero.
Finding all roots
One approach is to apply the method to a sufficiently large number of initial points along some circle containing all the roots, with some strict rules for early termination at too slow convergence. One would have to make the list of the roots found unique, but keep the multiplicity,...
The other standard method is to apply deflation, that is, divide out the linear factor of the root found. This works well in low degrees.
There is no need for the slower symbolic operations as there are functions that work directly on the coefficient array, such as polyval and polyder. Deflation by division with remainder can be achieved using the deconv function.
For real polynomials, we know that the complex conjugate of a root is also a root. Thus initialize the next iteration with the deflated polynomial with it.
Other points:
There is no point in the double conversions as at no point there is a conversion into the single type.
If you don't do anything with it, it makes no sense to create an array, especially not for Err.
Roots of the example
Implementing all this I get a log of
x(0) = 0.001000000000000+0.000000000000000i, |Pn(x(0))| = 0.99701
x(1) = 0.143349512707684+0.466072958423667i, |dx|= 0.48733
x(2) = 0.164462212064089+0.461399841949893i, |dx|=0.021624
x(3) = 0.164466373475316+0.461405404094130i, |dx|=6.9466e-06
root found x=0.164466373475316+0.461405404094130i with value P0(x)=-2.22045e-16+9.4369e-16i
Deflation
x(0) = 0.164466373475316-0.461405404094130i, |Pn(x(0))| = 2.1211e-15
root found x=0.164466373475316-0.461405404094130i with value P0(x)=-2.22045e-16-9.4369e-16i
Deflation
x(0) = 0.164466373475316+0.461405404094130i, |Pn(x(0))| = 4.7452
x(1) = 0.586360702193454+0.016571894375927i, |dx|= 0.61308
x(2) = 0.562204173408499+0.000003168181059i, |dx|=0.029293
x(3) = 0.562204925474889+0.000000000000000i, |dx|=3.2562e-06
root found x=0.562204925474889+0.000000000000000i with value P0(x)=2.22045e-16-1.33554e-17i
Deflation
x(0) = 0.562204925474889-0.000000000000000i, |Pn(x(0))| = 7.7204
x(1) = 3.332994579372812-0.000000000000000i, |dx|= 2.7708
root found x=3.332994579372812-0.000000000000000i with value P0(x)=6.39488e-14-3.52284e-15i
Deflation
x(0) = 3.332994579372812+0.000000000000000i, |Pn(x(0))| = 5.5571
x(1) = -2.224132251798332+0.000000000000000i, |dx|= 5.5571
root found x=-2.224132251798332+0.000000000000000i with value P0(x)=-3.33067e-14+1.6178e-15i
for the modified code
P = [1, -2, -6, 6, -3, 1];
P0 = P;
deg=length(P)-1; % The eq. degree
err=1e-05; %Answer tolerance
N=10; %Max. # of Iterations
x=1e-3; % Initial Value
for n=deg:-1:1
dP = polyder(P); % first derivative of P
d2P = polyder(dP); %second derivative of P
fprintf("x(0) = %.15f%+.15fi, |Pn(x(0))| = %8.5g\n", real(x),imag(x), abs(polyval(P,x)));
for k=1:N
Px = polyval(P,x);
dPx = polyval(dP,x);
d2Px = polyval(d2P,x);
if abs(Px) < 1e-14*polyval(abs(P),abs(x))
break % if value is zero in relative accuracy
end
G = dPx/Px;
H=G^2 - d2Px / Px;
D1= (G+sqrt((n-1)*(n*H-G^2)));
D2= (G-sqrt((n-1)*(n*H-G^2)));
D = D1;
if abs(D2)>abs(D1) D=D2; end % select the larger denominator
a=n/D;
x=x-a;
fprintf("x(%d) = %.15f%+.15fi, |dx|=%8.5g\n",k,real(x),imag(x), abs(a));
if abs(a) < err*(err+abs(x))
break
end
end
y = polyval(P0,x); % check polynomial value of the original polynomial
fprintf("root found x=%.15f%+.15fi with value P0(x)=%.6g%+.6gi\n", real(x),imag(x),real(y),imag(y));
disp("Deflation");
[ P,R ] = deconv(P,[1,-x]); % division with remainder
x = conj(x); % shortcut for conjugate pairs and clustered roots
end

Code wont produce the value of a definite integral in MATLAB

I've had problems with my code as I've tried to make an integral compute, but it will not for the power, P2.
I've tried using anonymous function handles to use the integral() function on MATLAB as well as just using int(), but it will still not compute. Are the values too small for MATLAB to integrate or am I just missing something small?
Any help or advice would be appreciated to push me in the right direction. Thanks!
The problem in the code is in the bottom of the section labelled "Power Calculations". My integral also gets quite messy if that makes a difference.
%%%%%%%%%%% Parameters %%%%%%%%%%%%
n0 = 1; %air
n1 = 1.4; %layer 1
n2 = 2.62; %layer 2
n3 = 3.5; %silicon
L0 = 650*10^(-9); %centre wavelength
L1 = 200*10^(-9): 10*10^(-9): 2200*10^(-9); %lambda from 200nm to 2200nm
x = ((pi./2).*(L0./L1)); %layer phase thickness
r01 = ((n0 - n1)./(n0 + n1)); %reflection coefficient 01
r12 = ((n1 - n2)./(n1 + n2)); %reflection coefficient 12
r23 = ((n2 - n3)./(n2 + n3)); %reflection coefficient 23
t01 = ((2.*n0)./(n0 + n1)); %transmission coefficient 01
t12 = ((2.*n1)./(n1 + n2)); %transmission coefficient 12
t23 = ((2.*n2)./(n2 + n3)); %transmission coefficient 23
Q1 = [1 r01; r01 1]; %Matrix Q1
Q2 = [1 r12; r12 1]; %Matrix Q2
Q3 = [1 r23; r23 1]; %Matrix Q3
%%%%%%%%%%%% Graph of L vs R %%%%%%%%%%%
R = zeros(size(x));
for i = 1:length(x)
P = [exp(j.*x(i)) 0; 0 exp(-j.*x(i))]; %General Matrix P
T = ((1./(t01.*t12.*t23)).*(Q1*P*Q2*P*Q3)); %Transmission
T11 = T(1,1); %T11 value
T21 = T(2,1); %T21 value
R(i) = ((abs(T21./T11))^2).*100; %Percent reflectivity
end
plot(L1,R)
title('Percent Reflectance vs. wavelength for 2 Layers')
xlabel('Wavelength (m)')
ylabel('Reflectance (%)')
%%%%%%%%%%% Power Calculation %%%%%%%%%%
syms L; %General lamda
y = ((pi./2).*(L0./L)); %Layer phase thickness with variable Lamda
P1 = [exp(j.*y) 0; 0 exp(-j.*y)]; %Matrix P with variable Lambda
T1 = ((1./(t01.*t12.*t23)).*(Q1*P1*Q2*P1*Q3)); %Transmittivity matrix T1
I = ((6.16^(15))./((L.^(5)).*exp(2484./L) - 1)); %Blackbody Irradiance
Tf11 = T1(1,1); %New T11 section of matrix with variable Lambda
Tf2 = (((abs(1./Tf11))^2).*(n3./n0)); %final transmittivity
P1 = Tf2.*I; %Power before integration
L_initial = 200*10^(-9); %Initial wavelength
L_final = 2200*10^(-9); %Final wavelength
P2 = int(P1, L, L_initial, L_final) %Power production
I've refactored your code
to make it easier to read
to improve code reuse
to improve performance
to make it easier to understand
Why do you use so many unnecessary parentheses?!
Anyway, there's a few problems I saw in your code.
You used i as a loop variable, and j as the imaginary unit. It was OK for this one instance, but just barely so. In the future it's better to use 1i or 1j for the imaginary unit, and/or m or ii or something other than i or j as the loop index variable. You're helping yourself and your colleagues; it's just less confusing that way.
Towards the end, you used the variable name P1 twice in a row, and in two different ways. Although it works here, it's confusing! Took me a while to unravel why a matrix-producing function was producing scalars instead...
But by far the biggest problem in your code is the numerical problems with the blackbody irradiance computation. The term
L⁵ · exp(2484/L) - 1
for λ₀ = 200 · 10⁻⁹ m will require computing the quantity
exp(1.242 · 10¹⁰)
which, needless to say, is rather difficult for a computer :) Actually, the problem with your computation is two-fold. First, the exponentiation is definitely out of range of 64 bit IEEE-754 double precision, and will therefore result in ∞. Second, the parentheses are wrong; Planck's law should read
C/L⁵ · 1/(exp(D) - 1)
with C and D the constants (involving Planck's constant, speed of light, and Boltzmann constant), which you've presumably precomputed (I didn't check the values. I do know choice of units can mess these up, so better check).
So, aside from the silly parentheses error, I suspect the main problem is that you simply forgot to rescale λ to nm. Changing everything in the blackbody equation to nm and correcting those parentheses gives the code
I = 6.16^(15) / ( (L*1e+9)^5 * (exp(2484/(L*1e+9)) - 1) );
With this, I got a finite value for the integral of
P2 = 1.052916498836486e-010
But, again, you'd better double-check everything.
Note that I used quadgk(), because it's one of the better ones available on R2010a (which I'm stuck with), but you can just as easily replace this with integral() available on anything newer than R2012a.
Here's the code I ended up with:
function pwr = my_fcn()
% Parameters
n0 = 1; % air
n1 = 1.4; % layer 1
n2 = 2.62; % layer 2
n3 = 3.5; % silicon
L0 = 650e-9; % centre wavelength
% Reflection coefficients
r01 = (n0 - n1)/(n0 + n1);
r12 = (n1 - n2)/(n1 + n2);
r23 = (n2 - n3)/(n2 + n3);
% Transmission coefficients
t01 = (2*n0) / (n0 + n1);
t12 = (2*n1) / (n1 + n2);
t23 = (2*n2) / (n2 + n3);
% Quality factors
Q1 = [1 r01; r01 1];
Q2 = [1 r12; r12 1];
Q3 = [1 r23; r23 1];
% Initial & Final wavelengths
L_initial = 200e-9;
L_final = 2200e-9;
% plot reflectivity for selected lambda range
plot_reflectivity(L_initial, L_final, 1000);
% Compute power production
pwr = quadgk(#power_production, L_initial, L_final);
% Helper functions
% ========================================
% Graph of lambda vs reflectivity
function plot_reflectivity(L_initial, L_final, N)
L = linspace(L_initial, L_final, N);
R = zeros(size(L));
for ii = 1:numel(L)
% Transmission
T = transmittivity(L(ii));
% Percent reflectivity
R(ii) = 100 * abs(T(2,1)/T(1,1))^2 ;
end
plot(L, R)
title('Percent Reflectance vs. wavelength for 2 Layers')
xlabel('Wavelength (m)')
ylabel('Reflectance (%)')
end
% Compute transmittivity matrix for a single wavelength
function T = transmittivity(L)
% Layer phase thickness with variable Lamda
y = pi/2 * L0/L;
% Matrix P with variable Lambda
P1 = [exp(+1j*y) 0
0 exp(-1j*y)];
% Transmittivity matrix T1
T = 1/(t01*t12*t23) * Q1*P1*Q2*P1*Q3;
end
% Power for a specific wavelength. Note that this function
% accepts vector-valued wavelengths; needed for quadgk()
function pwr = power_production(L)
pwr = zeros(size(L));
for ii = 1:numel(L)
% Transmittivity matrix
T1 = transmittivity(L(ii));
% Blackbody Irradiance
I = 6.16^(15) / ( (L(ii)*1e+9)^5 * (exp(2484/(L(ii)*1e+9)) - 1) );
% final transmittivity
Tf2 = abs(1/T1(1))^2 * n3/n0;
% Power before integration
pwr(ii) = Tf2 * I;
end
end
end

How to plot 𝛽−𝑤 diagram in MATLAB?

I am trying to plot the 𝛽−𝑤 diagrams for the given phase constants using MATLAB, but although I have look at many web pages, there is not a similar example plotting 𝛽−𝑤 diagram in MATLAB. Could you please clarify me how to proceed by giving some examples regarding to this problem? Any help would really be appreciated.
Plot range: 𝑓=10𝑀ℎ𝑧−10𝐺𝐻𝑧
w : Angular frequency
wc : A constant Angular frequency
Parameters for 1st: 𝑤𝑐1=0.2∗𝑤, 𝑤𝑐2=0.4∗𝑤, 𝑤𝑐3=0.6∗𝑤, 𝑤𝑐4=0.8∗𝑤 , ɛ1=1* ɛ0, μ= μ0
Parameters for 1st: a1=0.08636cm, a2=0.8636cm, a3=2.286cm, a4=29.21cm, ɛ1=1* ɛ0, μ= μ0
As the OP asked, this is a sort of Matlab code.
I assume to map the plot of B with w in range [1,100] (but values can be changed)
First case has wc has 3 different cases, 4 different plot of B (B1,B2, B3 and B4) will be mapped in four different colors
%constant inizialization
mu = 1.2566E-6;
e = 1;
start_f = 10000; %10 MHz start frequency range
end_f = 10000000; %10 GHz end frequency range
step = 10 %plot the function every "step" Hz (ONLY INTEGER NUMBERS ALLOWED)
k = 1;
% function of B example: B = w*sqrt(mu*e)*sqrt(1-((wc^2)/w));
%vectors initialization to avoid the "consider preallocation" Matlab not-critical warning
range_f = ceil((end_f - start_f)/step) + 1;
w = zeros(range_f);
B1 = zeros(range_f);
B2 = zeros(range_f);
B3 = zeros(range_f);
B4 = zeros(range_f);
for i=start_f:step:end_f %from 10 MHz to 10 GHz with steps of 1 Hz
%store i in the i-cell of vector w
w(k) = i;
%values that need to be updated every time
w1 = 0.2*w(i);
w2 = 0.4*w(i);
w3 = 0.6*w(i);
w4 = 0.8*w(i);
%four different results of B
B1(i) = w(i)*sqrt(mu*e)*sqrt(1-((w1^2)/w(i)));
B2(i) = w(i)*sqrt(mu*e)*sqrt(1-((w2^2)/w(i)));
B3(i) = w(i)*sqrt(mu*e)*sqrt(1-((w3^2)/w(i)));
B4(i) = w(i)*sqrt(mu*e)*sqrt(1-((w4^2)/w(i)));
k = k+1;
end
%plot the 4 lines
plot(w,B1,'r') %red line of B1 = f(w)
hold on
plot(w,B2,'g') %green line of B2 = f(w)
hold on
plot(w,B3,'b') %blue line of B3 = f(w)
hold on
plot(w,B4,'k') %black line of B4 = f(w)
4 different cases have to be represented with 4 plot (in this example they have been overlayed).
The last notation can be done in the same way (you have 4 constant parameters a1, a2 etc.) that does not depends from w this time. So
B1a(i) = sqrt((w(i)^2)*mu*e - ((pi^2)/a1)));
B2a(i) = sqrt((w(i)^2)*mu*e - ((pi^2)/a1)));
B3a(i) = sqrt((w(i)^2)*mu*e - ((pi^2)/a1)));
B4a(i) = sqrt((w(i)^2)*mu*e - ((pi^2)/a1)));
If some errors (due to "fast" writing) occurs to you, report them in comments and I will correct and update the code

Getting NaN values in neural network weight matrices

**I am trying to develop a feedforward NN in MATLAB. I have a dataset of 12 inputs and 1 output with 46998 samples. I have some NaN values in last rows of Matrix, because some inputs are accelerations & velocities which are 1 & 2 steps less respectively than displacements.
With this current data set I am getting w1_grad & w2_grad as NaN matrices. I tried to remove them using `Heave_dataset(isnan(Heave_dataset))=[];, but my dataset is getting converted into a column matrix of (1*610964).
can anyone help me with this ?
%
%% Clear Variables, Close Current Figures, and Create Results Directory
clc;
clear all;
close all;
mkdir('Results//'); %Directory for Storing Results
%% Configurations/Parameters
load 'Heave_dataset'
% Heave_dataset(isnan(Heave_dataset))=[];
nbrOfNeuronsInEachHiddenLayer = 24;
nbrOfOutUnits = 1;
unipolarBipolarSelector = -1; %0 for Unipolar, -1 for Bipolar
learningRate = 0.08;
nbrOfEpochs_max = 50000;
%% Read Data
Input = Heave_dataset(:, 1:length(Heave_dataset(1,:))-1);
TargetClasses = Heave_dataset(:, length(Heave_dataset(1,:)));
%% Calculate Number of Input and Output NodesActivations
nbrOfInputNodes = length(Input(1,:)); %=Dimention of Any Input Samples
nbrOfLayers = 2 + length(nbrOfNeuronsInEachHiddenLayer);
nbrOfNodesPerLayer = [nbrOfInputNodes nbrOfNeuronsInEachHiddenLayer nbrOfOutUnits];
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Forward Pass %%%%%%%%%%%
%% Adding the Bias to Input layer
Input = [ones(length(Input(:,1)),1) Input];
%% Weights leading from input layer to hidden layer is w1
w1 = rand(nbrOfNeuronsInEachHiddenLayer,(nbrOfInputNodes+1));
%% Input & output of hidde layer
hiddenlayer_input = Input*w1';
hiddenlayer_output = -1 + 2./(1 + exp(-(hiddenlayer_input)));
%% Adding the Bias to hidden layer
hiddenlayer_output = [ones(length(hiddenlayer_output(:,1)),1) hiddenlayer_output];
%% Weights leading from input layer to hidden layer is w1
w2 = rand(nbrOfOutUnits,(nbrOfNeuronsInEachHiddenLayer+1));
%% Input & output of hidde layer
outerlayer_input = hiddenlayer_output*w2';
outerlayer_output = outerlayer_input;
%% Error Calculation
TotalError = 0.5*(TargetClasses-outerlayer_output).^2;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Backward Pass %%%%%%%%%%%
d3 = outerlayer_output - TargetClasses;
d2 = (d3*w2).*hiddenlayer_output.*(1-hiddenlayer_output);
d2 = d2(:,2:end);
D1 = d2' * Input;
D2 = d3' * hiddenlayer_output;
w1_grad = D1/46998 + learningRate*[zeros(size(w1,1),1) w1(:,2:end)]/46998;
w2_grad = D2/46998 + learningRate*[zeros(size(w2,1),1) w2(:,2:end)]/46998;
You should try vectorize your algorithm. First arrange your data in a 46998x12 matrix X.Add bias to X like X=[ones(46998,1 X]. Then the weights leading from input layer to first hidden layer must be arranged in a matrix W1 with dimensions numberofneuronsinfirsthiddenlayer(24)x(input + 1). Then XW1' is what you feed in your neuron function (either is it sigmoid or whatever it is). The result (like sigmoid(XW') is the output of neurons at hidden level 1. You add bias like before and multiply by weight matrix W2 (the weights that lead from hidden layer 1 to hidden layer 2) and so on. Hope this helps to get you started vectorizing your code at least for the feedforward part. The back-propagation part is a little trickier but luckily involves the same matrices.
I will shortly recite the feedforward process so that we use same language talking about backpropagation.
There is the data called X.(dimensions 46998x12)
A1 = [ones(46998,1 X] is the input including bias. (46998x13)
Z2 = A1*W1' (W1 is the weight matrix that leads from input to hidden layer 1)
A2 = sigmoid(Z2);
A2 = [ones(m,1) A2]; adding bias again
Z3 = A2 * W2';
A3 = sigmoid(Z3);
Supposing you only have one hidden layer feedforward stops here. I'll start backwards now and you can generalize as appropriate.
d3 = A3 - Y; (Y must is part of your data, the actual values of the data with which you train your nn)
d2 = (d3 * W2).* A2 .* (1-A2); ( Sigmod function has a nice property that d(sigmoid(z))/dz = sigmoid(z)*(1-sigmoid(z)).)
d2 = d2(:,2:end);(You dont need the first column that corresponds in the bias)
D1 = d2' * A1;
D2 = d3' * A2;
W1_grad = D1/m + lambda*[zeros(size(W1,1),1) W1(:,2:end)]/m; (lamda is the earning rate, m is 46998)
W2_grad = D2/m + lambda*[zeros(size(W2,1),1) W2(:,2:end)]/m;
Everything must be in place now except for the vectorized cost function which have to be minimized. Hope this helps a bit...

MatLab: Matrix with one peak and rest decreasing

I'm trying to create a matrix such that if I define a random number between 0 and 1 and a random location in the matrix, I want all the values around that to "diffuse" out. Here's sort of an example:
0.214 0.432 0.531 0.631 0.593 0.642
0.389 0.467 0.587 0.723 0.654 0.689
0.421 0.523 0.743 0.812 0.765 0.754
0.543 0.612 0.732 0.843 0.889 0.743
0.322 0.543 0.661 0.732 0.643 0.694
0.221 0.321 0.492 0.643 0.521 0.598
if you notice, there's a peak at (4,5) = 0.889 and all the other numbers decrease as they move away from that peak.
I can't figure out a nice way to generate a code that does this. Any thoughts? I need to be able to generate this type of matrix with random peaks and a random rate of decrease...
Without knowing what other constraints you want to implement:
Come up with a function z = f(x,y) whose peak value is at (x0,y0) == (0,0) and whose values range between [0,1]. As an example, the PDF for the Normal distribution with mu = 0 and sigma = 1/sqrt(2*pi) has a peak at x == 0 of 1.0, and whose lower bound is zero. Similarly, a bivariate normal PDF with mu = {0,0} and determinate(sigma) == [1/(2*pi)]^2 will have similar characteristics.
Any mathematical function may have its domain shifted: f(x-x0, y-y0)
Your code will look something like this:
someFunction = #(x,y) theFunctionYouPicked(x,y);
[x0,y0,peak] = %{ you supply these values %};
myFunction = #(x,y) peak * someFunction(x - x0, y - y0);
[dimX,dimY] = %{ you supply these values %};
mymatrix = bsxfun( myFunction, 0:dimX, (0:dimY)' );
You can read more about bsxfun here; however, here's an example of how it works:
bsxfun( blah, [a b c], [d e f]' )
That should give the following matrix (or its transpose ... I don't have matlab in front of me):
[blah(a,d) blah(a,e) blah(a,f);
blah(b,d) blah(b,e) blah(b,f);
blah(c,d) blah(c,e) blah(c,f)]
Get a toy example working, then you can tinker with it to be more flexible. If the function dictating how it decreases is random (with the constraint that points closer to (x0,y0) are larger than more distant points), it won't be an issue to make a procedural function instead of using strictly mathematical ones.
In response to your answer:
Your equation could be thought of as a model for gravity where an object instantaneously induces a force on another mass, then stops exerting force. Following that logic, it could be modified to a naive vector formulation like this:
% v1 & v2 are vectors that point from the two peak points to the point [ii,jj]
theMatrix(ii,jj) = norm( (r1 / norm( v1 )) * v1 / norm( v1 ) ...
+ (r2 / norm( v2 )) * v2 / norm( v2 ) ...
);
The most extreme type of corner case you'll run into is one where v1 & v2 point in the same direction as in the following row:
[ . . A X1 X2 . . ]
... where you want a value for A w/respect to X1 & X2. Using the above expression it'll boil down to A = X1 / norm(v1) + X2 / norm(v2), which will definitely exceed the peak value at X1 because norm(v1) == 1. You could certainly do some dirty stuff to Band-Aid it, but personally I'd start looking for a different function.
Along those lines, if you used Newton's Law of Universal Gravitation with a few modifications:
You wouldn't need an analogue for G, so you could just assume G == 1
Treat each of the points in the matrix as having mass m2 == 1, so the equation reduces to: F_12 == -1 * (m1 / r^2) * RHAT_12
Sum the "force" vectors and calculate the norm to get each value
... you'll still run into the same problem. The corner case I laid out above would boil down to A = X1/norm(v1)^2 + X2/norm(v2)^2 == X1 + X2/4. Since it's inversely proportional to the square of the distances, it'd be easier to Band-Aid than the linear one, but I wouldn't recommend it.
Similarly, if you use polynomials it won't scale well; you can design one that won't ever exceed your chosen peaks, but there wouldn't be a lower bound.
You could use the logistic function to help with this:
1 / (1 + E^(-c*x))
Here's an example of using the logistic function on a degree 4 polynomial with peaks at points 2 & 4; you'll note I gave the polynomial a scaling factor to pull the polynomial down to relatively small values so calculated values aren't so close together.
I ended up creating a code that wraps the way I want based on a dimension, which I provide. Here's the code:
dims = 100;
A = zeros(dims);
b = floor(1+dims*rand(1));
c = floor(1+dims*rand(1));
d = rand(1);
x1 = c;
y1 = b;
A(x1,y1) = d;
for i = 1:dims
for j = i
k = 1-j;
while k <= j
if x1-j>0 && y1+k>0 && y1+k <= dims
if A(x1-j,y1+k) == 0
A(x1-j,y1+k) = eqn(d,x1-j,y1+k,x1,y1);
end
end
k = k+1;
end
end
for k = i
j = 1-k;
while j<=k
if x1+j>0 && y1+k>0 && y1+k <= dims && x1+j <= dims
if A(x1+j,y1+k)==0
A(x1+j, y1+k) = eqn(d,x1+j,y1+k,x1,y1);
end
end
j = j+1;
end
end
for j = i
k = 1-j;
while k<=j
if x1+j>0 && y1-k>0 && x1+j <= dims && y1-k<= dims
if A(x1+j,y1-k) == 0
A(x1+j,y1-k) = eqn(d,x1+j,y1-k,x1,y1);
end
end
k=k+1;
end
end
for k = i
j = 1-k;
while j<=k
if x1-j>0 && y1-k>0 && x1-j <= dims && y1-k<= dims
if A(x1-j,y1-k)==0
A(x1-j,y1-k) = eqn(d,x1-j,y1-k,x1,y1);
end
end
j = j+1;
end
end
end
colormap('hot');
imagesc(A);
colorbar;
If you notice, the code calls a function (I called it eqn), which provided the information for how to changes the values in each cell. The function that I settled on is d/distance (distance being computed using the standard distance formula).
It seems to work pretty well. I'm now just trying to develop a good way to have multiple peaks in the same square without one peak completely overwriting the other.