Running 3 for loops in parallel in Matlab - matlab

I have three mobile operators O1,O2, and O3, each of them has its own mobile ( N_M_O1,N_M_O2, and N_M_O3) they are sharing the base stations (B1 and B2) represented by (conter_B1,conter_B2) I need to associate every mobile that belongs to (operator (O1) or operator (O2) or operator (O3)) to the base stations (B1 and B2)independently,however each mobile should ask the base stations (B1,B2) first if the conter_B1 and conter_B2 more than 10 they reject to associate with the next mobile (which is number 11).
The problem is the implementation of multiple loops in Matlab will be sequencially means that Matlab will run loop1 then finish all iterations (for example if have 200 iterations) then start to run the second loop (loop2) and update the result after that start to run the third loop3
I need to run all the loops (loop1,loop2,loop3) at the same time and update the result at the same time keeping in mind the result will update the same conter for all (conter_B1 and conter_B2):
The code below follows the normal way of Matlab not parallel only for giving an example of multiple loops
N_M_O1=10;
N_M_O2=12;
N_M_O3=13;
conter_B1=0;
conter_B2=0;
x=[2 3 5 8 6 3 4 5 8 9];
y=[2 3 6 5 2 9 4 6 3 5];
x2=[2 8 5 8 6 3 6 5 6 9 10 12];
y2=[9 3 6 9 7 9 4 6 8 5 1 23];
x3=[2 3 1 8 6 3 55 5 6 9 2 3 5];
y3=[2 4 6 4 6 5 4 6 6 4 12 32 3];
for m=1:N_M_O1
z(m)=x(m)+y(m);
if z(m)>10
conter_B1=conter_B1+1;
else
conter_B2=conter_B2+1;
end
end
for m=1:N_M_O2
z2(m)=x2(m)+y2(m);
if z2(m)>10
conter_B1=conter_B1+1;
else
conter_B2=conter_B2+1;
end
end
for m=1:N_M_O3
z3(m)=x3(m)+y3(m);
if z3(m)>10
conter_B1=conter_B1+1;
else
conter_B2=conter_B2+1;
end
end

If I understand your question you only want:
zz = [x+y,x2+y2,x3+y3];
counter_B1 = sum(zz>10)
counter_B2 = sum(zz<=10)
Which will produce the same result as your 3 for loops.

Related

Is there any command to find mean of first 5 values then next 5 values for a total of 1000 values in a vector in MATLAB

Is there any command to find mean of first 5 values then next 5 values from a total of 25 values present in a vector in MATLAB. If the dataset is X.
If anyone can help me to provide a code where I can get mean at every 5th value.
X=[4 5 6 7 2 5 7 4 2 6 7 3 2 1 5 7 8 3 4 6 8 4 2 6 8];
You can for instance reshape the vector in an array with reshape and then apply the mean function:
M = mean(reshape(X, [5, numel(X)/5]),1);
or simply
M = mean(reshape(X, 5, []),1);
But there as stated in the comments there are many other ways.
Here is one simple way to do it. Rearrange the vector into a matrix loop over the columns and take the mean of all values in each column. Store the results in a new vector.
X=[4 5 6 7 2 5 7 4 2 6 7 3 2 1 5 7 8 3 4 6 8 4 2 6 8];
Xr = reshape(X,5,5)
cols = size(Xr)(2)
avgs=zeros(1,cols)
for i= 1:cols
avgs(i) = mean(Xr(:,i))
end

period in sequence of element in vector

I have a vector V periodic an I want to write a program which associates to each period the set of different elements in that period and gives its cardinal.
For example:
For the vector v=(2 3 7 2 7 3 2 3 7 2 7 3) and cardinal 6, give me only the vector P=(2 3 7 2 7 3).
For The vector v=(2 3 7 5 8 6 10 11 10 6 8 5 7 3 2 3 7 5 8 6) and the cardinal 14, give me P=(2 3 7 5 8 6 10 11 10 6 8 5 7 3).
If I understood you correctly you have to use build-in function seqperiod(v).
In your case, for example:
v=[2 3 7 5 8 6 10 11 10 6 8 5 7 3 2 3 7 5 8 6];
>> seqperiod(v)
ans =
14
Interesting moment: in your second example there aren't full repetition. So we can't really say is it periodic... But seqperiod still works and returns 14 as you wish.
go further you can use it in this way:
[p, num] = seqperiod(v);
p = 14
num = 1.4286
num - is a number of repetitions.
Ok. Now you say you need not only the cardinal, but the vector. So you can do it easily:
result = v(1:p);
Hope it helps!

