Error using matlab parfor - matlab

I am trying to parallelize pagerank using matlab parfor command as shown below.
However, the line which is marked by ** ** and is also written below:
p_t1(L{j,i}) = p_t1(L{j,i}) +constant;
is causing this error:
"Undefined function 'p_t1' for input arguments of type 'int32'."
When I comment it out, the code works. When I replace the parfor with a normal for, it works again. What is the problem?
Thanks
S='--------------------------------------------------';
n = 6;
index=1;
a = [2 6 3 4 4 5 6 1 1];
b = [1 1 2 2 3 3 3 4 6];
a = int32(a);
b=int32(b);
a=transpose(a);
b=transpose(b);
vec_len=length(a);
%parpool(2);
for i=1:vec_len
G(1,i)=a(i);
G(2,i)=b(i);
con_size(i)=0;
end
%n=916428
for j = 1:vec_len
from_idx=a(j);
con_size(from_idx)=con_size(from_idx)+1;
L{from_idx,con_size(from_idx)}=b(j);
end
% Power method
max_error=100;
p = .85;
delta = (1-p)/n;
p_t1 = ones(n,1)/n;
p_t0 = zeros(n,1);
cnt = 0;
tic
while max_error > .0001
p_t0 = p_t1;
p_t1 = zeros(n,1);
parfor j = 1:n
constant=p_t0(j)/con_size(j);
constant1=p_t0(j)/n;
if con_size(j) == 0
p_t1 = p_t1 + constant1;
else
for i=1:con_size(j)
**p_t1(L{j,i}) = p_t1(L{j,i}) +constant;**
end
end
end
p_t1;
sum(p_t1);
p_t1 = p*p_t1 + delta;
cnt = cnt+1;
max_error= max(abs(p_t1-p_t0));
%disp(S);
end
toc
%delete(gcp)

Each variable inside parfor loop must be classified into one of several categories. Your p_t1 variable cannot be classified as any. It appears that you are trying to accumulate result in this variable across multiple iterations, which can be done using reduction variables. This is possible only if the result does not depend on the order of iterations (which appears to be the case in your example), but as you can see from the documentation, only certain types of expressions are allowed for reduction variables - mostly just simple assignments. In particular, you cannot index into a reduction variable - neither on the left-hand side, nor on the right-hand side of the assignment.
Matlab should be also producing plenty of warnings and M-Lint (statical code analyzer) warnings to highlight this issue.
You need to re-write your code so that Matlab could clearly classify each variable used inside parfor into one of the allowed categories.

Related

How to return a series of number from a recursive function in Matlab

