Multiplication of cell elements with a vector in matlab - matlab

If I have a cell containing 2 matrices:
A = {[10 0 0 10 0 20 15;
0 10 10 15 0 0 20;
10 0 0 12 11 0 0;
10 0 0 0 19 0 14;
18 13 0 0 0 15 0;
0 10 0 0 0 10 15]
[ 0 0 10 0 20 15;
10 10 15 0 0 20;
0 0 12 11 0 0;
0 0 0 19 0 14;
13 0 0 0 15 0;
11 0 13 0 15 0]}
B = [500 550 600 650 700 550]
I want to multiply each matrix with this vector in a way that 1st row of A is multiplied by 1st element of B, 2nd row of A with 2nd element of B, ..., and 6th row of A with 6th element of B. how to define this since A is a cell?

You can use cellfun to operate on each element in A separately, and bsxfun to multiply each row in the matrices in A by one element in B:
celltimes = #(A) bsxfun(#times,A,B.');
C = cellfun(celltimes,A,'UniformOutput',false)
the result:
>> celldisp(C)
C{1} =
Columns 1 through 4
5000 0 0 5000
0 5500 5500 8250
6000 0 0 7200
6500 0 0 0
12600 9100 0 0
0 5500 0 0
Columns 5 through 7
0 10000 7500
0 0 11000
6600 0 0
12350 0 9100
0 10500 0
0 5500 8250
C{2} =
Columns 1 through 4
0 0 5000 0
5500 5500 8250 0
0 0 7200 6600
0 0 0 12350
9100 0 0 0
6050 0 7150 0
Columns 5 through 6
10000 7500
0 11000
0 0
0 9100
10500 0
8250 0
As pointed by #Adriaan in the comments, in Matlab 2016b bsxfun is implicitly implemented, so you can just write:
C = cellfun(#(A) A.*B.',A,'UniformOutput',false);

Related

How to exclud rows and columns of a square array from calculations in MATLAB?

I have a 10*10 array for a domain
TT =
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
, but I need to exclude a square centered in the domain, so the new domain would be :
TT_new =
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
I will create a for loop for the domain TT_new, how can I do this operation in MATLAB?
Clarification: I need the for loop to go through the "i,j" of the new domain "TT_new".
For example, I have the following mesh plot for steady heat conduction problem for a U-shaped plate:
2D plot
3D plot
I need to exclude the purple rectangular from the plot because it is not within the computational domain.
Have you thought about using a mask?
You can't have matrices with holes in them, but if you element-wise multiply your original array with a matrix containing ones everywhere and zeros in the places you want to remove, your result will be an array containing the original numbers everywhere but zeros where you have zeros in your mask. For example:
my_arr = reshape(1:30, 5, 6);
my_mask = ones(5, 6);
my_mask(1:3, 3:4) = 0;
masked_arr = my_arr .* my_mask;
This gives:
my_arr =
1 6 11 16 21 26
2 7 12 17 22 27
3 8 13 18 23 28
4 9 14 19 24 29
5 10 15 20 25 30
my_mask =
1 1 0 0 1 1
1 1 0 0 1 1
1 1 0 0 1 1
1 1 1 1 1 1
1 1 1 1 1 1
masked_arr =
1 6 0 0 21 26
2 7 0 0 22 27
3 8 0 0 23 28
4 9 14 19 24 29
5 10 15 20 25 30
Whether this is applicable to your situation depends on how you use the boundaries of your computational domain in your computation. Multiplying by a mask containing NaN will change unwanted elements to NaN.
Then, you could apply your mask before (or after, or both) every iteration to ensure that the unwanted elements are set to zero (or NaN, but that can cause problems if you add / subtract / multiply those elements with anything).
domain_mask = ones(size(T));
domain_mask(7:16, 12:31) = 0;
domain_mask_small = domain_mask(2:end-1, 2:end-1);
zero_row = zeros(1, size(T, 2));
zero_col = zeros(size(T, 1), 1);
while error > tol
% Perform operations on the entire array
T_iplus1 = [T(2:end, :); zero_row];
T_iminus1 = [zero_row; T(1:end-1, :)];
T_jplus1 = [T(:, 2:end), zero_col];
T_jminus1 = [zero_col, T(:, 1:end-1)];
T_temp = 0.25 * (T_iplus1 + T_iminus1 + T_jplus1 + T_jminus1);
T(2:end-1, 2:end-1) = T_temp(2:end-1, 2:end-1) .* domain_mask_small;
% Do whatever else
end

How do you trace all connected nonzero elements in a matrix in MATLAB?

Suppose I define the following simple matrix in MATLAB:
myImage3 = zeros(10,10);
for i=1:10
for j=i:2:10
myImage3(i,j) = 20;
end
end
Then myImage is a 10x10 matrix that looks like:
myImage3 =
20 0 20 0 20 0 20 0 20 0
0 20 0 20 0 20 0 20 0 20
0 0 20 0 20 0 20 0 20 0
0 0 0 20 0 20 0 20 0 20
0 0 0 0 20 0 20 0 20 0
0 0 0 0 0 20 0 20 0 20
0 0 0 0 0 0 20 0 20 0
0 0 0 0 0 0 0 20 0 20
0 0 0 0 0 0 0 0 20 0
0 0 0 0 0 0 0 0 0 20
How do I write a function that tracks or traces through all connected nonzero elements of the matrix? For example, if I start at (1,1), we have the following trace:
(1,1) --> (2,2) --> (3,3) ---> ... --> (10,10).
But if I start at (1,3), we have the following trace:
(1,3) --> (2,4) -> (3,5) ---> ... --> (8,10).
Similarly, if I start at (1,5), we have the following trace:
(1,5) --> (2,6) --> (3,7) ---> ... --> (6,10).
The elements do not need to be "20", but rather could be any non-zero number. Also, the elements do not have to be perfectly diagonal. They could be a zig zag like shown below:
myImage2 =
10 0 0 0 0 0 0 0 0 0
0 5 0 0 0 0 0 0 0 0
0 0 20 0 0 0 0 0 0 0
0 0 21 0 0 0 0 0 0 0
0 0 14 15 20 0 0 0 0 0
0 0 0 0 0 20 0 0 0 0
0 0 0 0 0 0 20 0 0 0
0 0 0 0 0 0 0 20 0 0
0 0 0 0 0 0 0 0 20 0
0 0 0 0 0 0 0 0 0 20
But notice that if I start at (1,1) again, every neighboring pixel has another non-zero neighboring pixel (i.e. connected).
The trace, starting at (1,1) would now look like:
(1,1)--> (2,2)--> (3,3) --> (4,3) --> (5,3)--> (5,4)--> (5,5)--> (6,6)--> (7,7)--> (8,8)--> (9,9)--> (10,10)
I think I need to use Depth First Search, but all the algorithms I see apply to adjacency matrices, not the type of matrices shown above.

How to solve linear algebra equation AC=D where A is non-square matrix [duplicate]

This question already has answers here:
How to perform inverse in GF(2) and multiply in GF(256) in Matlab?
(2 answers)
Closed 7 years ago.
I have a binary matrix A (only 1 and 0), and a vector D in Galois field (256) The vector C is calculated as:
C = (A^^-1)*D
where A^^-1 denotes the inverse matrix of matrix A in GF(2), * is multiplication operation. The result vector C must be in GF(256).
However, I only have a matrix A1 is non-square matrix. The above matrix A in the equation is created by delete some dependence rows of A1. In same manner, the vector D is constructed by delete some element corresponding the deleted rows in A1. Hence, we can solve above equation. My question is that can we have any function in MATLAB to do above steps?
For example, I have A1 is 16x14 matrix, D1 is 16x1 vector
A1 =[1 0 0 1 1 0 0 0 0 0 0 0 0 0
1 1 0 0 0 1 0 0 0 0 0 0 0 0
1 1 1 0 0 0 1 0 0 0 0 0 0 0
0 1 1 1 0 0 0 1 0 0 0 0 0 0
0 0 1 1 0 0 0 0 1 0 0 0 0 0
1 1 0 1 1 0 0 1 0 1 0 0 0 0
1 0 1 1 0 1 0 0 1 0 1 0 0 0
1 1 1 0 0 0 1 1 1 0 0 1 0 0
0 1 1 1 1 1 1 0 0 0 0 0 1 0
0 0 0 0 1 1 1 1 1 0 0 0 0 1
0 1 1 1 1 0 1 1 1 0 1 1 1 0
0 0 0 1 0 0 0 1 0 0 0 0 0 0
0 0 1 0 0 0 0 1 0 0 0 0 0 0
1 1 1 1 0 0 0 0 0 0 0 0 0 0
0 0 1 1 0 0 0 0 1 1 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0 0 0 1 ]
D1=[0; 0; 0; 0 ; 0; 0 ; 0; 0 ; 0 ; 0 ; 103 ; 198 ; 105 ; 115; 175 ; 14]
In above example, we need to delete two dependence rows/cols from A1 to obtain A is 14x14 matrix and D1 also delete 2 elements to obtain D, and then my expected result is
C=A^^-1*D
C= [ 103; 187 ; 125; 210 ; 181; 220 ; 161 ; 20 ; 175; 175; 187; 187 ; 220 ; 115]
This is what I tried
%%A1=gf(A1,8);
%%D1=gf(D1,8); %%2^8=256
%% Do something and last step is
%%C=inv(A)*D
[C,vld] = gflineq(A1,D1,8)
Or
C=gf(A1,8) \ gf(D1,8)
However, these ways did not return the my expected C vector. I found that Gaussian Elimination can be worked, but I don't know how can I apply for my case. Could you give me a correct solution?
First of all, I don't have access to the "Communication system toolbox", so in order to operate in GF(2) I have to add mod(stuff,2) calls in the code, and in order to operate in GF(2^8) I had to implement a function that sums in this field. Just define your variables with gf and remove these calls if you have access to the toolbox.
Prerequisite : Summing in GF(2^8) :
Summing in GF(2^8) is not trivial, as it behaves like (Z/2Z)^8.
In order to sum in this field, I have the following function.
Basically, elements in GF(2^8) are 8-tuples, each element taking a value in {0,1}. For example, (1,1,0,0,0,1,1,0) is one of them. In order to sum two tuples in this field, ones has, for each element to take the sum in Z/2Z.
For example, if we want the sum of (0,0,0,1,0,0,0,1) and (1,1,1,1,1,1,1,1) : (Remember that in Z/2Z, 0+0=0 , 0+1=1 , 1+0=1 and 1+1=0)
First elements of these tuple are 0 and 1, so the first element of the sum will be 0+1=1. Do this with all elements and you obtain :
(0,0,0,1,0,0,0,1)+(1,1,1,1,1,1,1,1)=(1,1,1,0,1,1,1,0)
The function operates the same way :
1) Transform inputs into binary numbers
2) Compare each digit. If they're equal they sum up to 0 (0+0=0 , 1+1=0), if not they sum up to 1 (0+1=1 and 1+0=1).
3) Transform result back into decimal numbers
function [D] = SumInGF256(D1,D2)
%UNTITLED3 Summary of this function goes here
% Detailed explanation goes here
A=size(D1);
P=numel(D1);
D=zeros(A);
D1=dec2bin(D1,8);
D2=dec2bin(D2,8);
% TmpD=cell(A);
for jj=1:P
TmpD1=D1(jj,:);
TmpD2=D2(jj,:);
out='';
for ii=1:8
if isequal(TmpD1(ii),TmpD2(ii))
out=strcat(out,'0');
else
out=strcat(out,'1');
end
end
D(jj)=bin2dec(out);
end
Gaussian elimination in GF(2) works exactly the same way in essance than in R or C, except it's much easier due to the fact that 1+1=0. Here's the code :
A1 =[1 0 0 1 1 0 0 0 0 0 0 0 0 0;...
1 1 0 0 0 1 0 0 0 0 0 0 0 0;...
1 1 1 0 0 0 1 0 0 0 0 0 0 0;...
0 1 1 1 0 0 0 1 0 0 0 0 0 0;...
0 0 1 1 0 0 0 0 1 0 0 0 0 0;...
1 1 0 1 1 0 0 1 0 1 0 0 0 0;...
1 0 1 1 0 1 0 0 1 0 1 0 0 0;...
1 1 1 0 0 0 1 1 1 0 0 1 0 0;...
0 1 1 1 1 1 1 0 0 0 0 0 1 0;...
0 0 0 0 1 1 1 1 1 0 0 0 0 1;...
0 1 1 1 1 0 1 1 1 0 1 1 1 0;...
0 0 0 1 0 0 0 1 0 0 0 0 0 0;...
0 0 1 0 0 0 0 1 0 0 0 0 0 0;...
1 1 1 1 0 0 0 0 0 0 0 0 0 0;...
0 0 1 1 0 0 0 0 1 1 0 0 0 0;...
0 0 1 0 0 0 0 0 0 0 0 0 0 1 ];
D1=[0; 0; 0; 0 ; 0; 0 ; 0; 0 ; 0 ; 0 ; 103 ; 198 ; 105 ; 115; 175 ; 14];
for ii=1:14
% Find ii-th pivot index between row ii and last row
PivIndex=find(A1(ii:end,ii),1)+ii-1;
% Switch ii-th row with Pivot row
A1([ii PivIndex],:)=A1([PivIndex ii],:);
D1([ii PivIndex])=D1([PivIndex ii]);
% Find all rows other than row ii containing a 1 in column ii
RowIndexes=find(A1(:,ii));
RowIndexes(RowIndexes==ii)==[];
% Add row ii to all rows in RowIndexes, do the same in D
A1(RowIndexes,:)=mod(A1(RowIndexes,:)+repmat(A1(ii,:),numel(RowIndexes),1),2);
%% Problem with my answer was here, as the sum in GF(256) doesn t work like that. (GF(256),+) behaves like ((Z/2Z)^8,+)... See prequisite for summing in GF(256)
% D1(RowIndexes)=mod(D1(RowIndexes)+repmat(D1(ii),numel(RowIndexes),1),256);
D1(RowIndexes)=SumInGF256(D1(RowIndexes),repmat(D1(ii),numel(RowIndexes),1));
end
% Now A1 is diagonal, with both last rows being zero. Problem is D
% has to be 0 aswell on the 2 last positions to get 0=0..
% Check if D(15:16)==[0;0] if not the system has no solution
if isequal(D1(15:16),[0;0])
A2=A1(1:14,:);
C=D1(1:14)
else
disp('No solution')
end
Here the output is as you wanted :
C =
103 187 125 210 181 220 161
20 175 175 187 187 220 115
First of all, I would like thank BillBokeey for your work. However, I am working in GF(256), it is more complex than GF(2). After google, I find a good solution for my case. This is source code for rfc-6330. In that source code, he had a function that is rfc6330_gaussian. For my question above, it is easy to apply it by
C=rfc6330_gaussian( A1, D1 )
So the result will be similar my expected result
C=[ 103
187
125
210
181
220
161
20
175
175
187
187
220
115]
This ans. will be useful for anyone who has similar my issue.

