Why is this function producing a value of 'Inf'? - matlab

I have the following function below which I need to translate into MATLAB code, I'm pretty sure I've got the function translated properly. However I've got a small issue with the code.
Function to translate:
When I attempt to run this function the value of phi comes out as being inf I'm really not sure why this is happening?
Also, can someone tell me if I'm doing the right thing with the sum part of this function? In my mind this is telling me to apply this function to every value and then take that value and add it to phi, but I'm not sure if that's what I'm actually doing.
function [exists] = detectHaarWatermark(watermarkedCoefs, watermark)
coefsSize = size(watermarkedCoefs,1);
phi = 0;
numeratorTotal = 0;
denomanatorTotal = 0;
for i = 1 : coefsSize
for j = 1 : coefsSize
y = watermarkedCoefs(i,j) %Watermarked coefficient
w = watermark(i,j) %Watermark
% val = ((w * sign(y))^2) / (w^2)
numerator = (w * sign(y))
numeratorTotal = numeratorTotal + numerator;
numeratorTotal = numeratorTotal^2;
denomanator = (w^2)
denomanatorTotal = denomanatorTotal + denomanator;
val = numeratorTotal / denomanatorTotal;
phi = val;
end
end
phi
stdDev = std2(watermarkedCoefs)
if phi > (10*stdDev)
exists = true;
else
exists = false;
end
end %end function
Edit:
numerator = (sum(sum(watermark.*(sign(watermarkedCoefs)))));
numerator = power(numerator, 2);
denomanator = sum(sum(watermark.^2));
phi = numerator / denomanator

Related

How can it be that a function is outputing a vector with 38 elements and Simulink takes it as one element?

