"Index Exceeds Matrix Dimensions" neural network function error - neural-network

I've got two datasets, which I load from a CSV file, and split them into X and T:
X (3x5000) double
T (1x5000) double
I'm trying to configure this function, but I can't
http://www.mathworks.co.uk/help/toolbox/nnet/ref/layrecnet.html
X has three features and 5000 examples. T has one feature and 5000 examples. For an example the target is feature 1 20 steps ahead. So basically X(1,21) == T(1).
[X,T] = simpleseries_dataset;
This works perfectly, in this case, I have 1x100, 1x100.
If I use my own data set, however, I get this:
X = data(:,1:3)';
T = data(:,4)';
net = layrecnet(1:2,10);
[Xs,Xi,Ai,Ts] = preparets(net,X,T);
??? Index exceeds matrix dimensions.
Error in ==> preparets at 273
ti = tt(:,FBS+((1-net.numLayerDelays):0));
I don't understand, what am I doing wrong?
UPDATE
I've noticed that my data set is T (1x5000) double while the example dataset is T (1x100) cell. What's the difference between double and cell?

I solved it by:
X = num2cell(X);
T = num2cell(T);
I have no idea why; it must be MATLAB syntax...

You can solve it by:
P = con2seq(p);
T = con2seq(t);
.....% for example
p=(1 2;3 4;5 6);
t=(3;7;11);
.....%now
P = con2seq(p);
T = con2seq(t);
net = elmannet(1:2,12);
[Xs,Xi,Ai,Ts] = preparets(net,P,T);
net = train(net,Xs,Ts,Xi,Ai);
view(net)
Y = net(Xs,Xi,Ai);
perf = perform(net,Ts,Y);

To clarify "(...)it must be MATLAB syntax...":
The problem here is the conversion from double to cell arrays. Matlab does not do this automatically since a cell can contain any type of value as mentioned here: http://www.mathworks.com/help/matlab/matlab_prog/what-is-a-cell-array.html
So, as mentioned in your answer, you can either convert your double arrays to cell arrays using num2cell() or you can allocate X and T as cell arrays from the very beginning using cell() and then copying your double values into them. This explicit type cast is necessary because preparets expects cell arrays as input, much like many of the plot functions in the ANN package.

Related

Error in MATLAB sequentialfs while selecting features from 94*263 feature vectors

I have 94 samples with 263 features for each sample. The total feature vector is 94*263 in size. There are no NaN or Inf value in the feature vectors. There are two classes (51 in class a and 43 in class b). I am using sequentialfs to select features but I am getting the following error each time:
Error using crossval>evalFun (line 480)
The function '#(XT,yT,Xt,yt)(sum(~strcmp(yt,classify(Xt,XT,yT,'quadratic'))))' generated the following error:
The input to SVD must not contain NaN or Inf.
The code is:
X = FEATUREVECTOR;
y = LABELS;
c = cvpartition(y,'k',10);
opts = statset('display','iter');
fun = #(XT,yT,Xt,yt)...
(sum(~strcmp(yt,classify(Xt,XT,yT,'quadratic'))));
[fs,history] = sequentialfs(fun,X,y,'cv',c,'options',opts)
Can you please tell me how to solve the problem?
It looks like you are calling sequentialfs with some inputs, that MAY be vaguely related to the mess of random numbers we see in your question. Beyond that, I can't read anything from your mind. If you want help you need to show what you did.
I change input data and it works well,
load fisheriris;
X = randn(150,10);
X(:,[1 3 5 7 ])= meas;
y = species;
c = cvpartition(y,'k',10);
opts = statset('display','iter');
fun = #(XT,yT,Xt,yt)...
(sum(~strcmp(yt,classify(Xt,XT,yT,'quadratic'))));
[fs,history] = sequentialfs(fun,X,y,'cv',c,'options',opts)
Your input data has problem.

Using spfun with two identically ordered sparse matrices