I use dynamic programming for finding the shortest path between two matrices. I printed all the step of the shortest path, but I would also like to save all of them so I can print them as a 2D figure. I wrote the code like below but it doesn't work. I searched on the internet and it seems like it need to be pass by an object as the argument? Does anyone know how to get the path matrix from the returning value? Thanks in advance!
ttt=find_path(7,7)
function pathMat = find_path(a,b)
pathMat=[];
if (a==0 || b==0)
return;
end
filename = sprintf('/Users/name/Desktop/song1.wav');
[x, Fs]=audioread(filename);
s=x;
filename = sprintf('/Users/name/Desktop/song2.wav');
[x, Fs]=audioread(filename);
t=x;
% dynamic time warping
w=-Inf;
ns=size(s,2);
nt=size(t,2);
%% initialization
D=zeros(ns+2,nt+2)-Inf; % cache matrix
D(1,1)=0;
D(2,2)=0;
% similarity matrix (cosing similarity)
oost = zeros(ns+1,nt+1)-Inf;
for i=1:ns
for j=1:nt
oost(i+1,j+1) =
(dot(s(:,i),t(:,j))/(norm(s(:,i),2)*norm(t(:,j),2))); % = cos(theta)
end
end
%% begin dynamic programming
%find the maximal similarity between two matrix
for i=1:ns
for j=1:nt
D(i+2,j+2)=oost(i+1,j+1)+max([D(i,j+1)+oost(i,j+1), D(i+1,j)+oost(i+1,j), D(i+1,j+1)]);
end
end
d=max(D(:,nt+2));
d_len=nt+2;
while(max(D(:,d_len))==-Inf)
d_len=d_len-1;
d=max(D(:,d_len));
end
fprintf('(%d, %d)', a, b);
pathMat = [pathMat];
if (max([D(a,b+1)+oost(a,b+1), D(a+1,b)+oost(a+1,b), D(a+1,b+1)])==D(a,b+1)+oost(a,b+1))
fprintf('(%d, %d)', a-1, b);
pathMat=[pathMat;find_path(a-1,b)];
find_path(a-2,b-1);
elseif (max([D(a,b+1)+oost(a,b+1), D(a+1,b)+oost(a+1,b), D(a+1,b+1)])==D(a+1,b)+oost(a+1,b))
fprintf('(%d, %d)', a, b-1);
pathMat=[pathMat;find_path(a,b-1)];
find_path(a-1,b-2);
elseif (max([D(a,b+1)+oost(a,b+1), D(a+1,b)+oost(a+1,b), D(a+1,b+1)])==D(a+1,b+1))
find_path(a-1,b-1);
end
end
There are two approaches you can use, to retain values between function calls or store all results in a "global" variable.
Due to the clutter and length of your code (not everything is relevant to the question), I will take the example of a factorial program to describe the approach.
Let there be a function that not only computes the factorial of the given number recursively, but also all the intermediate results of numbers lesser than itself. I believe this is a close model of what you require. An example of what the function should do:
>> [fact, list] = factorial(5)
>> fact = 120
>> list = [1, 2, 6, 24, 120]
Approach 1: Use persistent variables
Persistent variables are the equivalent of static function variables (like in C) in MATLAB.
Persistent variables by default are assigned to [] on first use. Also, the value is retained across function calls as expected. A sample code using this approach to define our factorial program:
function [fact, list] = factorial(n)
if n <= 1
fact = 1;
else
fact = n * factorial(n-1);
end
persistent res;
res = [res, fact];
list = res;
end
This can be used as follows:
>> [f, list] = factorial(4)
f =
24
list =
1 2 6 24
>> clear factorial
>> [f, list] = factorial(3)
f =
6
list =
1 2 6
Approach 2: Sharing variables in nested functions
MATLAB supports nested function definitions, where the inner functions can share variables from the outer one, and modify them without explicitly being passing as arguments. A sample code using this approach:
function [fact, list] = factorial(n)
list = [];
fact = factorial_core(n);
function fact = factorial_core(n)
if n <= 1
fact = 1;
else
fact = n * factorial_core(n-1);
end
list = [list, fact];
end
end
This is used the same way as before, except that clear factorial (that clears the persistent variables) between function calls is not required.
I would recommend you to try out whichever suits your case best. Also, it appears that you are loading the wav files each time of the recursion, which is unnecessary and inefficient. These two approaches can be used to avoid that, apart from solve your problem.

Unable to write to matrix lines with parfor

How can I write into my result matrix lines using parfor?
Code sample:
xCount = 10;
yCount = 20;
area = xCount*yCount;
PP = nan(area,3);
parfor x = 1:10
for y = 1:20
id = y + (x-1)*yCount; % global PP line id.
z = x^2+y*10; % my stuff to get Z.
PP(id,:) = [x y z]; % write to PP line
end
end
The PARFOR loop cannot run due to the way variable 'PP' is used.
I actually says "Valid indices are restricted within PARFOR loops". The reason it says that it that MATLAB iterates through a parfor loop non-consecutive, meaning it can do iterations in semi-random order like 5 2 4 1 3, as opposed to 1 2 3 4 5. This means that in order to know where in PP MATLAB has to store your result, it wants to know before entering the parallel environment that no lines get called by different iterations, as to avoid conflicts when getting results back from the workers.
The solution will be to structure PP in such a way that it's known beforehand where the indices are stores, e.g. by creating a 2D array to use before the loop to store stuff in:
xCount = 10;
yCount = 20;
area = xCount*yCount;
PP(xCount,yCount) = 0;
y=1:yCount;
parfor x = 1:xCount
z = x^2+y.*10; % my stuff to get Z.
PP(x,:) = z; % write to PP line
end
%// Go to the [x y z] format
PP = [repmat((1:yCount).',xCount,1),repmat((1:xCount).',yCount,1), PP(:)];
I'd personally not do the last line in this case, since it stores three doubles for each useful value (z), whilst in the 2D matrix that comes out of the loop it only stores 1 double which can be indexed by simply reading PP(x,y). Thus it costs you 3 times the memory to store the same amount of useful data.

classification with four classes by matlab

