Outputting from loop to array in Matlab without overwriting - arrays

I have a script to take the output of a simulink model and put this information in an array, such that each loop is written and then can be plotted/analysed etc. However on running the script I get the following:
test1
Outvs =
68.0000
68.0007
68.0430
68.0746
In an assignment A(I) = B, the number of elements in B and I must be the same.
Error in test1 (line 19)
output(sensv0) = Outvs;
My script is the following:
%Vectors/containers to store values%
%input = zeros(4,4);
output = zeros(4,4);
%INITIAL VELOCITY (v0)
%do a sensitivity analysis for different input values
for sensv0 = 85:88
%step 1: define input value to variable
v0 = sensv0;
%step 2: run simulation
sim('sldemo_absbrake');
%step 3: look at graphs at t=0,5,10,15s for Vehicle Speed
Outvs = getdatasamples(vs, [2,6,11,14]);
%Display Outvs (troubleshooting)
Outvs
%input(sensv0) = v0;
output(sensv0) = Outvs;
end

Two ways to handle such things.
If the size of outvs is constant, you can initialize a variable with the appropriate size:
var=zeros([4,4])
for k=85:88
var(k-84, :)=outvs;
end
the size of outvs varies, use a cell array (with curvy braces).
for k=85:88
var{k-84}=outvs;
end

Related

How to share counter variable among threads using threadpool.executor and increment it?

Following is a thread pool executor that I have implemented in python 3.x
with ThreadPoolExecutor(max_workers=15) as ex:
f = open(filename, 'r', encoding='UTF-8')
results = {ex.submit(callreadline, files ): files for files in f.readlines() }
The results variable contains values in the following format:
words and their corresponding 200 dimensional embedding
You can see that the values are tuples. The first value is a word and the 2nd value is 200 dimensional array. The number of values are 400000 in total. So there are 400000 tuples.
Now what I want to do is create another thread pool executor that does the following task
Create a ordered dictionary of the first values in the tuple list. This means that say words of the first 4 tuple values are the, is ,are, said. Then the ordered dictionary will contain:
{the:0,is:1,are:2,said:3,...…………….hello:399999}
Create a numpy nd array which contains the 200 dimensional array of the corresponding words in ordered dictionary(By corresponding word I mean the first entry will be of 200 dimensional array of word the, then 200 dimensional array of is...and the list goes on). So the numpy nd array will be of dimension 400000 * 200.
I was using for loop with the following code
count = 0
word_to_idx = OrderedDict()
vectors = []
for future in results.result:
b = future.result()
word_to_idx[count] = b[0]
if(count == 0):
vectors = np.array([b[1]])
else:
vectors = np.append(vectors,np.array([b[1]]),axis=0)
count = count +1
At the end of the above function I returned word_to_idx and vectors which did the job. However, the looping of 400000 tuples and assigning one by one to variable took extremely long time(about 10 hours).
So I was thinking if there is a way of parallelizing this functionality as well using thread pool executor.
I was thinking of creating threads and then share a counter variable with each thread getting access to the shared variable one at a time. The thread would then increment that variable and then another thread will access the incremented counter. Could someone point me to the right direction?
Edit:
Here is the call readline function which works really fast as it is called with 15 workers:
def callreadline(line):
# word_to_idx = OrderedDict()
word_to_idx = OrderedDict()
vectors = []
vocabulary = None
word_to_idx = read_w2v_word(line.split(' ')[0])
try:
vectors = np.append(vectors, [np.array(line.split(' ')[1:])], axis=0)
except:
vectors = np.array(line.split(' ')[1:],dtype=float)
if vocabulary is not None:
word_to_idx, vectors = filter_words(word_to_idx, vectors, vocabulary)
return word_to_idx,vectors
I have a feeling the callreadline function also isn't even close to being as fast as it could be, but it wasn't part of the question, so let me try to fix the rest for you:
with ThreadPoolExecutor(max_workers=15) as ex:
f = open(filename, 'r', encoding='UTF-8')
results = [ex.submit(callreadline, files) for files in f.readlines()]
word_to_idx = dict()
vectors = []
for count, future in enumerate(results):
b = future.result()
word_to_idx[b[0]] = count
vectors.append(b[1])
vectors = np.array(vectors)

