Translating a matlab command to c# - matlab

Im new to matlab and i having trouble understanding this line of code
A((i-1)*nneg+1:i*nneg,:) =
ones(nneg,1)*temp(i,2:n+1)+
temp(npos+1:npos+nneg,2:n+1);
does this mean that ->
each element in A where x is being varied between :
(i-1)*nneg+1 and the upper bound i*nneg and for all y, will have assigned 1* .....
an element from temp or all elements in the range of the y (temp(i,2:n+1))?
and by the same reasoning one of the range of temp(npos+1:npos+nneg,2:n+1) or all added up?

The command updates some horizontal sub-matrix of A
A(a:b, :) = some range of rows, and ALL columns = some horizontal sub-matrix of A
A(:, c:d) = some range of columns, and ALL rows = = some vertical sub-matrix of A
UPDATE:
Without seeing more of your code, i cant be sure but the syntax suggests that temp(npos+1:npos+nneg,2:n+1) is a matrix, and ones(nneg,1)*temp(i,2:n+1) is offcourse also a matrix of the same size which contains only 1's.
(i-1)*nneg+1 and i*nneg will both be integers, where (i-1)*nneg+1 <= i*nneg. these two integers define a sub-matrix of A which will have their values updated.
ones(nneg,1) creates a vertical array of ones [1,1,1,1...] with length nneg. this is then multiplies with a horizontal array temp(i,2:n+1) which creates a matrix X. X is added to another matrix temp(npos+1:npos+nneg,2:n+1), and the sub-matrix of A (explained above) is updated with this result.

Related

matlab Create growing matrix with for loop that grows by 3 per loop

So I have written this:
HSRXdistpR = squeeze(comDatape_m1(2,7,1,:,isubj));
HSRXdistpL = squeeze(comDatape_m1(2,4,1,:,isubj));
TocomXdistp = squeeze(comDatape_m1(2,10,1,:,isubj));
for i = 1:2;
HSRXp = NaN(8,3*i);
HSRXp(:,i*3) = [HSRXdistpR(:,i) HSRXdistpL(:,i) TocomXdistp(:,i)];
end
In the first part I am just selecting data from a 5-D matrix, nothing special. All that's important here is that it creates an 8x2 matrix per line (isubj=2). Now I want to add the first column of each matrix into an 8x3 matrix, and then the second column of each matrix into the same matrix (creating an 8x6 matrix). Since the number of my subjects will vary, I want to do this in a for loop. This way, if the isubj increases to 3, it should go on to create an 8x9 matrix.
So I tried to create a matrix that will grow by 3 for each iteration of i, which selects the ith column of each of the 3 matrices and then puts them in there.
However I get the following error:
Subscripted assignment dimension mismatch.
Is it possible to let a matrix grow by more than one in a for loop? Or how should it be done otherwise?
Here is your problem:
HSRXp(:,i*3) = [HSRXdistpR(:,i) HSRXdistpL(:,i) TocomXdistp(:,i)];
You're trying to assign an n x 3 matrix (RHS) into an n x 1 vector (LHS). It would be easier to simply use horizontal concatenation:
HSRXp = [HSRXp, [HSRXdistpR(:,i) HSRXdistpL(:,i) TocomXdistp(:,i)]];
But that would mean reallocation at each step, which might slow your code down if the matrix becomes large.

MatLab: Create matrix row element if row elements of two previous matrices are identical