I have a classification problem with four classes of input vector.The four classes are
A = [1 , 1; 1 ,2];
B = [2,2; -1,0];
C = [-1,-2;2,1];
D = [-1,-2; -1,-2];
I wan Implement this problem by Matlab, I Use this code :
C = [-1,-2;2,1];
A = [1 , 1; 1 ,2];
B = [2,2; -1,0];
D = [-1,-2; -1,-2];
hold on
grid on
plot(A(1,:),A(2,:),'bs')
plot(B(1,:),B(2,:),'r+')
plot(C(1,:),C(2,:),'go')
plot(D(1,:),D(2,:),'m*')
a = [0 1]';
b = [1 1]';
c = [1 0]';
d = [0 0]';
P = [A B C D];
T = [repmat(a,1,length(A)) repmat(b,1,length(B)) repmat(c,1,length(C)) repmat(d,1,length(D)) ];
net = perceptron;
E = 1;
net.adaptParam.passes = 1;
linehandle = plotpc(net.IW{1},net.b{1});
n = 0;
while (sse(E))
n = n+1;
[net,Y,E] = adapt(net,P,T);
linehandle = plotpc(net.IW{1},net.b{1},linehandle);
drawnow;
end
but My Code does'nt work I have No idea why, please Help me....
As has been suggested by thewaywewalk, the trouble is your while-loop and the fact that you do not provide an adequate check for the statement you wish to evaluate.
Replace your while-statement with these two lines:
ACCEPTABLE_ERROR = 3.0;
while (sse(E)>ACCEPTABLE_ERROR)
And you should see your script terminate after three iterations. You can play with the ACCEPTABLE_ERROR variable to check which solution works best for you. If you set it too small, your while loop will not exit, because the statement will not be false.
An explanation to your original while-statement:
All you ever evaluated if sse(e) returned a results - which it did in each case. That's why it never stopped.
To the question of sse requires more than one input argument:
That depends on what input arguments you provide.
The documentation says:
perf = sse(net,t,y,ew) takes these input arguments and optional function parameters,
net: Neural network
t: Matrix or cell array of target vectors
y: Matrix or cell array of output vectors
ew: Error weights (default = {1})
and returns the sum squared error.
However, it is not necessary, to provide the error weights, ew, as the source code reveals:
Only the first three arguments are required. The default error weight is {1}, which weights the importance of all targets equally.
In your case you should, based on the documentation, call sse like this:
sse(net,T,Y)
Without being mentioned in the documentation (or I haven't found it), this is equivalent to what you have done, by providing simply the network errors, E as provided from adapt:
sse(E)
Both give the same results.

Parfor in Matlab

I'm trying to run this loop as a parfor-loop:
correlations = zeros(1,N);
parfor i = 1:(size(timestamps,1)-1)
j = i+1;
dts = timestamps(j) - timestamps(i);
while (dts < T) && (j <= size(timestamps,1))
if dts == 0 && detectors(i) ~= detectors(j)
correlations(1) = correlations(1) + 2;
elseif detectors(i) ~= detectors(j)
dts = floor(dts/binning)+1;
correlations(dts) = correlations(dts) + 1;
end
j = j + 1;
if j <= size(timestamps,1)
dts = timestamps(j) - timestamps(i);
end
end
end
Matlab gives me the following error:
Error: File: correlate_xcorr.m Line: 18 Column: 17
The variable correlations in a parfor cannot be classified.
See Parallel for Loops in MATLAB, "Overview".
Line 18 is the following:
correlations(1) = correlations(1) + 2;
I can not understand why this shouldn'n be possible. The final value of correlations doesn't depend on the order in which the loop is executed, but only dts and detectors. I found similar examples in the documentation which work fine.
Why can't Matlab execute this code and how can I fix it?
I found the following solution and it seems to work. The program looks a litte different, but it has the same shape. This way Matlab is forced to think x/correlations is a reduction variable.
X = zeros(1,5);
parfor i= 1:1000
a = zeros(1,5);
dts = randi(10)-1;
if dts == 0
a(1) = (a(1) + 2);
elseif dts <= 5
a(dts) = a(dts) +1;
end
X = X + a;
end
MATLAB cannot determine that your loop is order independent because of the way you're accessing correlations(1) from multiple iterations of the PARFOR loop. It looks like this value is in some way 'special', it should work to make a 'reduction' variable, i.e. replace correlations(1) with correlations_1 or something.
The next problem you'll encounter is that you are not correctly 'slicing' the remainder of correlations. For MATLAB to analyse a PARFOR loop, it needs to be able to tell that each loop iteration is writing only to its 'slice' of the output variables. In practice, this means that you must index the outputs using literally the loop index.
More about PARFOR variable classification here: http://www.mathworks.com/help/distcomp/advanced-topics.html#bq_of7_-1
EDIT:
If you want correlations to behave strictly as a reduction variable as I believe you imply in your comments, you need to give PARFOR a clue that's what you mean: in particular, you need to add to the whole variable each time you need to. In other words, something more like:
parfor ...
dummyVec = zeros(1, N);
dummyVec(elementToIncrement) = 1;
correlations = correlations + dummyVec;
end
I agree this is non-obvious. See http://blogs.mathworks.com/cleve/2012/11/26/magic-squares-meet-supercomputing/ for more.

matlab syntax errors in single layer neural network [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
I have to implement a single layer neural network or perceptron.For this, I have 2 files data sets , one for the input and one for the output.I have to do this in matlab without using neural toolbox.The format of 2 files is given below.
In:
0.832 64.643
0.818 78.843
1.776 45.049
0.597 88.302
1.412 63.458
Out:
0 0 1
0 0 1
0 1 0
0 0 1
0 0 1
The target output is "1 for a particular class that the corresponding input belongs to and "0 for the remaining 2 outputs.
I tried to do this, But it is not working for me.
load in.data
load out.data
x = in(:1);
y = in(:2);
learning rate = 0.2;
max_iteration = 50;
function result = calculateOutput(weights,x, y)
s = x*(weights(1) +weight(2) +weight(3));
if s>=0
result = 1
else:
result = -1
end
end
Count = length(x);
weights[0] = rand();
weights[1] = rand();
weights[2] = rand();
iter = 0;
do {
iter++;
globalerror = 0;
for(p=0; p<count;p++){
output = calculateoutput(weights,x[p],y[p]);
localerror = output[p] - output
weights[0]+= learningrate *localerror*x[p];
weights[1]+= learningrate *localerror*y[p];
weights[2]+= learningrate *localerror;
globalerror +=(localerror*localerror);
}
}while(globalerror != 0 && iter <= max_iteration);
Where is the mistake in this algorithm??
I am referring the example given in the link below:-
Perceptron learning algorithm not converging to 0
Here's a list of what I see wrong:
deep breath
The indexing syntax (:1) is incorrect. Perhaps you mean (:,1) as in "all rows of column 1".
There is no such thing as a do...while loop in MATLAB. Only FOR and WHILE loops. Also, your for loop is defined wrong. MATLAB has a different syntax for that.
There are no ++ or += operators in MATLAB.
The "not equal" operator in MATLAB is ~=, not !=.
Indexing of vectors and matrices needs to be done with parentheses (), not square brackets [].
Is all of this inside a function or a script? You can not define functions, namely calculateOutput, in a script. You would have to put that in its own m-file calculateOutput.m. If all of the code is actually inside a larger function, then calculateOutput is a nested function and should work fine (assuming you have ended the larger enclosing function with an end).
You have a number of apparent typos for variable names:
weight vs. weights (as per phoffer's answer)
Count vs. count (MATLAB is case-sensitive)
calculateOutput vs. calculateoutput (again, case-sensitivity)
learning rate vs. learningrate (variables can't have spaces in them)
heavy exhale ;)
In short, it needs quite a bit of work.
The main mistake is that this is not written using Matlab syntax. Here is an attempt to do what I think you were trying to do.
Unfortunately, there is a fundamental problem with your algorithm (see comments in the code). Also, I think you should have a look at the very good Matlab documentation. Reading the manual will tell you quickly how you format this.
function neuralNetwork
%# load data
load in.data
load out.data
x = in(:,1);
y = in(:,2);
%# set constants
learningrate = 0.2;
max_iteration = 50;
% initialize parameters
count = length(x);
weights = rand(1,3); % creates a 1-by-3 array with random weights
iter = 0;
while globalerror ~= 0 && iter <= max_iteration
iter = iter + 1;
globalerror = 0;
for p = 1:count
output = calculateOutput(weights,x(p),y(p));
%# the following line(s) cannot possibly work
%# output is not a vector, since the previous line
%# assigns it to a scalar
%# Also, arrays are accessed with parentheses
%# and indexing starts at 1
%# and there is no += operator in Matlab
localerror = output[p] - output
weights[0]+= learningrate *localerror*x[p];
weights[1]+= learningrate *localerror*y[p];
weights[2]+= learningrate *localerror;
globalerror +=(localerror*localerror);
end %# for-loop
end %# while-loop
%# subfunctions in Matlab are put at the end of the file
function result = calculateOutput(weights,x, y)
s = x*(weights(1) +weight(2) +weight(3));
if s>=0
result = 1
else:
result = -1
end
end
On line #10, you have weights(1) +weight(2) +weight(3); but the rest of the code has weights with an s.
EDIT: Also, MATLAB does not have the ++ operator; your for loop will cause an error. In MATLAB, construct a for loop like this:
for p=0:count
blah blah blah
end
Also, MATLAB does not use the += operator either, as Jonas pointed out in his code. You need to do this:
weights(0) = weights(0) + learningrate * localerror * x(p)