How to covert vector A to symmetric matrix M in MATLAB
Such that M is a symmetric matrix (i.e. A21=A12) and all diagonal terms are equal (i.e. A11=A22=A33=A44).
Use hankel to help you create the symmetric matrix, then when you're finished, set the diagonal entries of this intermediate result to be the first element of the vector in A:
M = hankel(A,A(end:-1:1));
M(eye(numel(A))==1) = A(1);
Example
>> A = [1;2;3;4]
A =
1
2
3
4
>> M = hankel(A,A(end:-1:1));
>> M(eye(numel(A))==1) = A(1)
M =
1 2 3 4
2 1 4 3
3 4 1 2
4 3 2 1
As you can see, M(i,j) = M(j,i) except for the diagonal, where each element is equal to A(1).
Related
I am looking for a matrix operation of the form: B = M*A*N where A is some general square matrix and M and N are the matrices I want to find.
Such that the columns of B are the diagonals of A. The first column the main diagonal, the second the diagonal shifted by 1 from the main and so on.
e.g. In MATLAB syntax:
A = [1, 2, 3
4, 5, 6
7, 8, 9]
and
B = [1, 2, 3
5, 6, 4
9, 7, 8]
Edit:
It seems a pure linear algebra solution doesn't exist. So I'll be more precise about what I was trying to do:
For some vector v of size 1 x m. Then define C = repmat(v,m,1). My matrix is A = C-C.';.
Therefore, A is essentially all differences of values in v but I'm only interested in the difference up to some distance between values.
Those are the diagonals of A; but m is so large that the construction of such m x m matrices causes out-of-memory issues.
I'm looking for a way to extract those diagonals in a way that is as efficient as possible (in MATLAB).
Thanks!
If you're not actually looking for a linear algebra solution, then I would argue that constructing three additional matrices the same size as A using two matrix multiplications is very inefficient in both time and space complexity. I'm not sure it's even possible to find a matrix solution, given my limited knowledge of linear algebra, but even if it is it's sure to be messy.
Since you say you only need the values along some diagonals, I'd construct only those diagonals using diag:
A = [1 2 3;
4 5 6;
7 8 9];
m = size(A, 1); % assume A is square
k = 1; % let's get the k'th diagonal
kdiag = [diag(A, k); diag(A, k-m)];
kdiag =
2
6
7
Diagonal 0 is the main diagonal, diagonal m-1 (for an mxm matrix) is the last. So if you wanted all of B you could easily loop:
B = zeros(size(A));
for k = 0:m-1
B(:,k+1) = [diag(A, k); diag(A, k-m)];
end
B =
1 2 3
5 6 4
9 7 8
From the comments:
For v some vector of size 1xm. Then B=repmat(v,m,1). My matrix is A=B-B.'; A is essentially all differences of values in v but I'm only interested in the difference up to some distance between values.
Let's say
m = 4;
v = [1 3 7 11];
If you construct the entire matrix,
B = repmat(v, m, 1);
A = B - B.';
A =
0 2 6 10
-2 0 4 8
-6 -4 0 4
-10 -8 -4 0
The main diagonal is zeros, so that's not very interesting. The next diagonal, which I'll call k = 1 is
[2 4 4 -10].'
You can construct this diagonal without constructing A or even B by shifting the elements of v:
k = 1;
diag1 = circshift(v, m-k, 2) - v;
diag1 =
2 4 4 -10
The main diagonal is given by k = 0, the last diagonal by k = m-1.
You can do this using the function toeplitz to create column indices for the reshuffling, then convert those to a linear index to use for reordering A, like so:
>> A = [1 2 3; 4 5 6; 7 8 9]
A =
1 2 3
4 5 6
7 8 9
>> n = size(A, 1);
>> index = repmat((1:n).', 1, n)+n*(toeplitz([1 n:-1:2], 1:n)-1);
>> B = zeros(n);
>> B(index) = A
B =
1 2 3
5 6 4
9 7 8
This will generalize to any size square matrix A.
I have a matrix M[1,98] and a matrix N[1,x], let's assume in this case x =16.
What I want is to multiply N by M , make the sum by element, and increment the matrix M. With the finality of getting an output of [1,98].
It's a bit confusing. An example:
M=[2 3 4 5 6 7]
N=[1 2 3]
it1=(2*1)+(3*2)+(4*3)+(5*0)+...=20
it2=(3*1)+(4*2)+(5*3)+(6*0)+...=26
it3=..
Output=[20 26 ... ... ... ...]
Like that until the end but considering the size of the matrix N variable. M has always the same size.
That's a convolution:
result = conv(M, N(end:-1:1), 'valid');
To achieve the result you want you need to flip the second vector and keep only the "valid" part of the convolution (no border effects).
In your example:
>> M = [2 3 4 5 6 7];
>> N = [1 2 3];
>> result = conv(M, N(end:-1:1), 'valid')
result =
20 26 32 38
Consider an n-by-k matrix M and an p-by-1 vector of indexes V ranging from 1 to n. How can I create the p-by-k matrix C where each row corresponds to the entry of M referred to by the value in each row of V.
Example
M = 1 1
1 2
1 3
1 4
and
V = 2
1
3
What I require is the matrix
C = 1 2
1 1
1 3
To assign the rows V of matrix M to a matrix C, you would write:
C = M(V,:);
I'm really missing some very basic stuff here,
Problem:
I have a 2D matrix say
A = 8 1 6
3 5 7
4 9 2
Now i have some X and Y index as vectors
X = [1 2 3]
Y = [1 2 3]
Now i want (1,1), (2,2), (3,3) of A to be assigned some value say 1
Expected output:
out = 1 1 6
3 1 7
4 9 1
One method would be to use sub2ind to create linear column-major indices to set the locations referenced by these indices to 1. Assuming that X are your rows and Y are your columns (it's hard to tell because the matrix and locations are symmetric):
A(sub2ind(size(A), X, Y)) = 1;
Another method is to create a sparse matrix, convert this to a logical matrix, and use this to index into A to set the corresponding locations that are logical true to 1:
B = logical(sparse(X, Y, 1, size(A,1), size(A,2)));
A(B) = 1;
suppose that we are creating following matrix from given signal
function [ x ]=create_matrix1(b,l)
n = length(b);
m = n-l+1;
x = zeros(m,l);
for i=1:m
x(i,:)=b(i:i+l-1);
end;
end
with some window length,for example
X=[2;1;3;4;5;7]
X =
2
1
3
4
5
7
>> B=create_matrix1(X,3)
B =
2 1 3
1 3 4
3 4 5
4 5 7
if we have given matrix and windows length ,how can i reconstruct original signal?let say i know that windows length is 3,thanks in advance,i think i should sum elements on anti diagonal and divide by number of elements in this anti diagonal ,but how can i do it by code?thanks in advance
Your original vector is located along the top and right edge of your matrix B and can be reconstructed like so:
>> X_reconstructed = [B(1,1:end-1).'; B(:,end)]
X_reconstructed =
2
1
3
4
5
7
In case the matrix B is some noisy matrix and you actually want to do the averages along the diagonals:
>> BB = fliplr(B);
>> X_mean = arrayfun(#(i) mean(diag(BB,i)), size(B,2)-1:-1:-size(B,1)+1).'
X_mean =
2
1
3
4
5
7