Sorry for the title. I could not think of something better.
I have the following problem.
I have two four-column matrices build up like this:
Property | X | Y | Z
The two matrices have different sizes, since matrix 1 has a large amount of additional rows compared to matrix 2.
What I want to do is the following:
I need to create a third matrix that only features those rows (of the large matrix) that are identical in columns X, Y and Z to rows in matrix2(the property column is always different).
I tried an if-statement but it did not really work out due to my programming syntax. Has somebody a tip?
Thank you!
I tried something like this: (in this case A is the larger matrix and I want its property column for X,Y,Z-positions that are identical to another matrix B.. I am terrible with the MatLab-syntax..
if (A(:,2) == B(:,2) and (A(:,3) == B(:,3) and (A(:,4) == B(:,4))
newArray(:,1) = A(:,1);
end
Use ismember with the 'rows' option to find the desired rows, and then use that as an index to build the result:
ind = ismember(A(:,2:4), B(:,2:4), 'rows');
C = A(ind,:);
I have assumed that a row of A is selected if its last three columns match those of any row of B.

Finding the largest vector inside a matrix

I am trying to find the largest vector inside a matrix compound by vectors with MATLAB, however I am having some difficulties, so I would be very thankful if someone help me. I have this:
The matrix paths (solution of a Dijkstra function), which is a 1000x1000 matrix, whose values are vectors of 1 row and different number of columns (when the columns are bigger than 10, the values appear as "1x11 double, 1x12 double, etc"). The matrix paths have this form:
1 2 3 ....
1 1 <1x20 double> <1x16 double>
2 <1x20 double> 2 [2,870,183,492,641,863,611,3]
3 <1x16 double> [3,611,863,641,492,183,870,2] 3
4 <1x25 double> <1x12 double> <1x14 double>
.
.
.
At first I thought in just finding the largest vector in the matrix by
B = max(length(paths))
However MATLAB returns B = 1000, value which is feasible, but not likely. When trying to find out the position of the vector by using:
[row,column] = find(length(paths) == B)
MATLAB returns row = 1, column = 1, which for sure is wrong... I have thought that maybe is a problem of how MATLAB takes the data. It is like it doesn't consider the entries of the matrix as vectors, because when I enter:
length(paths(3,2))
It returns me 1, but it should return 8 as I understand, also when introducing:
paths(3,2)
It returns [1x8 double] but I expect to see the whole vector. I don't know what to do, maybe a "for" loop, I really do not know if MATLAB takes the data of the matrix as vectors or as simple double values.
The cell with the largest vector can be found using cellfun and numel to get the number of elements in each numeric matrix stored in the cells of paths:
vecLens = cellfun(#numel,paths);
[maxLen,im] = max(vecLens(:));
[rowMax,colMax] = ind2sub(size(vecLens),im)
This gets a 1000x1000 numeric matrix vecLens containing the sizes, max gets the linear index of the largest element, and ind2sub translates that to row,column indexes.
A note on length: It gives you the size of the largest dimension. The size of paths is 1000x1000, so length(paths) is 1000. My advice is, Don't ever use length. Use size, specifying the dimension you want.
If multiple vectors are the same length, you get the first one with the above approach. To get all of them (starting after the max command):
maxMask = vecLens==maxLen;
if nnz(maxMask)>1,
[rowMax,colMax] = find(maxMask);
else
[rowMax,colMax] = ind2sub(size(vecLens),im)
end
or just
[rowMax,colMax] = find(vecLens==maxLen);

Maximum of a subset of array (MATLAB)

Suppose in MATLAB I have a real matrix A which is n x m and a binary matrix B of the same size. The latter matrix defines the optimization set (all indices for which the element of B equals one): over this set I would like to find the maximal element of A. How can I do this?
The first idea I had is that I consider C = A.*B and look for the maximal element of C. This works fine for all matrices A which have at least one positive element, however it does not work for matrices with all negative elements.
You can do
C = A(B==1);
to give you an array of just the values of A corresponding to a value of 1 in B. And
max( C )
will give you the maximum value of A where B is 1
With this method you don't run into a problem when all values of A are negative as the zeros don't appear in C.
Obviously you can condense this to
desiredValue = max(A(B(:)==1));
I am using the colon operator to make sure that the result of A(B(:)==1) is a column vector - if B is all ones I am not sure if Matlab would return a vector or a nxm matrix (and I can't confirm right now).
update to get the index of the value, you can do:
f = find(B==1);
[m mi] = max(A(f));
maxIndex = f(mi);
And to get that back to the 2D elements:
[i j] = ind2sub(size(A), maxIndex);

How can I generate a binary matrix with specific patterns?

I have a binary matrix of size m-by-n. Given below is a sample binary matrix (the real matrix is much larger):
1010001
1011011
1111000
0100100
Given p = m*n, I have 2^p possible matrix configurations. I would like to get some patterns which satisfy certain rules. For example:
I want not less than k cells in the jth column as zero
I want the sum of cell values of the ith row greater than a given number Ai
I want at least g cells in a column continuously as one
etc....
How can I get such patterns satisfying these constraints strictly without sequentially checking all the 2^p combinations?
In my case, p can be a number like 2400, giving approximately 2.96476e+722 possible combinations.
Instead of iterating over all 2^p combinations, one way you could generate such binary matrices is by performing repeated row- and column-wise operations based on the given constraints you have. As an example, I'll post some code that will generate a matrix based on the three constraints you have listed above:
A minimum number of zeroes per column
A minimum sum for each row
A minimum sequential length of ones per column
Initializations:
First start by initializing a few parameters:
nRows = 10; % Row size of matrix
nColumns = 10; % Column size of matrix
minZeroes = 5; % Constraint 1 (for columns)
minRowSum = 5; % Constraint 2 (for rows)
minLengthOnes = 3; % Constraint 3 (for columns)
Helper functions:
Next, create a couple of functions for generating column vectors that match constraints 1 and 3 from above:
function vector = make_column
vector = [false(minZeroes,1); true(nRows-minZeroes,1)]; % Create vector
[vector,maxLength] = randomize_column(vector); % Randomize order
while maxLength < minLengthOnes, % Loop while constraint 3 is not met
[vector,maxLength] = randomize_column(vector); % Randomize order
end
end
function [vector,maxLength] = randomize_column(vector)
vector = vector(randperm(nRows)); % Randomize order
edges = diff([false; vector; false]); % Find rising and falling edges
maxLength = max(find(edges == -1)-find(edges == 1)); % Find longest
% sequence of ones
end
The function make_column will first create a logical column vector with the minimum number of 0 elements and the remaining elements set to 1 (using the functions TRUE and FALSE). This vector will undergo random reordering of its elements until it contains a sequence of ones greater than or equal to the desired minimum length of ones. This is done using the randomize_column function. The vector is randomly reordered using the RANDPERM function to generate a random index order. The edges where the sequence switches between 0 and 1 are detected using the DIFF function. The indices of the edges are then used to find the length of the longest sequence of ones (using FIND and MAX).
Generate matrix columns:
With the above two functions we can now generate an initial binary matrix that will at least satisfy constraints 1 and 3:
binMat = false(nRows,nColumns); % Initialize matrix
for iColumn = 1:nColumns,
binMat(:,iColumn) = make_column; % Create each column
end
Satisfy the row sum constraint:
Of course, now we have to ensure that constraint 2 is satisfied. We can sum across each row using the SUM function:
rowSum = sum(binMat,2);
If any elements of rowSum are less than the minimum row sum we want, we will have to adjust some column values to compensate. There are a number of different ways you could go about modifying column values. I'll give one example here:
while any(rowSum < minRowSum), % Loop while constraint 2 is not met
[minValue,rowIndex] = min(rowSum); % Find row with lowest sum
zeroIndex = find(~binMat(rowIndex,:)); % Find zeroes in that row
randIndex = round(1+rand.*(numel(zeroIndex)-1));
columnIndex = zeroIndex(randIndex); % Choose a zero at random
column = binMat(:,columnIndex);
while ~column(rowIndex), % Loop until zero changes to one
column = make_column; % Make new column vector
end
binMat(:,columnIndex) = column; % Update binary matrix
rowSum = sum(binMat,2); % Update row sum vector
end
This code will loop until all the row sums are greater than or equal to the minimum sum we want. First, the index of the row with the smallest sum (rowIndex) is found using MIN. Next, the indices of the zeroes in that row are found and one of them is randomly chosen as the index of a column to modify (columnIndex). Using make_column, a new column vector is continuously generated until the 0 in the given row becomes a 1. That column in the binary matrix is then updated and the new row sum is computed.
Summary:
For a relatively small 10-by-10 binary matrix, and the given constraints, the above code usually completes in no more than a few seconds. With more constraints, things will of course get more complicated. Depending on how you choose your constraints, there may be no possible solution (for example, setting minRowSum to 6 will cause the above code to never converge to a solution).
Hopefully this will give you a starting point to begin generating the sorts of matrices you want using vectorized operations.
If you have enough constraints, exploring all possible matrices could be attempted:
// Explore all possibilities starting at POSITION (0..P-1)
explore(int position)
{
// Check if one or more constraints can't be verified anymore with
// all values currently set.
invalid = ...;
if (invalid) return;
// Do we have a solution?
if (position >= p)
{
// print the matrix
return;
}
// Set one more value and continue exploring
for (int value=0;value<2;value++)
{ matrix[position] = value; explore(position+1); }
}
If the number of constraints is low, this approach will take too much time.
In this case, for the kind of constraints you gave as examples, simulated annealing may be a good solution.
You must design an energy function, high when all constraints are met. That would be something like that:
Generate a random matrix
Compute energy E0
Change one cell
Compute energy E1
If E1>E0, or E0-E1 is smaller than f(temperature), keep it, otherwise reverse the move
Update temperature, and goto 2 unless stop criterion is reached
If all the contraints relate to columns (as is the case in the question), then you can find all possible valid columns and check that each column in the matrix is in this set. (i.e. when you consider each column independently, you reduce the number of possibilities a lot.)
I might be way off here, but I remember doing something similar once with some genetic algorithm.
Check out pseudo boolean constraints (also called 0-1 integer programming).
This is virtually impossible if your constraint set is complex enough. You might try to use a stochastic optimizer, like simulated annealing, particle swarm optimization, or a genetic algorithm to find a feasible solution.
However, if you can generate one (non-random) solution to such a problem, then often you can generate others by random permutations made to the existing solution.