In the Simulink model below my interpreted function output is a vector with 38 elements. I have two functions that have the same outputs one of them works perfectly (desiredtrajectory_sim.m) but the other one doesn't (desiredtrajectory.m).
Any suggestions. thanks
Here is the Simulink model
function [desired_state] = desiredtrajectory_sim(in)
t = in(1);
Sf = [ 1; 2; pi/4];
dSf = [0;0;0];
Pf = [ 0.1*t; 0; 0.5*sin(0.03*pi*t) + 2; 0; 0.01*pi*t ; 0];
dPf = [ 0.1; 0; 0.5*0.03*pi*cos(0.03*pi*t); 0; 0.01*pi; 0];
pf = Sf(1); qf = Sf(2); betaf = Sf(3);
xf = Pf(1); yf = Pf(2); zf = Pf(3);
phif = Pf(4); thetaf = Pf(5); psif = Pf(6);
rf = sqrt(pf^2 + qf^2 - 2*pf*qf*cos(betaf));
h1 = sqrt(0.5*(pf^2 + qf^2 - 0.5*rf^2));
h2 = sqrt(0.5*(rf^2 + pf^2 - 0.5*qf^2));
h3 = sqrt(0.5*(qf^2 + rf^2 - 0.5*pf^2));
alpha1 = acos((4*(h1^2+h2^2)-9*pf^2)/(8*h1*h2));
alpha2 = acos((4*(h1^2+h3^2)-9*qf^2)/(8*h1*h3));
Rot = RPYtoRot_ZXY(phif, thetaf, psif);
r1 = Rot*[2/3*h1;0;0];
r2 = Rot*[2/3*h2*cos(alpha1);2/3*h2*sin(alpha1);0];
r3 = Rot*[2/3*h3*cos(alpha2);-2/3*h3*sin(alpha2);0];
pos_des1 = [xf;yf;zf] + r1;
pos_des2 = [xf;yf;zf] + r2;
pos_des3 = [xf;yf;zf] + r3;
omega = [0 -sin(psif) cos(thetaf)*cos(psif);...
0 -cos(psif) cos(thetaf)*sin(psif);...
1 0 -sin(thetaf)]*dPf(4:6);
vel_des1 = dPf(1:3) + cross(omega, r1);
vel_des2 = dPf(1:3) + cross(omega, r2);
vel_des3 = dPf(1:3) + cross(omega, r3);
acc_des = [0;0;0];
desired_state1 = [pos_des1;vel_des1;acc_des];
desired_state2 = [pos_des2;vel_des2;acc_des];
desired_state3 = [pos_des3;vel_des3;acc_des];
desired_state = [desired_state1;desired_state2;desired_state3; psif; 0; Pf;
Sf]
size(desired_state)
end
Here is the Simulink block and the error message
As you can notice the bus gives just one element compared to the previous one which gives 38 elements, although they have the same output.
function [desired_state] = desiredtrajectory(in)%(t, pos)
tm= in(1)
pos = in(2:10);
syms t xf yf zf phif thetaf psif pf qf betaf
rf = sqrt(pf^2+qf^2-2*pf*qf*cos(betaf));
h1 = sqrt(0.5*(pf^2+qf^2-0.5*rf^2));
h2 = sqrt(0.5*(rf^2+pf^2-0.5*qf^2));
h3 = sqrt(0.5*(qf^2+rf^2-0.5*pf^2));
alf1 = acos((4*(h1^2+h2^2)-9*pf^2)/(8*h1*h2));
alf2 = acos((4*(h1^2+h3^2)-9*qf^2)/(8*h1*h3));
Rot = RPYtoRot_ZXY(phif, thetaf, psif);
eps = [Rot*[2/3;0;0]+[xf;yf;zf]
Rot*[2/3*h2*cos(alf1);2/3*h2*sin(alf1);0]+[xf;yf;zf]
Rot*[2/3*h2*cos(alf2);-2/3*h3*sin(alf2);0]+[xf;yf;zf]];
X = [ xf yf zf phif thetaf psif pf qf betaf];
Sf = [ 1; 2; pi/4];
dSf = [0;0;0];
Pf = [ 0.1*t; 0; 0.5*sin(0.03*pi*t) + 2; 0; 0.01*pi*t ; 0];
dPf = [ 0.1; 0; 0.5*0.03*pi*cos(0.03*pi*t); 0; 0.01*pi; 0];
qd = [Pf; Sf];
qddot = [dPf; dSf];
jac = jacobian(eps,X);
%%%%%%%%%%%%%
pf = Sf(1); qf = Sf(2); betaf = Sf(3);
xf = Pf(1); yf = Pf(2); zf = Pf(3);
phif = Pf(4); thetaf = Pf(5); psif = Pf(6);
x1=pos(1);
y1=pos(2);
z1=pos(3);
x2=pos(4);
y2=pos(5);
z2=pos(6);
x3=pos(7);
y3=pos(8);
z3=pos(9);
qpf=[(x1+x2+x3)/3;...
(y1+y2+y3)/3;...
(z1+z2+z3)/3;...
atan2((2*z1/3-z2/3-z3/3),(2*y1/3-y2/3-y3/3)); ...
-atan2((2*z1/3-z2/3-z3/3),(2*x1/3-x2/3-x3/3)); ...
atan2((2*y1/3-y2/3-y3/3),(2*x1/3-x2/3-x3/3))];
qsf=[sqrt((x1-x2)^2+(y1-y2)^2+(z1-z2)^2); ...
sqrt((x1-x3)^2+(y1-y3)^2+(z1-z3)^2); ...
acos((pf^2+qf^2-rf^2)/(2*pf*qf))];
q = [qpf;qsf];
%%%%%%%%%%%%%
%%%pos_desired%%%%%%%
pos_des = eval(eps);
pos_des =subs(pos_des,t,tm);
jacval = eval(jac);
qd = eval(qd);%subs(qd,t,tm);
q = eval(q);
qe = qd - q;
qddot = eval(qddot);%subs(qddot,t,tm);
kappa=0.2*eye(9);
qrefdot = qddot + kappa*qe;
vel_des = jacval*qrefdot;
vel_des = subs(vel_des,t,tm);
acc_des = zeros(3,1);
yaw = 0;
yawdot = 0;
% =================== Your code ends here ===================
desired_state1 = [pos_des(1:3);vel_des(1:3);acc_des];
desired_state2 = [pos_des(4:6);vel_des(4:6);acc_des];
desired_state3 = [pos_des(7:9);vel_des(7:9);acc_des];
Pf = subs(Pf,t,tm);
Sf = subs(Sf,t,tm);
format short
digits(3);
desired_state = vpa([desired_state1;desired_state2;desired_state3; psif; 0;
Pf; Sf])
size(desired_state)
end
The second image shows that the output of the second function is a scalar - the dimension at the output of the block is 1 - not 38 as you believe it is.
That is, your functions do not give the same output as you believe they do.
The error is because the Selector blocks expect their inputs to be dimension 38, and they are not.
To determine why what you believe is happening is not actually what is happening, you could use the editor to set a break point in the m-code, run the model, then step through the code to determine why it gives a scalar output when you expect it to do otherwise.
Another approach would be to run your functions from the MATLAB Command Line with fake input data. Something like
tmp = desiredtrajectory(randn(10,1))
would be appropriate here.
The answer is that desiredtrajectory outputs desired_state, which is a symbolic variable. Yes it contains a 38 element vector, but Simulink treats the object itself is a scalar.
The real problem though is that you can't propagate a symbolic variable down a Simulink signal. You need the output to be a numeric vector.
One way to overcome this is to put the line
desired_state = double(desired_state);
at the end of your file to cast the symbolic object to a double, which will have 38 elements.
(However it's not clear why you are using symbolic math in the first place, and I'd suggest it would be better, and is certainly more efficient, if you didn't use it.)

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)