I got two sparse matrices A and B, which have identical sparsity pattern (all nonzeros are at exactly the same locations):
i = randi(1000,[50,1]);
j = randi(1000,[50,1]);
a = rand(50,1);
b = rand(50,1);
A = sparse(i,j,a,1000,1000);
B = sparse(i,j,b,1000,1000);
I would like to calculate efficiently exp(A-B) only for the nonzeros, and save it back into A.
I tried to use spfun for that task:
f = #(x,y) exp(x-y);
A = spfun(f,A,B);
but I got an error in spfun saying: "Too many input arguments."
Can anyone suggest an efficient way to calculate it?
It should be calculated many times.
Thanks!
Edit: mikkola suggested A = spfun(#f,A-B) which solves the problem, but the question remains how to do it with a function of two variables that can't be solved using the same trick. For example:
g = #(x,y) x.*cos(y);
A = spfun(#g,A,B);
You can't use
A = spfun(#exp, A-B);
because for entries where A an B are equal you will get 0 instead of 1.
To solve that, you can compute the vector of exponentials at the nonzero components, and then build a sparse matrix from that:
A = sparse(i,j,exp(nonzeros(A)-nonzeros(B))); %// if you have i, j stored
or
A(find(A)) = exp(nonzeros(A)-nonzeros(B));
Edit
According to the documentation, spfun can take only two inputs: a function and one sparse matrix.
So you cannot do directly what you want to do. The best solution is probably what has been suggested in the comments, i.e.:
res = spfun(#exp, A-B);
Best,

to find mean square error of two cell arrays of different sizes

I have two cell arrays. One is 'trans_blk' of size <232324x1> consists of cells of size <8x8> and another 'ca' is of size <1024x1> consists of cells of size <8x8>.
I want to compute mean square error (MSE) for each cell of 'ca' with respect to every cell of 'trans_blk'.
I used the following code to compute:
m=0;
for ii=0:7
for jj=0:7
m=m+((trans_blk{:,1}(ii,jj)-ca{:,1}(ii,jj))^2);
end
end
m=m/(size of cell); //size of cell=8*8
disp('MSE=',m);
Its giving an error. Bad cell reference operation in MATLAB.
A couple of ways that I figured you could go:
% First define the MSE function
mse = #(x,y) sum(sum((x-y).^2))./numel(x);
I'm a big fan of using bsxfun for things like this, but unfortunately it doesn't operate on cell arrays. So, I borrowed the singleton expansion form of the answer from here.
% Singleton expansion way:
mask = bsxfun(#or, true(size(A)), true(size(B))');
idx_A = bsxfun(#times, mask, reshape(1:numel(A), size(A)));
idx_B = bsxfun(#times, mask, reshape(1:numel(B), size(B))');
func = #(x,y) cellfun(#(a,b) mse(a,b),x,y);
C = func(A(idx_A), B(idx_B));
Now, if that is a bit too crazy (or if explicitly making the arrays by A(idx_A) is too big), then you could always try a loop approach such as the one below.
% Or a quick loop:
results = zeros(length(A),length(B));
y = B{1};
for iter = 1:length(B)
y = B{iter};
results(:,iter) = cellfun(#(x) mse(x,y) ,A);
end
If you run out of memory: Think of what you are allocating: a matrix of doubles that is (232324 x 1024) elements. (That's a decent chunk of memory. Depending on your system, that could be close to 2GB of memory...)
If you can't hold it all in memory, then you might have to decide what you are going to do with all the MSE's and either do it in batches, or find a machine that you can run the full simulation/code on.
EDIT
If you only want to keep the sum of all the MSEs (as OP states in comments below), then you can save on memory by
% Sum it as you go along:
results = zeros(length(A),1);
y = B{1};
for iter = 1:length(B)
y = B{iter};
results = results + cellfun(#(x) mse(x,y) ,A);
end
results =sum (results);

Error: Matrix dimensions must agree for plot

having a problem with my "new love", matlab: I wrote a function to calculate an integral using the trapz-method: `
function [L]=bogenlaenge_innen(schwingungen)
R = 1500; %Ablegeradius
OA = 1; %Amplitude
S = schwingungen; %Schwingungszahl
B = 3.175; %Tapebreite
phi = 0:2.*pi./10000:2.*pi;
BL = sqrt((R-B).^2+2.*(R-B).*OA.*sin(S.*phi)+OA.^2.*(sin(S.*phi)).^2+OA.^2.*S.^2.*(cos(S.*phi)).^2);
L = trapz(phi,BL)`
this works fine when i start it with one specific number out of the command-window. Now I want to plot the values of "L" for several S.
I did the following in a new *.m-file:
W = (0:1:1500);
T = bogenlaenge_innen(W);
plot(W,T)
And there it is:
Error using .*
Matrix dimensions must agree.
What is wrong? Is it just a dot somewhere? I am using matlab for the second day now, so please be patient.... ;) Thank you so much in advance!
PS: just ignore the german part of the code, it does not really matter :)
In your code, the arrays S and phi in the expression sin(S.*phi) should have same size or one of them should be a constant in order the code works
The error is most likely because you have made it so that the number of elements in schwingungen, i.e. W in your code, must be equal to the number of elements in phi. Since size(W) gives you a different result from size(0:2.*pi./10000:2.*pi), you get the error.
The way .* works is that is multiplies each corresponding elements of two matrices provided that they either have the same dimensions or that one of them is a scalar. So your code will work when schwingungen is a scalar, but not when it's a vector as chances are it has a different number of elements from the way you hard coded phi.
The simplest course of action (not necessarily the most Matlabesque though) for you is to loop through the different values of S:
W = (0:1:1500);
T = zeros(size(W); %Preallocate for speed)
for ii = 1:length(W)
T(ii) = bogenlaenge_innen(W(ii));
end
plot(W,T)
In your function you define phi as a vector of 10001 elements.
In this same function you do S.*phi, so if S is not the same length as phi, you will get the "dimensions must agree" error.
In your call to the function you are doing it with a vector of length 1501, so there is your error.
Regards

how to do this in a for loop in Matlab

I have a 3-dimensial matrix W of size 160x170x18 and I want to compute the difference
between each sucessive matrices inside W.
For example diff1 = W(:,:,1) - W(:,:,2) and diff2 = W(:,:,2) - W(:,:,3), etc ...
Next I want to select some special parts of the resulting matrices, For example:
NewDiff1 = [diff1(20:50,110:140); diff1(60:90,110:140)];
and the same thing for the other matrices.
finally I want to compute the mean of each matrix and the error as follow:
mean1 = mean(mean(NewDiff1));
er1 = 0.1-abs(mean1);
I succeeded to do this for each matrix alone, but prefer to do all at once in a for loop.
The expression
diff1 = diff(W,1,3)
will return, in your example, a 160*170*17 matrix where diffW(:,:,1) = W(:,:,2) - W(:,:,1), which isn't quite what you want. But
diff1 = (-1)*diff(W,1,3)
does, if my arithmetic is good, give you the differences you want. From there on you need something like:
newdiff1 = [diff1(20:50,110:140,:);diff1(60:90,110:140,:)];
and
means = mean(mean(newdiff1));
er1 = 0.1 - abs(mean1);
I haven't tested this thoroughly on matrices of the size you are working with, but it seems to work OK on smaller tests.
Store your matrices into a cell array and then just loop through the contents of the cell array and apply the same differencing logic to each thing. Be careful to use the {} syntax with a cell array to get its contents, rather than () which gives you the cell at a particular location.