Matlab: creating a matrix whose rows consist of a linspace or similar pattern

Anybody know a fast way to produce a matrix consisting of a linspace for each row? For example, the sort of pattern I'm looking for in this matrix is:
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
...
1 2 3 4 5 6 7 8 9 10
Anyone know any fast tricks to produce this WITHOUT using a for loop?
I just figured this out, so just in case anyone else was troubled by this, we can achieve this exact pattern by:
a=linspace(1,10,10);
b=ones(3,1)*a;
This will give:
>> a = 1 2 3 4 5 6 7 8 9 10
>> b = 1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
You need to use repmat.
Example:
>> B = repmat(1:10,[3 1])
B =
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
You can vary the value of 3 there. You can change it accordingly.
Another shortcut I can recommend is similar to repmat, but you specify a base array first of a = 1:10;. Once you do this, you specify a series of 1s in the first dimension when indexing which should produce a matrix of the same vectors with many rows as you want, where each row consists of the base array a. As such:
%// number of times to replicate
n = 4;
a = 1:10;
a = a(ones(1,n),:);
Result:
a =
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
Insert this command: transpose(ndgrid(1:10,1:n));, where n is the number of rows desired in the result.
You can consider these solutions:
With basic matrix indexing (taken from here)
b=a([1:size(a,1)]' * ones(1,NumToReplicate), :) %row-wise replication
b=a(:, ones(NumToReplicate, 1)) %column-wise replication
With bsxfun:
bsxfun(#times,a,(ones(1,NumToReplicate))') %row-wise replication
bsxfun(#times,a',(ones(1,NumToReplicate))) %column-wise replication
You are welcome to benchmark above two solutions with repmat.

Manipulate specific regions of matrix

I want to make a manipulate a matrix/look-up table in matlab. Here is the Matrix I am working with:
0 5 10 15 20 25 30 35 40 45 50
0 3 4 5 6 4 5 5 5 5 5
20 3 4 5 6 4 5 5 5 5 5
27 3 4 5 6 4 5 5 5 5 5
34 3 4 5 6 4 5 5 5 5 5
41 3 4 5 6 4 5 5 5 5 5
49 3 4 5 6 4 5 5 5 5 5
56 3 4 5 6 4 5 5 5 5 5
63 3 4 5 6 4 5 5 5 5 5
71 3 4 5 6 4 5 5 5 5 5
78 3 4 5 6 4 5 5 5 5 5
85 3 4 5 6 4 5 5 5 5 5
93 3 4 5 6 4 5 5 5 5 5
100 3 4 5 6 4 5 5 5 5 5
The First column and row i want to use as my variables. So for instance if i want to manipulate a certain region, how would I do so? e.g. all values between 5 - 15 (top row) and 20-41 (first column) were to be multiplied by 1.33.
Ideally, i want this to be used in a GUI but I want to get the concept understood first as i'm still a new user to the software.
Thanks for all the help,
Kind regards,
Sam
Build a logical index, using bsxfun to combine the row and column conditions (could also be done with repmat). Then use that index to apply the desired operation to the selected entries.
Let A denote your matrix:
ind = bsxfun(#and, A(1,:)>=5 & A(1,:)<=15, A(:,1)>=20 & A(:,1)<=41);
A(ind) = A(ind)*1.33;
You probably need to create some kind of lookup function or data structure. I would create two vectors for your first row and first column separately from your "data" matrix, and use find() function to look up the corresponding index.
If you know the indices of the values that you want to modify in your matrix, then,
A(3:6,2:4) = 1.33*A(3:6,2:4);
should work.
In this case I would actually use 2 indices, one for each dimension.
I assume your data is in one matrix but it should not be too hard to adjust for the case where you use 2 vectrices and a matrix.
idx1 = A(1,:)>=5 & A(1,:)<=15;
idx2 = A(:,1)>=20 & A(:,1)<=41);
A(idx1,idx2) = A(idx1,idx2)*1.33

matlab: dividing vector into overlapping chunks of fixed size

I've a vector that I would like to split into overlapping subvectors of size cs in shifts of sh. Imagine the input vector is:
v=[1 2 3 4 5 6 7 8 9 10 11 12 13]; % A=[1:13]
given a chunksize of 4 (cs=4) and shift of 2 (sh=2), the result should look like:
[1 2 3 4]
[3 4 5 6]
[5 6 7 8]
[7 8 9 10]
[9 10 11 12]
note that the input vector is not necessarily divisible by the chunksize and therefore some subvectors are discarded. Is there any fast way to compute that, without the need of using e.g. a for loop?
In a related post I found how to do that but when considering non-overlapping subvectors.
You can use the function bsxfun in the following manner:
v=[1 2 3 4 5 6 7 8 9 10 11 12 13]; % A=[1:13]
cs=4;
sh=2;
A = v(bsxfun(#plus,(1:cs),(0:sh:length(v)-cs)'));
Here is how it works. bsxfun applies some basic functions on 2 arrays and performs some repmat-like if the sizes of inputs do not fit. In this case, I generate the indexes of the first chunk, and add the offset of each chunck. As one input is a row-vector and the other is a column-vector, the result is a matrix. Finally, when indexing a vector with a matrix, the result is a matrix, that is precisely what you expect.
And it is a one-liner, (almost) always fun :).
Do you have the signal processing toolbox? Then the command is buffer. First look at the bare output:
buffer(v, 4, 2)
ans =
0 1 3 5 7 9 11
0 2 4 6 8 10 12
1 3 5 7 9 11 13
2 4 6 8 10 12 0
That's clearly the right idea, with only a little tuning necessary to give you exactly the output you want:
[y z] = buffer(v, 4, 2, 'nodelay');
y.'
ans =
1 2 3 4
3 4 5 6
5 6 7 8
7 8 9 10
9 10 11 12
That said, consider leaving the vectors columnwise, as that better matches most use cases. For example, the mean of each window is just mean of the matrix, as columnwise is the default.
I suppose the simplest way is actually with a loop.
A vectorizes solution can be faster, but if the result is properly preallocated the loop should perform decently as well.
v = 1:13
cs = 4;
sh = 2;
myMat = NaN(floor((numel(v) - cs) / sh) + 1,cs);
count = 0;
for t = cs:sh:numel(v)
count = count+1;
myMat(count,:) = v(t-cs+1:t);
end
You can accomplish this with ndgrid:
>> v=1:13; cs=4; sh=2;
>> [Y,X]=ndgrid(1:(cs-sh):(numel(v)-cs+1),0:cs-1)
>> chunks = X+Y
chunks =
1 2 3 4
3 4 5 6
5 6 7 8
7 8 9 10
9 10 11 12
The nice thing about the second syntax of the colon operator (j:i:k) is that you don't have to calculate k exactly (e.g. 1:2:6 gives [1 3 5]) if you plan to discard the extra entries, as in this problem. It automatically goes to j+m*i, where m = fix((k-j)/i);
Different test:
>> v=1:14; cs=5; sh=2; % or v=1:15 or v=1:16
>> [Y,X]=ndgrid(1:(cs-sh):(numel(v)-cs+1),0:cs-1); chunks = X+Y
chunks =
1 2 3 4 5
4 5 6 7 8
7 8 9 10 11
10 11 12 13 14
And a new row will form with v=1:17. Does this handle all cases as needed?
What about this? First I generate the starting-indices based on cs and sh for slicing the single vectors out of the full-length vector, then I delete all indices for which idx+cs would exceed the vector length and then I'm slicing out the single sub-vectors via arrayfun and afterwards converting them into a matrix:
v=[1 2 3 4 5 6 7 8 9 10 11 12 13]; % A=[1:13]
cs=4;
sh=2;
idx = 1:(cs-sh):length(v);
idx = idx(idx+cs-1 <= length(v))
A = arrayfun(#(i) v(i:(i+cs-1)), idx, 'UniformOutput', false);
cell2mat(A')
E.g. for cs=5; sh=3; this would give:
idx =
1 3 5 7
ans =
1 2 3 4 5
3 4 5 6 7
5 6 7 8 9
7 8 9 10 11
Depending on where the values cs; sh come from, you'd probably want to introduce a simple error-check so that cs > 0; as well as sh < cs. sh < 0 would be possible theoretically if you'd want to leave some values out in between.
EDIT: Fixed a very small bug, should be running for different combinations of sh and cs now.