Array of structures with parfor in Matlab - arrays

I am using Matlab to work on my project, and I want to use "parfor" as a part of my code that returns an array of structures in each its iteration, But when I run my code I got some errors. I just tried to bring an example of my problem in the simplest way. Will be appreciated any helps! Here is the example:
clear;
clc;
% An arbitrary number
constant_Number=3;
tic
parfor i=1:2
k=[constant_Number,i];
r(i)=test(k);
end
toc
and test function is as follows:
function [a]=test(k)
a.first=k(1) * k(2);
a.second=k(1)+k(2);
b.first=k(1)/k(2);
b.second=k(1);
a=[a;b];
end
One note is that when I just return one structure, it works fine but when I have more than one (adding b for instance), I got the following error: "Unable to perform assignment because the indices on the left side are not compatible with the size of the right side."
Thanks,
Ali

Find the solution, just need to define a cell array and then finally merge them! Follow can be an answer:
clear;
clc;
% An arbitrary number
constant_Number=3;
% Define an arbitrary array of structure
arb_arr=[];
% Define an arbitrary cell array
r={};
tic
parfor i=1:2
k=[constant_Number,i];
r{i}=test(k);
end
for i=1:2
arb_arr=[arb_arr;r{i}];
end
toc

Related

Julia: How to efficiently sort subarrays of 2 large arrays in parallel?

