Parfor in Matlab - 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.

Related

How to break loop if number repeats -Matlab

I recognized this is a quite hard problem for me. I asked this problem on official Matlab side but no-one could help me either so maybe someone of you can come up with an outstanding approach.
In detail my Problem consist of:
N = 100 %some number
G = 21 %random guess < N
for x = 1:N;
a = mod(G^x,N);
end
Now I want the calculation of a to stop, if a number repeats.
For example: a = 1, 2, 3, 1 -break
Seems simple but I just can't handle it right after many tries.
For instance I've put:
for x = 1:N
a = mod(G^x,N);
b = unique(a);
if a ~= b
break
end
end
but doesn't seem to work bc. it's not element wise I guess.
This approach keeps a running log of the past Results and uses the ismember() function to check if the current value of a has been previously seen.
clc;
N = 100; %some number
G = 21; %random guess < N
Results = NaN(1,N);
for x = 1:N
a = mod(G^x,N);
disp(a);
if ismember(a,Results)
disp("-break");
break
end
Results(x) = a;
end
Ran using MATLAB R2019b

Is there any special rules for nesting if-statement in for-loop in MATLAB?

I am trying to create a signal and then build a discrete-time signal by sampling the CT signal I create first. Until the last for-loop, things work out fine but I need to take N samples seperated by T. Without an if statement, I am getting an index out-of-bounds error and I had to limit sampling within the duration of the signal. For some reason, my code goes into if statement once and no more, and for debugging, I am printing out the values both in if and out of if. Although the logical operation should be true for more than one iteration(printing statements will show the values), it just does not print the statements inside the if-statement. What's wrong here?
function x = myA2D(b,w,p,T,N)
%MYA2D description: Takes in parameters to construct the CT-sampled DT signal
%b,w,p are Mx1 vectors and it returns Nx1 vector.
timeSpace = 0:0.001:3*pi;
xConstT = zeros(size(timeSpace));
%Construct Xc(t) signal
for k = 1:size(b,1)
temp = b(k) .* cos(w(k).*timeSpace + p(k));
xConstT = xConstT + temp;
end
plot(xConstT);
%Sampling CT-Signal to build DT-signal
disp(strcat('xConstT size',int2str(size(xConstT))));**strong text**
x = zeros(N,1);
sizeConstT = size(xConstT);
for i = 0:N-1
index = i .* T .* 1000 + 1;
disp(strcat('indexoo=',int2str(index)));
disp(strcat('xConstSizeeee',int2str(sizeConstT)));
if index <= sizeConstT
disp(strcat('idx=',int2str(index)));
disp(strcat('xSize',int2str(sizeConstT)));
%x(i+1,1) = xConstT(index);
end
end
end
sizeConstT = size(xConstT); creates an 1x2 array so you compare a float to an array, and your code enters the if loop only if comparison to each element of the array is successful. This example illustrates the issue:
if 1 <= [1 12]; disp('one'); end % <- prints 'one'
if 2 <= [1 12]; disp('two'); end % <- prints nothing
Your code will work with sizeConstT = length(xConstT);

Loop through data set until specific point - Matlab