Error in evaluating a function

EDIT: The code that I have pasted is too long. Basicaly I dont know how to work with the second code, If I know how calculate alpha from the second code I think my problem will be solved. I have tried a lot of input arguments for the second code but it does not work!
I have written following code to solve a convex optimization problem using Gradient descend method:
function [optimumX,optimumF,counter,gNorm,dx] = grad_descent()
x0 = [3 3]';%'//
terminationThreshold = 1e-6;
maxIterations = 100;
dxMin = 1e-6;
gNorm = inf; x = x0; counter = 0; dx = inf;
% ************************************
f = #(x1,x2) 4.*x1.^2 + 2.*x1.*x2 +8.*x2.^2 + 10.*x1 + x2;
%alpha = 0.01;
% ************************************
figure(1); clf; ezcontour(f,[-5 5 -5 5]); axis equal; hold on
f2 = #(x) f(x(1),x(2));
% gradient descent algorithm:
while and(gNorm >= terminationThreshold, and(counter <= maxIterations, dx >= dxMin))
g = grad(x);
gNorm = norm(g);
alpha = linesearch_strongwolfe(f,-g, x0, 1);
xNew = x - alpha * g;
% check step
if ~isfinite(xNew)
display(['Number of iterations: ' num2str(counter)])
error('x is inf or NaN')
end
% **************************************
plot([x(1) xNew(1)],[x(2) xNew(2)],'ko-')
refresh
% **************************************
counter = counter + 1;
dx = norm(xNew-x);
x = xNew;
end
optimumX = x;
optimumF = f2(optimumX);
counter = counter - 1;
% define the gradient of the objective
function g = grad(x)
g = [(8*x(1) + 2*x(2) +10)
(2*x(1) + 16*x(2) + 1)];
end
end
As you can see, I have commented out the alpha = 0.01; part. I want to calculate alpha via an other code. Here is the code (This code is not mine)
function alphas = linesearch_strongwolfe(f,d,x0,alpham)
alpha0 = 0;
alphap = alpha0;
c1 = 1e-4;
c2 = 0.5;
alphax = alpham*rand(1);
[fx0,gx0] = feval(f,x0,d);
fxp = fx0;
gxp = gx0;
i=1;
while (1 ~= 2)
xx = x0 + alphax*d;
[fxx,gxx] = feval(f,xx,d);
if (fxx > fx0 + c1*alphax*gx0) | ((i > 1) & (fxx >= fxp)),
alphas = zoom(f,x0,d,alphap,alphax);
return;
end
if abs(gxx) <= -c2*gx0,
alphas = alphax;
return;
end
if gxx >= 0,
alphas = zoom(f,x0,d,alphax,alphap);
return;
end
alphap = alphax;
fxp = fxx;
gxp = gxx;
alphax = alphax + (alpham-alphax)*rand(1);
i = i+1;
end
function alphas = zoom(f,x0,d,alphal,alphah)
c1 = 1e-4;
c2 = 0.5;
[fx0,gx0] = feval(f,x0,d);
while (1~=2),
alphax = 1/2*(alphal+alphah);
xx = x0 + alphax*d;
[fxx,gxx] = feval(f,xx,d);
xl = x0 + alphal*d;
fxl = feval(f,xl,d);
if ((fxx > fx0 + c1*alphax*gx0) | (fxx >= fxl)),
alphah = alphax;
else
if abs(gxx) <= -c2*gx0,
alphas = alphax;
return;
end
if gxx*(alphah-alphal) >= 0,
alphah = alphal;
end
alphal = alphax;
end
end
But I get this error:
Error in linesearch_strongwolfe (line 11) [fx0,gx0] = feval(f,x0,d);
As you can see I have written the f function and its gradient manually.
linesearch_strongwolfe(f,d,x0,alpham) takes a function f, Gradient of f, a vector x0 and a constant alpham. is there anything wrong with my declaration of f? This code works just fine if I put back alpha = 0.01;
As I see it:
x0 = [3; 3]; %2-element column vector
g = grad(x0); %2-element column vector
f = #(x1,x2) 4.*x1.^2 + 2.*x1.*x2 +8.*x2.^2 + 10.*x1 + x2;
linesearch_strongwolfe(f,-g, x0, 1); %passing variables
inside the function:
[fx0,gx0] = feval(f,x0,-g); %variable names substituted with input vars
This will in effect call
[fx0,gx0] = f(x0,-g);
but f(x0,-g) is a single 2-element column vector with these inputs. Assingning the output to two variables will not work.
You either have to define f as a proper named function (just like grad) to output 2 variables (one for each component), or edit the code of linesearch_strongwolfe to return a single variable, then slice that into 2 separate variables yourself afterwards.
If you experience a very rare kind of laziness and don't want to define a named function, you can still use an anonymous function at the cost of duplicating code for the two components (at least I couldn't come up with a cleaner solution):
f = #(x1,x2) deal(4.*x1(1)^2 + 2.*x1(1)*x2(1) +8.*x2(1)^2 + 10.*x1(1) + x2(1),...
4.*x1(2)^2 + 2.*x1(2)*x2(2) +8.*x2(2)^2 + 10.*x1(2) + x2(2));
[fx0,gx0] = f(x0,-g); %now works fine
as long as you always have 2 output variables. Note that this is more like a proof of concept, since this is ugly, inefficient, and very susceptible to typos.

