Here's my code for a k-nearest neighbors algorithm:
function [preds, distances, indices] = knnfull(HandTrain,HandTest)
nn_value = 10; % how many nearest
inputs = HandTrain(:,2:end);
Y = HandTrain(:,1);
[preds, distances, indices] = knn_alg(inputs, y, HandTest, nn_value);
end
function [preds, D, I] = knn_alg(train_inputs, train_y, test_inputs, nn_value)
num_train_inputs = size(train_inputs,2);
num_train_examples = size(train_inputs,1)
num_test_inputs = size(test_inputs,2);
num_test_examples = size(test_inputs,1)
preds = zeros(size(test_inputs,1),1);
[D,I] = pdist2(train_inputs,test_inputs,'euclidean','Smallest',nn_value);
preds = mode(train_y(I'),2);
end
If you're asking why I have two separate functions, that's a good question. But regardless, I'm getting the errors:
Error in knnkaggle>knn_alg (line 16)
num_train_inputs = size(train_inputs,2);
Output argument "indices" (and maybe others) not assigned during call to
"C:...knn_alg".
Error in knnkaggle (line 10)
[preds, distances, indices] = knn_alg(inputs, y, HandTest, nn_value);
Can't figure out the issue.
It means that there are possible paths through your function which don't assign any value at all to the output argument.
Related
I have this matlab function to calculate the cosine similarity between 60 vectors of a dataset. 60 rows correspond to the vector number and 2 columns to the x and y components of each vector.
function [cosSim] = cosineSimilarity(data)
[n_row n_col] = size(data);
norm_r = sqrt(sum(abs(data).^2,2));
for i = 1:n_row
for j = i:n_row
cosSim(i,j) = dot(data(i,:), data(j,:)) / (norm_r(i) * norm_r(j));
cosSim(j,i) = cosSim(i,j);
end
end
end
The main script:
cd(matlabroot)
cd('help/toolbox/stats/examples')
ds = dataset('XLSFile','TestCosSim.xlsx');
c = cosineSimilarity(ds);
When I run the script, I get the following errors:
Undefined operator '.^' for input arguments of type 'dataset'.
Error in cosineSimilarity (line 8)
norm_r = sqrt(sum(data.^2,2));
Error in CosSimTest (line 6)
c = cosineSimilarity(ds);
Does anybody have an idea of why this is happening?
Thanks a lot in advance.
I am trying to compute the convolution of a sound signal without using the built in conv function but instead using arrays. x is the input signal and h is are the impulse responses. However, when I run my other main function to call onto my_conv I am getting these errors:
Undefined function or variable 'nx'.**
Error in my_conv (line 6)
ly=nx+nh-1;
Error in main_stereo (line 66)
leftchannel = my_conv(leftimp, mono); % convolution of left ear impulse response and mono
This is my function my_conv:
function [y]=my_conv(x,h)
x=x(:);
h=h(:);
lx=length(x);
lh=length(h);
ly=nx+nh-1;
Y=zeros(nh,ny);
for i =1:nh
Y((1:nx)+(i-1),i)=x;
end
y=Y*h;
What changes should I make to fix these errors and get this code running?
I am trying to immplement the function into this code:
input_filename = 'speech.wav';
stereo_filename = 'stereo2.wav';
imp_filename = 'H0e090a.dat';
len_imp = 128;
fp = fopen(imp_filename, 'r', 'ieee-be');
data = fread(fp, 2*len_imp, 'short');
fclose(fp);
[mono,Fs] = audioread(input_filename);
if (Fs~=44100)
end
len_mono = length(mono);
leftimp = data(1:2:2*len_imp);
rightimp = data(2:2:2*len_imp);
leftchannel = my_conv(leftimp, mono);
rightchannel = my_conv(rightimp, mono);
leftchannel = reshape(leftchannel , length(leftchannel ), 1);
rightchannel = reshape(rightchannel, length(rightchannel), 1);
norml = max(abs([leftchannel; rightchannel]))*1.05;
audiowrite(stereo_filename, [leftchannel rightchannel]/norml, Fs);
As pointed out by #SardarUsama in comments, the error
Undefined function or variable 'nx'.
Error in my_conv (line 6) ly=nx+nh-1;
tells you that the variable nx has not been defined before before its usage on the line ly=nx+nh-1. Given the naming of the variables and their usage, it looks like what you intended to do was:
nx = length(x);
nh = length(h);
ny = nx+nh-1;
After making these modifications and solving the first error, you are likely going to get another error telling you that
error: my_conv: operator *: nonconformant arguments
This error is due to an inversion in the specified size of the Y matrix. This can be fixed by initializing Y with Y = zeros(ny, nh);. The resulting my_conv function follows:
function [y]=my_conv(x,h)
nx=length(x);
nh=length(h);
ny=nx+nh-1;
Y=zeros(ny,nh);
for i =1:nh
Y((1:nx)+(i-1),i)=x;
end
y=Y*h;
Note that storing every possible shifts of one of the input vectors in the matrix Y to compute the convolution as a matrix multiplication is not very memory efficient (requiring O(NM) storage). A more memory efficient implementation would compute each element of the output vector directly:
function [y]=my_conv(x,h)
nx=length(x);
nh=length(h);
if (nx < nh)
y = my_conv(h,x);
else
ny=nx+nh-1;
y = zeros(1,ny);
for i =1:ny
idh = [max(i-(ny-nh),1):min(i,nh)]
idx = [min(i,nx):-1:max(nx-(ny-i),1)]
y(i) = sum(x(idx).*h(idh));
end
end
An alternate implementation which can be more computationally efficient for large arrays would make use of the convolution theorem and use the Fast Fourier Transform (FFT):
function [y]=my_conv2(x,h)
nx=length(x);
nh=length(h);
ny=nx+nh-1;
if (size(x,1)>size(x,2))
x = transpose(x);
end
if (size(h,1)>size(h,2))
h = transpose(h);
end
Xf = fft([x zeros(size(x,1),ny-nx)]);
Hf = fft([h zeros(size(h,1),ny-nh)]);
y = ifft(Xf .* Hf);
I am trying to use bvp4c to solve a system of 4 odes. The issue is that one of the boundaries is unknown.
Can bvp4c handle this? In my code L is the unknown I am solving for.
I get an error message printed below.
function mat4bvp
L = 8;
solinit = bvpinit(linspace(0,L,100),#mat4init);
sol = bvp4c(#mat4ode,#mat4bc,solinit);
sint = linspace(0,L);
Sxint = deval(sol,sint);
end
% ------------------------------------------------------------
function dtdpdxdy = mat4ode(s,y,L)
Lambda = 0.3536;
dtdpdxdy = [y(2)
-sin(y(1)) + Lambda*(L-s)*cos(y(1))
cos(y(1))
sin(y(1))];
end
% ------------------------------------------------------------
function res = mat4bc(ya,yb,L)
res = [ ya(1)
ya(2)
ya(3)
ya(4)
yb(1)];
end
% ------------------------------------------------------------
function yinit = mat4init(s)
yinit = [ cos(s)
0
0
0
];
end
Unfortunately I get the following error message ;
>> mat4bvp
Not enough input arguments.
Error in mat4bvp>mat4ode (line 13)
-sin(y(1)) + Lambda*(L-s)*cos(y(1))
Error in bvparguments (line 105)
testODE = ode(x1,y1,odeExtras{:});
Error in bvp4c (line 130)
bvparguments(solver_name,ode,bc,solinit,options,varargin);
Error in mat4bvp (line 4)
sol = bvp4c(#mat4ode,#mat4bc,solinit);
One trick to transform a variable end point into a fixed one is to change the time scale. If x'(t)=f(t,x(t)) is the differential equation, set t=L*s, s from 0 to 1, and compute the associated differential equation for y(s)=x(L*s)
y'(s)=L*x'(L*s)=L*f(L*s,y(s))
The next trick to employ is to transform the global variable into a part of the differential equation by computing it as constant function. So the new system is
[ y'(s), L'(s) ] = [ L(s)*f(L(s)*s,y(s)), 0 ]
and the value of L occurs as additional free left or right boundary value, increasing the number of variables = dimension of the state vector to the number of boundary conditions.
I do not have Matlab readily available, in Python with the tools in scipy this can be implemented as
from math import sin, cos
import numpy as np
from scipy.integrate import solve_bvp, odeint
import matplotlib.pyplot as plt
# The original function with the interval length as parameter
def fun0(t, y, L):
Lambda = 0.3536;
#print t,y,L
return np.array([ y[1], -np.sin(y[0]) + Lambda*(L-t)*np.cos(y[0]), np.cos(y[0]), np.sin(y[0]) ]);
# Wrapper function to apply both tricks to transform variable interval length to a fixed interval.
def fun1(s,y):
L = y[-1];
dydt = np.zeros_like(y);
dydt[:-1] = L*fun0(L*s, y[:-1], L);
return dydt;
# Implement evaluation of the boundary condition residuals:
def bc(ya, yb):
return [ ya[0],ya[1], ya[2], ya[3], yb[0] ];
# Define the initial mesh with 5 nodes:
x = np.linspace(0, 1, 3)
# This problem has multiple solutions. Try two initial guesses.
L_a=8
L_b=9
y_a = odeint(lambda y,t: fun1(t,y), [0,0,0,0,L_a], x)
y_b = odeint(lambda y,t: fun1(t,y), [0,0,0,0,L_b], x)
# Now we are ready to run the solver.
res_a = solve_bvp(fun1, bc, x, y_a.T)
res_b = solve_bvp(fun1, bc, x, y_b.T)
L_a = res_a.sol(0)[-1]
L_b = res_b.sol(0)[-1]
print "L_a=%.8f, L_b=%.8f" % ( L_a,L_b )
# Plot the two found solutions. The solution are in a spline form, use this to produce a smooth plot.
x_plot = np.linspace(0, 1, 100)
y_plot_a = res_a.sol(x_plot)[0]
y_plot_b = res_b.sol(x_plot)[0]
plt.plot(L_a*x_plot, y_plot_a, label='L=%.8f'%L_a)
plt.plot(L_b*x_plot, y_plot_b, label='L=%.8f'%L_b)
plt.legend()
plt.xlabel("t")
plt.ylabel("y")
plt.grid(); plt.show()
which produces
Trying different initial values for L finds other solutions on quite different scales, among them
L=0.03195111
L=0.05256775
L=0.05846539
L=0.06888907
L=0.08231966
L=4.50411522
L=6.84868060
L=20.01725616
L=22.53189063
I am trying to link SimEvent and the optimization module of MATLAB. For that, I first need to define a function that runs the simulation then call it in an optimization function. I got the idea of the simulation/optimization code from the link below:
http://au.mathworks.com/videos/optimizing-manufacturing-production-processes-68961.html
I tried to go through all the code I see in this video but, when I am applying it, it is not working. Here is my code:
function finalresults = SimOpt ()
intcon = [1];
A=[];
b=[];
Aeq=[];
beq = [];
lb = [1];
ub= [10];
finalresults= intlinprog(#f,intcon,A,b,Aeq,beq,lb,ub);
function obj = f(vecX)
NumServers = vecX(1);
NumTruck = vecX(2);
set_param('concreting10/Positioning and Unloading','NumberOfServers',num2str(NumServers));
set_param('concreting10/Washing','NumberOfServers',num2str(NumTruck));
simOut = sim('concreting10','SaveOutput','on','OutputSaveName','WaitingTimeInQueue');
z = simOut.get('WaitingTimeInQueue');
waiting = max(z);
cost = [100 200]*vecX';
obj = waiting*1000+cost;
end
end
When I run the whole code I get this warning:
Error using intlinprog (line 122) INTLINPROG requires the following inputs to be of data type double: 'f'.
Error in SimOpt (line 26) finalresults= intlinprog(#f,intcon,A,b,Aeq,beq,lb,ub);
Any help will be appreciated.
Change the last line in the function to
obj = waiting * 1000.0 + cost
MATLAB and many other HLLs convert data type to integer if multiplied by an integer type constant value. So it is necessary to multiply the constant as double type by adding a decimal point.
I am interested in writing some matrix elements as functions which can take value as per my convenience and then the required matrix operations can be applied on top of that. More precisely, I am trying to integrate over x, the trace of a matrix which has matrix elements as functions of x (which are unknown analytically as they come through products of matrices dependent on x) .
When I try to write the matrix elements as functions, then I obviously get the error- Conversion to double from function_handle is not possible. Is there an easy way to write the matrix elements as functions ?
Thanks. Please ask if my question is not clear.
For example, its something like this:-
N_k = 10;
M_sigma = cell(N_k,1);
M_rho = cell(N_k,1);
for ii = 1:N_k
M_sigma {ii}(1,2) = #(sigma) sigma; %this kind of thing is not allowed in matlab
M_sigma {ii}(2,1) = #(sigma) -conj(sigma);
M_sigma {ii}(1,1) = 0;
M_sigma {ii}(2,2) = 0;
end
for ii = 1:N_k
M_rho {ii}(1,2) = #(rho) rho;
M_rho {ii}(2,1) = #(rho) -conj(rho);
M_rho {ii}(1,1) = 0;
M_rho {ii}(2,2) = 0;
end
M_tau = cell(N_k,1);
for ii = 1:N_k
M_tau {ii} = exp(M_sigma{ii})*exp(M_rho{ii});
end
% the following statement is wrong but I want to do something like
%:-write M_tau as a function of sigma and sum(integrate) the trace of M_tau for all values of sigma
integral(#(sigma) M_tau{1}(sigma), {0,1})
I don't think that you would be able to accomplish that with function handles. I think the best way you could do it would be to define a function as follows :
function x = myFunction(rowindex,colindex)
x = x * rowindex + colindex;
end
You would replace this function with your algorithm and then you could iterate over it doing the following:
for a=1:10
for b=1:10
x(a,b)=myFunction(a,b);
end
end