I've run an experiment where a machine exerts a force on a bridge until it breaks. I need to cycle through my entire data set and calculate the toughness until I've hit the breaking point (fdValue1).
The toughness is calculated by summing up all the rectangles under my load vs. distance curve. (Basically the integral)
However, I have not been able to find a reasonable way of doing so and my current loop is an infinite loop and I'm not sure why.
%Initializing variables
bridge1Data = xlsread('Bridge1Data.xlsx', 'A2:C2971');
bridge2Data = xlsread('Bridge2Data.xlsx', 'A2:C1440');
bridge1Load = bridge1Data(:, 2);
bridge2Load = bridge2Data(:, 2);
bridge1Dist = bridge1Data(:, 3);
bridge2Dist = bridge2Data(:, 3);
[row1, col1] = size(bridge1Dist);
[row2, col2] = size(bridge2Dist);
bridge1Disp = zeros(row1, col1);
bridge2Disp = zeros(row2, col2);
fdValue1 = 0.000407350000000029;
&Main code
%Displacement
for k = 2:length(bridge1Dist)
bridge1Disp(k-1, 1) = bridge1Dist(k, 1) - bridge1Dist(k-1, 1);
end
%Max Load Bridge 1
maxLoad1 = 0;
for n = 1:length(bridge1Load)
for k = 1
if bridge1Load(n, k) > maxLoad1
maxLoad1 = bridge1Load(n, k);
end
end
end
%Cycle through data till failure, change proj data
totalRect1 = 0;
for j = 2:length(bridge1Disp)
while bridge1Disp(j, 1) ~= fdValue1
rectangle = (bridge1Disp(j, 1) - bridge1Disp(j-1, 1))*...
((bridge1Load(j, 1) + bridge1Load(j-1, 1))/2);
totalRect1 = totalRect1 + rectangle;
end
end
Basically, I make an array for the load and distance the machine pushes down on the bridge, assign a 'Failure Distance' value (fdValue) which should be used to determine when we stop calculating toughness. I then calculate displacement, calculate the maximum load. Then through the variable 'rectangle', calculate each rectangle and sum them all up in 'totalRect1', and use that to calculate the toughness by finding the area under the curve. Is anyone able to see why the loop is an infinite loop?
Thanks
The problem with the condition while bridge1Disp(j, 1) ~= fdValue1 is that you need to check for <= and not for (in)equality, since double numbers will almost never evaluate to be equal even if they seem so. To read more about this you can look here and also google for matlab double comparison. Generally it has something to do with precision issues.
Usually when checking for double equality you should use something like if abs(val-TARGET)<1E-4, and specify some tolerance which you are willing to permit.
Regardless,
You don't need to use loops for what you're trying to do. I'm guessing this comes from some C-programming habits, which are not required in MATLAB.
The 1st loop (Displacement), which computes the difference between every two adjacent elements can be replaced by the function diff like so:
bridge1Disp = diff(bridge1Dist);
The 2nd loop construct (Max Load Bridge 1), which retrieves the maximum element of bridge1Load can be replaced by the command max as follows:
maxLoad1 = max(bridge1Load);
For the last loop construct (Cycle ...) consider the functions I've mentioned above, and also find.
In the code section
%Cycle through data till failure, change proj data
totalRect1 = 0;
for j = 2:length(bridge1Disp)
while bridge1Disp(j, 1) ~= fdValue1
rectangle = (bridge1Disp(j, 1) - bridge1Disp(j-1, 1))*...
((bridge1Load(j, 1) + bridge1Load(j-1, 1))/2);
totalRect1 = totalRect1 + rectangle;
end
end
the test condition of the while loop is
bridge1Disp(j, 1) ~= fdValue1
nevertheless, in the while loop the value of bridge1Disp(j, 1) does not change so if at the first iteratiion of the while loop bridge1Disp(j, 1) is ~= fdValue1 the loop will never end.
Hope this helps.

parfor loop has wrong sliced variables

Can anyone explain to me, why the following gives an error for u but nor for h
max_X = 100;
max_Y = 100;
h = ones(max_Y,max_X);
u = zeros(max_Y,max_X);
parfor l=1:max_X*max_Y
i = mod(l-1,max_X) + 1;
j = floor((l-1)/max_Y) + 1;
for k=1:9
m = i + floor((k-1)/3) - 1;
n = j + mod(k,-3) + 1;
h_average(k) = sqrt(h(i,j)*h(m,n));
u_average(k) = (u(i,j)*sqrt(h(i,j)) + u(m,n)*sqrt(h(m,n)))/(sqrt(h(i,j)) + sqrt(h(m,n)));
end
end
I can now substitute (i,j) with (l), but even if I try to calculate the related variable, let's call it p, according to (m,n), and write u(p) instead of u(m,n) it gives me an error message.
It only underlines the u(m,n), resp. u(p) but not the h(m,n).
MATLAB says:
Explanation:
For MATLAB to execute parfor loops efficiently, the amount of data sent to the MATLAB workers must be minimal. One of the ways MATLAB achieves this is by restricting the way variables can be indexed in parfor iterations. The indicated variable is indexed in a way that is incompatible with parfor.
Suggested Action
Fix the indexing. For a description of the indexing restrictions, see “Sliced Variables” in the Parallel Computing Toolbox documentation
Any idea, what's wrong here?
The problems with u and h are that they are both being sent as broadcast variables to the PARFOR loop. This is not an error - it's just a warning indicating that more data than might otherwise be necessary is being sent.
The PARFOR loop cannot run because you're indexing but not slicing u_average and h_average. It's not clear what outputs you want from this loop since you're overwriting u_average and h_average each time, therefore the PARFOR loop is pointless.

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)