What does 1./diag(A) mean? - matlab

so I'm trying to study a code written in MATLAB. And there are these two strange lines of code, which I can't seem to understand, maybe someone could help me out? I'm new to MATLAB, I'm coding in C# most of the time.
As far as I know diag(A) means that it takes the members of main diagonal of matrix A. But what about the other parts of the line? Especially the 1./ operation, what does it do?
In the code below
A is a 4x4 matrix, which stores double type values, b is the coefficients vector and alpha is a freely chosen vector (10, 5, 4, 2).
Atld=diag(1./diag(A))*A-diag(alpha)
btld=diag(1./diag(A))*b

diag(A) returns a vector with the diagonal elements of matrix A
./ is the element-wise division operator, so 1./diag(A) inverts the elements from this vector.
diag(1./diag(A)) returns the diagonal matrix from that vector
So, basically, diag(1./diag(A)) is a matrix with the inverse of the diagonal of A on its diagonal, and zeros everywhere else.

Related

Matlab, cosines of the angles θj between a query vector q and the document vectors aj

I am attempting to find The cosines of the angles θj between a query vector q and the document vectors aj in which j refers to the column number.
Here is the formula, I am attempting to write in matlab.
And here is my attempt at the code thus far:
cosval = (R(:,i)'*(v(Q(:,i))'))./(norm(v)*norm(R(:,i)));
And the issue I am running into:
Subscript indices must either be real positive integers or logicals.
And here are the two matrices I am attempting this with: The matrices are separated by the line, sorry for my poor paint skills. Could the issue I am having be because my matrices do not consist of real integers or is this just the way matlab displays matrices and the issue is with my calculations line?
Where do you define i ? Are the pictured matrices R and Q? We need more information to answer fully.
The most likely problem I can see is it appears you're using values from Q as subscript indices for v, which makes no sense if those values are not integers: you can't have the 5.774th entry in a vector. Going by the formula posted and assuming Q is a matrix it looks more likely that you want to write R(:,i)'*(Q'*v), although I don't know what the capital A subscript means in your formula.
Alternatively, if you haven't assigned a variable i, it could be that matlab is interpreting it as the imaginary unit. Either error would lead to the complaint about indices needing to be 'real positive integers'.

Matlab: How to convert a matrix into a Toeplitz matrix