How To Loop Array with Two Samples in Matlab?

I would like to take two constants from the array constants at a time because I do not want to go one by one these constants through because it is time consuming; instead, I compare the changes what they cause and only react if there is a big change between the effects of two constants.
I am looping one sample constant in the array constants at a time in Matlab 2016a
constants=[45 90 180 360 720 1440 2880 5760]';
for constant=constants
...
end
However, I would like to take two constants at a time by one loop, like pseudocode
for constant1,constant2=constants
...
end
How can you take two constant(s) from constants in one for loop of Matlab?
Something like this?
for index = 1:length(constants) - 1
c1 = constants(index);
c2 = constants(index + 1);
end
Another option is to define a function that pairs each element with the next element in the array -
function result = pairAdjacent(array)
result = [array(1:end-1) ; array(2:end)];
end
and then do
for constant = pairAdjacent(constants)
c1 = constant(1);
c2 = constant(2);
end
Recall that when you use the notation
for elem = array
// Now elem is a single column from array
end
the variable elem is assigned successively to each of the columns of array, so your array constants needs to be a 1xN array for this to work correctly.

How to name variables in a data array using a for loop

I have an array within an array and I am trying to name the variables using a for loop as there are a lot of variables. When I use the following simple code Time1 = dataCOMB{1,1}{1,1}(1:1024, 1); it opens the first cell in an array and proceeds to open the first cell in the following array and finally defines all the values in column 1 rows 1 to 1024 as Time1. However I have 38 of these different sets of data and when I apply the following code:
for t = 1:38
for aa = 1:38
Time(t) = dataCOMB{1,1}{1,aa}(1:1024, 1);
end
end
I get an error
In an assignment A(I) = B, the number of elements in B and I must be the same.
Error in Load_Files_working (line 39)
Time(t) = dataCOMB{1,1}{1,aa}(1:1024, 1);
Basically I am trying to get matlab to call the first column in each data set Time1, Time2, etc.
The problem:
1)You'd want to extract in a cell row...
2) ...the first 1024 numbers in the 1st column...
3) ...from each of the first 38 cells of a cell array.
The plan:
1) If one wants to get info from each element of a cell array (that is, an array accessed via {} indexing), one may use cellfun. Calling cellfun(some_function, a_cell_array) will aggregate the results of some_function(a_cell_array{k}) for all possible k subscripts. If the results are heterogeneous (i.e. not having the same type and size), one may use the cell_fun(..., 'UniformOutput', false) option to put them in an output cell array (cell arrays are good at grouping together heterogeneous data).
2) To extract the first 1024 numbers from the first column of an numeric array x one may use this anonymous function: #(x) x(1:1024,1). The x argument will com from each element of a cell array, and our anonymous function will play the role of some_function in the step above.
3) Now we need to specify a_cell_array, i.e. the cell array that contains the first 38 cells of the target. That would be, simply dataCOMB{1,1}(1,1:38).
The solution:
This one-liner implements the plan:
Time = cellfun(#(x) x(1:1024,1), dataCOMB{1,1}(1,1:38), 'UniformOutput', false);
Then you can access your data as in this example:
this_time = Time{3};
Your error is with Time(t). That's not how you create a new variable in matlab. To do exactly what you want (ie, create variables names Time1, Time2, etc...you'll need to use the eval function:
for aa = 1:38
eval(['Time' num2str(aa) '= dataCOMB{1,1}{1,aa}(1:1024,1);']);
end
Many people do not like recommending the eval function. Others wouldn't recommend moving all of your data out of a data structure and into their own independently-named variables. So, to address these two criticisms, a better alternative might be to pull your data out of your complicated data structure and to put it into a simpler array:
Time_Array = zeros(1024,38);
for aa = 1:38
Time_Array(:,aa) = dataCOMB{1,1}{1,aa}(1:1024,1);
end
Or, if you don't like that because you really like the names Time1, Time2, etc, you could create them as fields to a data structure:
Time_Data = [];
for aa = 1:38
fieldname = ['Time' num2str(aa)];
Time_Data.(fieldname) = dataCOMB{1,1}{1,aa}(1:1024,1);
end
And, in response to a comment below by the original post, this method can be extended to further unpack the data:
Time_Data = [];
count = 0;
for z = 1:2;
for aa = 1:38
count = count+1;
fieldname = ['Time' num2str(count)];
Time_Data.(fieldname) = dataCOMB{1,z}{1,aa}(1:1024,1);
end
end

Concatenating 1D matrices of different sizes

I perhaps am going about this wrong, but I have data{1}, data{2}...data{i}. Within each, I have .type1, .type2.... .typeN. The arrays are different lengths, so horizontal concatenation does not work.
For simplicity sake
>> data{1}.type1
ans =
1
2
3
>> data{2}.type1
ans =
2
4
5
6
Results should be [1;2;3;2;4;5;6]
I've been trying to loop it but not sure how? I will have a variable number of files (a,b..). How do I go about looping and concatenating? Ultimately I need a 1xN array of all of this..
My working code, thanks..figured it out..
for i = 1:Types
currentType = nTypes{i}
allData.(currentType)=[];
for j = 1:nData
allData.(currentType) = [allData.(currentType); data{j}.(currentType)(:,3)]; %3rd column
end
end
Look at cat, the first argument is the dimension. In your simple example it would be:
result = cat(1,a,b);
Which is equivalent to:
result = [a;b];
Or you can concatenate them as row vectors and transpose back to a column vector:
result = [a',b']';
For the case of a structure inside a cell array I don't think there will be any way around looping. Let's say you have a cell array with M elements and N "types" as the structure fields for each element. You could do:
M=length(data);
newData=struct;
for i=1:M
for j=1:N
field=sprintf('type%d',j); % //field name
if (M==1), newData.(field)=[]; end % //if this is a new field, create it
newData.(field)=[newData.(field);data{i}.(field)];
end
end

Compute inner poduct without IML

I am trying to create a macro that compute the inner(dot) product of a vector and a matrix.
Y*X*t(Y) ## equivalent to the Sum(yi*Xij*yj)
I don't have IML, so I try to do it using array manipulation.
How to create a multidimensional array from the data to avoid index
translation within single array.
How to debug my loop, or at least print some variable to control my program?
How to delete temporary variables?
I am a SAS newbie, but this is what I have tried so far:
%macro dot_product(X = ,y=, value= );
/* read number of rows */
%let X_id=%sysfunc(open(&X));
%let nrows=%sysfunc(attrn(&X_id,nobs));
%let rc=%sysfunc(close(&X_id));
data &X.;
set &X.;
array arr_X{*} _numeric_;
set &y.;
array arr_y{*} _numeric_;
do i = 1 to &nrows;
do j = 1 to &nrows;
value + arr_y[i]*arr_X[j + &nrows*(i-1)]*arr_y[j];
end;
end;
run;
%mend;
When I run this :
%dot_product(X=X,y=y,value=val);
I get this error :
ERROR: Array subscript out of range at line 314 column 158.
I am using this to generate data :
data X;
array myCols{*} col1-col5;
do i = 1 to 5;
do j = 1 to dim(myCols);
myCols{j}=ranuni(123);
end;
output;
end;
drop i j;
run;
/* create a vector y */
data y;
array myCols{*} col1-col5;
do j = 1 to dim(myCols);
myCols{j}=ranuni(123);
end;
output;
drop j;
run;
Thanks in advance for your help or any idea to debug my data.
Edit: The following relates to the description of the question, how to evaluate a quadratic form using dot, inner or scalar products. The actual code is nearly fine. end edit
If you want to reduce it to dot products, then your value is the dot product of the linearization of X_ij and the same linearization applied to Z_ij=Y_i*Y_j.
The other way is to portion X_ij into its rows or columns depending on the linearization of the matrix, and compute separate dot products of Y with, say, each row. Of the resulting vector you the compute the dot product again with Y.
Edit added: The length nrows of the nested loops in the code should be determined from the length of the vector y, perhaps with a check that the length of x is nrows*nrows.

Resources