I have large 1D arrays a and b, and an array of pointers I that separates them into subarrays. My a and b barely fit into RAM and are of different dtypes (one contains UInt32s, the other Rational{Int64}s), so I don’t want to join them into a 2D array, to avoid changing dtypes.
For each i in I[2:end], I wish to sort the subarray a[I[i-1],I[i]-1] and apply the same permutation to the corresponding subarray b[I[i-1],I[i]-1]. My attempt at this is:
function sort!(a,b)
p=sortperm(a);
a[:], b[:] = a[p], b[p]
end
Threads.#threads for i in I[2:end]
sort!( a[I[i-1], I[i]-1], b[I[i-1], I[i]-1] )
end
However, already on a small example, I see that sort! does not alter the view of a subarray:
a, b = rand(1:10,10), rand(-1000:1000,10) .//1
sort!(a,b); println(a,"\n",b) # works like it should
a, b = rand(1:10,10), rand(-1000:1000,10) .//1
sort!(a[1:5],b[1:5]); println(a,"\n",b) # does nothing!!!
Any help on how to create such function sort! (as efficient as possible) are welcome.
Background: I am dealing with data coming from sparse arrays:
using SparseArrays
n=10^6; x=sprand(n,n,1000/n); #random matrix with 1000 entries per column on average
x = SparseMatrixCSC(n,n,x.colptr,x.rowval,rand(-99:99,nnz(x)).//1); #chnging entries to rationals
U = randperm(n) #permutation of rows of matrix x
a, b, I = U[x.rowval], x.nzval, x.colptr;
Thus these a,b,I serve as good examples to my posted problem. What I am trying to do is sort the row indices (and corresponding matrix values) of entries in each column.
Note: I already asked this question on Julia discourse here, but received no replies nor comments. If I can improve on the quality of the question, don't hesitate to tell me.
The problem is that a[1:5] is not a view, it's just a copy. instead make the view like
function sort!(a,b)
p=sortperm(a);
a[:], b[:] = a[p], b[p]
end
Threads.#threads for i in I[2:end]
sort!(view(a, I[i-1]:I[i]-1), view(b, I[i-1]:I[i]-1))
end
is what you are looking for
ps.
the #view a[2:3], #view(a[2:3]) or the #views macro can help making thins more readable.
First of all, you shouldn't redefine Base.sort! like this. Now, sort! will shadow Base.sort! and you'll get errors if you call sort!(a).
Also, a[I[i-1], I[i]-1] and b[I[i-1], I[i]-1] are not slices, they are just single elements, so nothing should happen if you sort them either with views or not. And sorting arrays in a moving-window way like this is not correct.
What you want to do here, since your vectors are huge, is call p = partialsortperm(a[i:end], i:i+block_size-1) repeatedly in a loop, choosing a block_size that fits into memory, and modify both a and b according to p, then continue to the remaining part of a and find next p and repeat until nothing remains in a to be sorted. I'll leave the implementation as an exercise for you, but you can come back if you get stuck on something.

Assigning values in an array into another array in MATLAB

I want to assign part of a matrix into another matrix using a for loop in MATLAB. I've tried different ways but none of them worked. I want to know what's wrong with this one:
fullGrid = complex(zeros(FFTLen, numSym, numTx),zeros(FFTLen, numSym, numTx));
for i=0:(numSym/2)-1
for j=0:(FFTLen/2)-1
A(i,j)=[fullGrid(i,j)];
end
end
You made a very basic mistake. The index position in a matrix/array in
Matlab starts from 1 and not 0. So replace all the for loops from 1 to
required length.
Corrected code is given below.
fullGrid = complex(zeros(FFTLen, numSym, numTx),zeros(FFTLen, numSym, numTx));
for i=1:(numSym/2)-1
for j=1:(FFTLen/2)-1
A(i,j)=[fullGrid(i,j)];
end
end

How to subtract matrices from elements of cell arrays in a loop?

I have created a cell array of dimensions 1x10, named A. Each element contains a 100x5 matrix. Hence, I got 10 matrices 100x5. However, I want to put every matrix of the cell array into a loop. If B is a 100x5 matrix, C is a 100x1 vector and c is a constant, the loop should look like:
for t=1:100;
j=1:5;
x=c*inv((B(t,j)-A(t,j))*((B(t,j)-A(t,j))')*(A(t,j)-C(t,1)*ones(1,5));
end;
end;
At the end x should deliver a 1x10 cell array that will contain 10 elements of matrices 100x5.
I would appreciate any help. Thank you in advance!
If I understand your question correctly, you are asking how to access a cell array. Let i index the cell array. Then you can access the ith entry of the cell array by calling A{i}. Then your code is:
for i=1:10
for t=1:100
j=1:5
x{i}=c*inv((B(t,j)-A{i}(t,j))*((B(t,j)-A{i}(t,j))')*(A{i}(t,j)-C(t,1)*ones(1,5));
end
end
end
You may want to think about your problem and whether or not you can eliminate the the two middle for loops by writing it in matrix notation. It looks similar to a least-squares estimator, which is (X'X)^(-1)*X'y, but the element-by-element inverse is throwing me off.

Inserting zeros into an array and looping using a for loop

I have several arrays that are calculated example a,b and c (there are more than three) are calculated: Please note this is just an example the numbers are much larger and are not so basic
a=[1,2,3,4,5] b=[10,20,30,40,50] c=[100,200,300,400,500] and I want a for loop that inserts zeros into it so I can have the new_abc array steps look like.
1st for loop step new_abc=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
2nd for loop step new_abc=[1,0,0,2,0,0,3,0,0,4,0,0,5,0,0]
3rd for loop step new_abc=[1,10,0,2,20,0,3,30,0,4,40,0,5,50,0]
4th for loop step new_abc=[1,10,100,2,20,200,3,30,300,4,40,400,5,50,500]
how can I do this with a for loop?
I started with the code below which gives me the zeros
a=[1,2,3,4,5]
new_abc=zeros(1,length(a)*(3));
But I'm not sure how to place the values of the array a b and c using a for loopinto the correct locations ofnew_abc
I know I could place all the arrays into one large array and do a reshape but the calculated arrays I use become to large and I run out of ram, so reading / calculating each array and inserting them into one common array new_abcusing a for loop works best.
I'm running octave 3.8.1 which is like matlab.
This should do it. You can put a,b,c into a cell array. (you can also put them in a matrix...)
new_abc = zeros(1, 3*numel(a));
in = {a, b, c};
for k = 1:3
new_abc(k:3:end) = in{k};
end

Converting a loop from Matlab to C

I have a (3x5) matrix and I want to get its reduced row echelon form.
I want to implement it in C, so I first impelemnted it in Matlab like follows:
[L,U]=lu(a);
[m,n]=size(U);
disp('convert elements in major diagonal to 1')
for s=1:m
U(s,:)=U(s,:)/U(s,s);
end
for j=m:-1:2
for i=j-1:-1:1
U(i,:)=U(i,:)-U(j,:)*(U(i,j)/U(j,j));
end
end
The above code and rref function gave the same result.
When converting this code to C, I successfully implemented the LU decomposition and the conversion of elements in major diagonal to 1 but when imlemented these nested loops
for j=m:-1:2
for i=j-1:-1:1
U(i,:)=U(i,:)-U(j,:)*(U(i,j)/U(j,j));
end
end
as follows:
for(j=m-1;j>0;j--){
for(i=j-1;i=0;i--){
for(k=0;k<n;k++){
U[i*n+k]=U[i*n+k]-(U[j*n+k]*(U[i*n+j]/U[j*n+j]));
}
}
}
I got a wrong result. How to correct it please?
If you take a closer look at your inner loop. As soon as you reach k=j you write the element U[i*n+j] or U(i,j) and use this updated value in all following iterations. Your matlab code uses the old value because you implemented vectorized operations. If you calculate *(U[i*n+j]/U[j*n+j]) outside the inner loop it should be fine.

Resources