Considering a discrete dynamical system where x[0]=rand() denotes the initial condition of the system.
I have generated an m by n matrix by the following step -- generate m vectors with m different initial conditions each with dimension N (N indicates the number of samples or elements). This matrix is called R. Using R how do I create a Toeplitz matrix, T? T
Mathematically,
R = [ x_0[0], ....,x_0[n-1];
..., ,.....;
x_m[0],.....,x_m[n-1]]
The toeplitz matrix T =
x[n-1], x[n-2],....,x[0];
x[0], x[n-1],....,x[1];
: : :
x[m-2],x[m-3]....,x[m-1]
I tried working with toeplitz(R) but the dimension changes. The dimension should no change, as seen mathematically.
According to the paper provided (Toeplitz structured chaotic sensing matrix for compressive sensing by Yu et al.) there are two Chaotic Sensing Matrices involved. Let's explore them separately.
The Chaotic Sensing Matrix (Section A)
It is clearly stated that to create such matrix you have to build m independent signals (sequences) with m different initials conditions (in range ]0;1[) and then concatenate such signals per rows (that is, one signal = one row). Each of these signals must have length N. This actually is your matrix R, which is correctly evaluated as it is. Although I'd like to suggest a code improvement: instead of building a column and then transpose the matrix you can directly build such matrix per rows:
R=zeros(m,N);
R(:,1)=rand(m,1); %build the first column with m initial conditions
Please note: by running randn() you select values with Gaussian (Normal) distribution, such values might not be in range ]0;1[ as stated in the paper (right below equation 9). As instead by using rand() you take uniformly distributed values in such range.
After that, you can build every row separately according to the for-loop:
for i=1:m
for j=2:N %skip first column
R(i,j)=4*R(i,j-1)*(1-R(i,j-1));
R(i,j)=R(i,j)-0.5;
end
end
The Toeplitz Chaotic Sensing Matrix (Section B)
It is clearly stated at the beginning of Section B that to build the Toeplitz matrix you should consider a single sequence x with a given, single, initial condition. So let's build such sequence:
x=rand();
for j=2:N %skip first element
x(j)=4*x(j-1)*(1-x(j-1));
x(j)=x(j)-0.5;
end
Now, to build the matrix you can consider:
how do the first row looks like? Well, it looks like the sequence itself, but flipped (i.e. instead of going from 0 to n-1, it goes from n-1 to 0)
how do the first column looks like? It is the last item from x concatenated with the elements in range 0 to m-2
Let's then build the first row (r) and the first column (c):
r=fliplr(x);
c=[x(end) x(1:m-1)];
Please note: in Matlab the indices start from 1, not from 0 (so instead of going from 0 to m-2, we go from 1 to m-1). Also end means the last element from a given array.
Now by looking at the help for the toeplitz() function, it is clearly stated that you can build a non-squared Toeplitz matrix by specifying the first row and the first column. Therefore, finally, you can build such matrix as:
T=toeplitz(c,r);
Such matrix will indeed have dimensions m*N, as reported in the paper.
Even though the Authors call both of them \Phi, they actually are two separate matrices.
They do not take the Toeplitz of the Beta-Like Matrix (Toeplitz matrix is not a function or operator of some kind), neither do they transform the Beta-Like Matrix into a Toeplitz-matrix.
You have the Beta-Like Matrix (i.e. the Chaotic Sensing Matrix) at first, and then the Toeplitz-structured Chaotic Sensing Matrix: such structure is typical for Toeplitz matrices, that is a diagonal-constant structure (all elements along a diagonal have the same value).

Multiplying a 3D Matrix with a 1D

I attempted to use the solution from this post: Multiply a 3D matrix with a 2D matrix, to vectorize the multiplication of a one dimensional with a three dimensional, but to no avail. Any help would be greatly appreciated!
for s = 1: s_length
for a = 1: a_length
for g = g_length
two_dim(s,a) = two_dim(s,a) + one_dim(g) * three_dim(s,a,g);
end
end
end
I think this does what you want.
two_dim = reshape(three_dim, [], size(three_dim,3))*one_dim(:);
two_dim = reshape(two_dim, size(three_dim,1), size(three_dim,2));
This works as follows:
First line reshapes your 3D array into a matrix, collapsing the first two dimensions into one. That way the operation you want is standard multiplication of the resulting matrix times a column vector.
Second line reshapes the result into matrix shape.
mtimes does not work with inputs with dimension larger than 2, so you have to find a way to do the multiplication by yourself. The solution of Luis Mendo is a nice solution; here is another one using bsxfun:
two_dim = two_dim + squeeze(sum(bsxfun(#times, three_dim, reshape(one_dim,[1 1 g_length])),3));
Here is how it works:
reshape makes the vector one_dim looking like a 3D array. This must be done because the multiplication between the vector and the 3D array is performed along the 3rd dimension, so Matlab need a hint on sizes.
bsxfun perfoms the element-wise multiplcation, so the result must be sumed up along the 3rd dimension (and squeezed to be compliant with a 2D matrix format)

Matlab returning only NANs from a vector that has NaNs and non-NaNs

I have simulation data in a vector of size 50,000 x 1, which has NaNs and non-NaNs. I would like to average the non-NaNs, but the function nanmean returns NAN. I have tried removing the NANs, but I only get a vector of zeros. Visual inspection of the vector leads me to doubt that the true mean of this vector is really NaN.
Also, I would like to use this vector to compute covariance with several other vectors (at some point). My alternative is doing this in Excel, which would be painful.
Any thoughts?
Thank you
Let's say your data in stored in a vector A, you can take the mean of the vector excluding the NaNs as well as any Inf and -Inf values via:
meanA = mean( A(isfinite(A)) );
Assuming you have a vector that only contains finite numeric values, and a NaN here and there, the solution is very simple
nanmean(A)
This should only bring trouble if there are non finite values in your vector.
In this case you could filter them out as suggested by #Ryan, but then you need to realize that you are not actually calculating the mean of the vector.
Ask yourself whether you may instead be interested in something like
nanmedian(A)
About the calculation of covariances and the likes, assuming you have vectors v and w, then I would recommend you to do something like this:
idx = isfinite(v) & isfinite(w);
cov(v(idx),w(idx))

Reshape function (apparently) is useless?

reshape function should change the shape of a matrix.
But if I try using it (it's also written in the manual) I discover that if I declare:
reshape(A,m,n);
Then A must have m lines and n columns.
If I try using reshape passing as arguments numbers different from these, I get an error.
So appearently, it does not reshape any matrix, it just does return the same matrix if I pass m and n as arguments, and return an error otherwise.
So if I have a 4x4 matrix and I want to make it smaller: 2x2, I can't.
It changes the shape, not the size of the array. To change the shape the number of elements must not change. So if you have 4x4 you can go to 8x2 or 2x8 or 16x1 etc. but not 2x2 (what do you expect to happen to the other elements?)
Reshape rearranges elements; if you do B = reshape(A, u) then logically B must have the same number of elements (note that size(B) == prod(u)) as A (length(B(:)) == length(A(:))). Otherwise, how would it know which elements to drop if A had more, or where would it get new ones if B had more?
One situation in which reshape is useful is when for some reason your square matrix was unrolled into a vector (perhaps by another function) and you simply need to arrange it back to its previous form.
When you want to get a smaller part of a matrix, use A(i1:i2, j1:j2). When you want to "tile" a matrix, use repmat(A, i, j).
As #thrope says, reshape changes the shape, not the number of elements. If you have a 4x4 matrix and you want the upper left 2x2 corner of it, use B=A(1:2,1:2) or the bottom right 2x2 corner, B=A(3:4,3:4).