Matrix Row manipulation in Breeze using Scala?

I've a DenseMatrix
1 2 3 0 0 0 0 0 0
0 0 0 11 22 33 0 0 0
0 0 0 0 0 0 111 222 333
I want to remove the first row and then a last row with all 0s
0 0 0 11 22 33 0 0 0
0 0 0 0 0 0 111 222 333
0 0 0 0 0 0 0 0 0
How do I achieve this in Breeze ?
First, gather the rows you still want:
val subset = matrix(::, 2 to 3)
then add the zeroes:
val newMatrix = DenseMatrix.horzcat(subset, DenseMatrix.zeros[Double](1,9))
I might have mixed up rows and columns in the last line.

Concatenating binary bits into a number

I want to concatenate last four bits of binary into a number i have tried the following code
x8=magic(4)
x8_n=dec2bin(x8)
m=x8_n-'0'
which gives me the following output
m =
1 0 0 0 0
0 0 1 0 1
0 1 0 0 1
0 0 1 0 0
0 0 0 1 0
0 1 0 1 1
0 0 1 1 1
0 1 1 1 0
0 0 0 1 1
0 1 0 1 0
0 0 1 1 0
0 1 1 1 1
0 1 1 0 1
0 1 0 0 0
0 1 1 0 0
0 0 0 0 1
now i want to take every last 4 bits it each row and convert it into an integer
n = 4; %// number of bits you want
result = m(:,end-n+1:end) * pow2(n-1:-1:0).'; %'// matrix multiplication
Anyway, it would be easier to use mod on x8 directly, without the intermediate step of m:
result = mod(x8(:), 2^n);
In your example:
result =
0
5
9
4
2
11
7
14
3
10
6
15
13
8
12
1
This could be another approach -
n = 4; %%// number of bits you want
out = bin2dec(num2str(m(:,end-n+1:end)))
Output -
out =
0
5
9
4
2
11
7
14
3
10
6
15
13
8
12
1