I want to make a function that computes the value of the Scallop loss for a Rectangular, Hamming and Blackman window using the Scallop loss formula.
I have created a function but it only returns that answer 0, have I made an error?
function s_l = scallop loss(len)
window = rectwin(len);
num_total = 0;
den_total = 0;
for n = 0:len-1
A1 = exp(-((1i*(n)*pi)/len));
A2 = window(n+1)*A1;
num = abs(A2);
den = win(n+1);
num_total = num_total + num;
den_total = den_total + den:
end
result = 20*log(num_total/den_total);
s_l = result;
You have a maths problem:
abs(sum(A)) != sum(abs(A))
They are not the same!
Change your code to:
window = rectwin(len);
num_total = 0;
den_total = 0;
for n = 0:len-1
A1 = exp(-((1i*(n)*pi)/len));
A2 = window(n+1)*A1;
num = A2; % !!
den = abs(window(n+1)); % you also forgot the abs here
num_total = num_total + num;
den_total = den_total + den;
end
num_total=abs(num_total); % !!
result = 20*log(num_total/den_total);
s_l = result;
please change the log() function to log10(). without it the result is completely wrong :)
I mean this line:
result = 20*log10*(num_total/den_total);
Related
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.)
function Test()
a = 2;
b = 1;
c = 0.5;
q = 0.001;
r = 10;
function F = Useful(x) %calculates existing values for x with size 11
eq1 = (1*(0.903*x(2))^(-1))-(0.903*x(1));
eq2 = (1*(0.665*x(3))*(0.903*x(2))^(-1))-0.903*x(4);
eq3 = (1*(0.399*x(5))*(0.903*x(2)))-0.665*x(6);
eq4 = (1*(0.399*x(5))*(0.903*x(2))^2)-0.903*x(7);
eq5 = (1*(0.399*x(5))*(0.903*x(2))^3)-1*x(8);
eq6 = (1*(0.665*x(3))*(0.399*x(5))*(0.903*x(2)))-1*x(9);
eq7 = (1*(0.665*x(3))*(0.399*x(5))*(0.903*x(2))^2)-0.903*x(10);
eq8 = (1*(0.665*x(3))*(0.399*x(5)))-0.903*x(11);
eq9 = x(3)+x(4)+x(9)+x(10)+x(11)-a;
eq10 = x(5)+x(6)+x(7)+x(8)+x(9)+x(10)+x(11)-b;
eq11 = x(2)+x(6)+2*x(7)+3*x(8)+x(9)+2*x(10)-x(1)-x(4)-c;
F = [eq1;eq2;eq3;eq4;eq5;eq6;eq7;eq8; eq9; eq10; eq11];
end
Value(1,1) = 0;
for d = 2:100
x = fsolve(#Useful,x0,options); %Produces the x(1) to x(11) values
Value(1,d) = (x(3)+x(5))*d+Value(1,d-1); %Gives a new value after each iteration
a = a-x(3);
b = b-x(5);
c = c-x(2);
end
function Zdot = rhs(t,z) %z = (e1,e2,e3,e4,e5)
Zdot=zeros(5,1);
Zdot(1) = -1*z(1);
Zdot(2) = 1*z(1);
Zdot(3) = 1*z(1) - 1*z(2)*z(3);
Zdot(4) = 1*1*z(1) - Value(1,100)*H(z(3))*z(4)*z(4);
Zdot(5) = Value(1,100)*H(z(3))*(z(4));
end
function hill = H(x)
hill = q/(q+x^r);
end
[T,Y] = ode15s(#rhs, [0, 120], [1, 0, 1, 0, 0]); %Solve second function with values giving z(1) to z(5)
plot(T,Y(:,5))
end
I'm wondering, is it possible to pass on each Value obtained (Value (1), Value (2)... so on), into "function Zdot" or is only the final value possible to pass on? Essentially is this possible to implement:
function Zdot = rhs(t,z) %z = (e1,e2,e3,e4,e5)
Zdot=zeros(5,1);
Zdot(1) = -1*z(1);
Zdot(2) = 1*z(1);
Zdot(3) = 1*z(1) - 1*z(2)*z(3);
Zdot(4) = 1*1*z(1) - Value(1,d)*H(z(3))*z(4)*z(4);
Zdot(5) = Value(1,d)*H(z(3))*(z(4));
end
Any insights would be much appreciated and I would be extremely grateful. Thank you in advance!
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
I'm trying to implement k-NN in matlab. I have a matrix of 214 x's that have 9 columns of attributes with the 10th column being the label. I want to measure loss with a 0-1 function on 10 cross-validation tests. I have the following code:
function q3(file)
data = knnfile(file);
loss(data(:,1:9),'KFold',data(:,10))
losses = zeros(25,3);
new_data = data;
new_data(:,10) = [];
sdd = std(new_data);
meand = mean(new_data);
for s = 1:214
for q = 1:9
new_data(s,q) = (new_data(s,q) - meand(q)) / sdd(q);
end
end
new_data = [new_data data(:,10)];
for k = 1:25
loss1 = 0;
loss2 = 0;
for j = 0:9
index = floor(214/10)*j+1;
curd1 = data([1:index-1,index+21:end],:);
curd2 = new_data([1:index-1,index+21:end],:);
for l = 0:20
c1 = knn(curd1,k,data(index+l,:));
c2 = knn(curd2,k,new_data(index+l,:));
loss1 = loss1 + (c1 ~= data(index+l,10));
loss2 = loss2 + (c2 ~= new_data(index+l,10));
end
end
losses(k,1) = k;
losses(k,2) = 100*loss1/210;
losses(k,3) = 100*loss2/210;
end
function cluster = knn(Data,k,x)
distances = zeros(193,2);
for i = 1:size(Data,1)
row = Data(i,:);
d = norm(row(1:size(row,2)-1) - x(1:size(x,2)-1));
distances(i,:) = [d row(10)];
end
distances = sortrows(distances,1);
cluster = mode(distances(1:k,2));
I'm getting 40%+ loss with almost no correlation to k and I'm sure that something here is wrong but I'm not quite sure.
Any help would be appreciated!
I executed this code using Feature Matrix 517*11 and Label Matrix 517*1. But once the dimensions of matrices change the code cant be run. How can I fix this?
The error is:
Subscripted assignment dimension mismatch.
in this line :
edges(k,j) = quantlevels(a);
Here is my code:
function [features,weights] = MI(features,labels,Q)
if nargin <3
Q = 12;
end
edges = zeros(size(features,2),Q+1);
for k = 1:size(features,2)
minval = min(features(:,k));
maxval = max(features(:,k));
if minval==maxval
continue;
end
quantlevels = minval:(maxval-minval)/500:maxval;
N = histc(features(:,k),quantlevels);
totsamples = size(features,1);
N_cum = cumsum(N);
edges(k,1) = -Inf;
stepsize = totsamples/Q;
for j = 1:Q-1
a = find(N_cum > j.*stepsize,1);
edges(k,j) = quantlevels(a);
end
edges(k,j+2) = Inf;
end
S = zeros(size(features));
for k = 1:size(S,2)
S(:,k) = quantize(features(:,k),edges(k,:))+1;
end
I = zeros(size(features,2),1);
for k = 1:size(features,2)
I(k) = computeMI(S(:,k),labels,0);
end
[weights,features] = sort(I,'descend');
%% EOF
function [I,M,SP] = computeMI(seq1,seq2,lag)
if nargin <3
lag = 0;
end
if(length(seq1) ~= length(seq2))
error('Input sequences are of different length');
end
lambda1 = max(seq1);
symbol_count1 = zeros(lambda1,1);
for k = 1:lambda1
symbol_count1(k) = sum(seq1 == k);
end
symbol_prob1 = symbol_count1./sum(symbol_count1)+0.000001;
lambda2 = max(seq2);
symbol_count2 = zeros(lambda2,1);
for k = 1:lambda2
symbol_count2(k) = sum(seq2 == k);
end
symbol_prob2 = symbol_count2./sum(symbol_count2)+0.000001;
M = zeros(lambda1,lambda2);
if(lag > 0)
for k = 1:length(seq1)-lag
loc1 = seq1(k);
loc2 = seq2(k+lag);
M(loc1,loc2) = M(loc1,loc2)+1;
end
else
for k = abs(lag)+1:length(seq1)
loc1 = seq1(k);
loc2 = seq2(k+lag);
M(loc1,loc2) = M(loc1,loc2)+1;
end
end
SP = symbol_prob1*symbol_prob2';
M = M./sum(M(:))+0.000001;
I = sum(sum(M.*log2(M./SP)));
function y = quantize(x, q)
x = x(:);
nx = length(x);
nq = length(q);
y = sum(repmat(x,1,nq)>repmat(q,nx,1),2);
I've run the function several times without getting any error.
I've used as input for "seq1" and "seq2" arrays such as 1:10 and 11:20
Possible error might rise in the loops
for k = 1:lambda1
symbol_count1(k) = sum(seq1 == k);
end
if "seq1" and "seq2" are defined as matrices since sum will return an array while
symbol_count1(k)
is expected to be single value.
Another possible error might rise if seq1 and seq2 are not of type integer since they are used as indexes in
M(loc1,loc2) = M(loc1,loc2)+1;
Hope this helps.