How convert symbolic equation to solve in ode45?

I'm trying to solve a differential equation like below:
%% Parameters Initialization
C = 0.01;
gfi = 0.2308;
gso = 0.769;
Efi = 17.333;
Eso = 0;
km = 0.842;
v12m = 5.85;
kn = 4.4;
v12n = 9.667;
tauni = 3;
%% defining Functions
syms v n;
n_v_e = 1 / (1+exp((v12n-v)/kn));
m_v = 1 / (1+exp((v12m-v)/km));
gfi_v = gfi * m_v;
Dn = tauno*(n_v_e-n);
Ifi = gfi_v*(v-Efi);
Iso = gso*n*(v-Eso);
Dv = -1/C * (Ifi + Iso);
%% Solving ODE
v0 = -10;
n0 = 0.1;
te = 2000;
Dv = subs(Dv,'v','y(1)');
Dv = subs(Dv,'n','y(2)');
Dn = subs(Dn,'v','y(1)');
Dn = subs(Dn,'n','y(2)');
[t,V] = ode45(#(t,y)[Dv;Dn],[0 te],[v0;n0]);
the problem occurs right here at ode45 saying "Inputs must be floats, namely single or double."
I know the problem is due to symbols (n and v) but I don't know how to get rid of them!
I don't also want to write a seperate function and use it instead of [Dv;Dn].
Thank you for your help

how do I integrate, a function with many arguments using matlab

If I'm to integrate a function
y = -((F+h)M^3(cosh(h*M)+M*beta*sinh(h*M)))/(h*M*cosh(h*M)+(-1+h*M^2*beta)*sinh(h*M))- (alpha*(M^2*(F+h)*(-1+2*h^2*M^2+ cosh(2*h*M)-2*h*M*sinh(2*h*M)))/(8*(h*M*cosh(h*M)+(-1+h*M^2*beta)*sinh(h*M))^2));
with respect to x, where
phi = 0.6;
x = 0.5;
M = 2;
theta = -1:0.5:1.5;
F = theta - 1;
h = 1 + phi*cos(2*pi*x);
alpha = 0.2;beta = 0.0;
I have written an Mfile
function r = parameterIntegrate(F,h,M,beta,alpha,theta,phi)
% defining a nested function that uses one variable
phi = 0.6;
x = 0.5;
r = quad(#testf,0,1 + phi*cos(2*pi*x));
% simpson's rule from 0 to h
function y = testf(x)
h = 1 + phi*cos(2*pi*x);
theta = -1:0.5:1.5;
F = theta - 1;
M = 2;
beta = 0;
alpha = 0;
y = -((F+h)*M^3*(cosh(h*M)+M*beta*sinh(h*M)))/(h*M*cosh(h*M)+(-1+h*M^2*beta)*sinh(h*M))- (alpha*(M^2*(F+h)*(-1+2*h^2*M^2+ cosh(2*h*M)-2*h*M*sinh(2*h*M)))/(8*(h*M*cosh(h*M)+(-1+h*M^2*beta)*sinh(h*M))^2));
end
end
and called the function by
tol = [1e-5 1e-3];
q = quad(#parameterIntegrate, 0, h,tol)
or
q = quad(#parameterIntegrate, 0,1 + phi*cos(2*pi*0.5),tol)
its not working its giving me
Error using ==> plus
Matrix dimensions must agree.
What your error message means is that for some line of code, there are 2 matrices, but the dimensions don't match, so it can't add them. What I suggest you do to solve this is as follows:
Figure out exactly which line of code is causing the problem.
If the line has large numbers of variables, simplify them some.
Remember that if there are any matrixs at all, and you don't want to do matrix multiplication/division, use the .*, ./, and .^.
I suspect that if you change your multiplies/divides with step 3, your problem will go away.