Could anybody tell me how to generate a random sign (-1/1) definite positive matrix in Matlab ?
Update: Thanks to all who replied, that was very helpful
I am experimenting compressed sensing using l1 Magic with different sensing matrices, Gaussian worked well but with Bernoulli, l1 Magic gives me an "matrix must be definite positive" error that's why I was asking my question
A really good answer would require more knowledge about the exact requirements and context. From what I've read:
What you're asking for may be doable for non-symmetric matrices
As horchler pointed out,
A = [1, 0, 0
0, 1, 0
-1, 1, 1];
has all positive eigenvalues, hence is positive definite.
How to find these efficiently for large sized matrices seems to me a non-trivial problem, but I don't really know.
What you're asking for does not appear possible for symmetric matrices
Restricting entries to the set {-1,1}, there are NO 2x2 or 3x3 or 4x4 or 5x5 or 6x6 positive definite matrices.
Restricting entries to the set {-1, 0, 1}, the ONLY positive definite matrices that I've found, by enumerating all possibilities, are the identity matrix! I'd conjecture it's impossible for any size matrix, but I don't know for sure.
Brute force enumeration of 2x2 symmetric matrices:
[-1, -1 eigenvalues -2, 0
-1, -1]
[-1, -1 eigenvalues -1.4, 1.4
-1, 1]
[-1, 1 eigenvalues -2, 0
1, -1]
[-1, 1 eigenvalues -1.4, 1.4
1, 1]
[1, 1 eigenvalues 0, 2
1, 1]
[1, 1 eigenvalues -1.4, 1.4
1, -1]
[1, -1 eigenvalues 0, 2
-1, 1]
[1, -1 eigenvalues -1.4, 1.4
-1, -1]
Related
I am trying to plot the 3 roots of my function as they vary with my K vector. I know the the index of my r matrix must be an integer but even when I use the small k vector it still gives the same error. How should I fix this issue?
%problem 3d
clear,clc
K=0:.01:2;
%K=10
k=0:1:2000;
r(K,:)=roots([1,1.76,5.31,(4.55+4.6.*K)])
%r1=roots([1,.76+(4.6*K),(4.55+(9.2*K))])
figure(1)
plot(real(r(1,:)),imag(r(1,:)),'*')
Several comments:
Indices in MATLAB must be positive integers (eg. 1, 2, 3, ...).
Your K vector has non-integer numbers beginning at zero: 0, .01, .02, .03, ... hence they cannot be array indices.
Why not do: r = roots([1,1.76,5.31,(4.55+4.6.*K)])?
If this is confusing, I would also go through some Matlab array indexing tutorials.
Suppose I have the matrix below:
syms x y z
M = [x+y-z;2*x+3*y+-5*z;-x-y6*z];
I want to have the a matrix consisting the coefficients of the variables x,y, and z:
CM = [1,1,-1;2,3,-5;-1,-1,6];
If I multiply CM by [x;y;z], I expect to get M.
Edit
I have a system of ODE:
(d/dt)A = B
A and B are square matrices. I want to solve these set of equations. I don't want to use ode solving commands of Matlab.
If I turn the above set of equations into:
(d/dt)a = M*a
then I can solve it easily by the eigen vectors and values of matrix M. Here a is a column vector containing the variables, and M is the matrix of coefficient extracted from B.
Since you seem to be using the Symbolic Math Toolbox, you should diff symbolically, saving the derivative with respect to each variable:
syms x y z;
M=[x+y-z;2*x+3*y-5*z;-x-y+6*z];
Mdiff=[];
for k=symvar(M)
Mdiff=[Mdiff diff(M,k)];
end
Then you get
Mdiff =
[ 1, 1, -1]
[ 2, 3, -5]
[ -1, -1, 6]
If you want to order the columns in a non-lexicographical way, then you need to use a vector of your own instead of symvar.
Update
Since you mentioned that this approach is slow, it might be faster to use coeffs to treat M as a polynomial of its variables:
syms x y z;
M=[x+y-z;2*x+3*y-5*z;-x-y+6*z];
Mdiff2=[];
varnames=symvar(M);
for k=1:length(M)
Mdiff2=[Mdiff2; coeffs(M(k),varnames(end:-1:1))];
end
Note that for some reason (which I don't understand) the output of coeffs is reversed compare to its input variable list, this is why we call it with an explicitly reversed version of symvar(M).
Output:
>> Mdiff2
Mdiff2 =
[ 1, 1, -1]
[ 2, 3, -5]
[ -1, -1, 6]
As #horchler pointed out, this second solution will not work if your symbolic vector has varying number of variables in its components. Since speed only matters if you have to do this operation a lot of times, with many configurations of the parameters in your M, I would suggest constructing M parametrically (so that the coefficients are also syms) is possible, then you only have to perform the first version once. The rest is only substitution into the result.
The filter f’ = [0 -1/2 0 1/2 0] gives an estimate of the first derivative of the image in the x direction. What is the corresponding second derivative filter f"?
Can someone give me a clue and guide me as to how I would go about this problem?
If you are talking about a 1-D signal, use [.5, -1, .5]. In the case of an image what you are looking for is probably the "Laplacean" filter, but the actual second derivative is more complicated than that. It's not a single filter, and it's definitely not just a 1-D array.
The "second derivative" could be that filter applied to the x or the y direction. Their sum is the Laplacian. But there is also dxy/dxdy, which is the convolution by something like:
[[-1, 0, 1],
[ 0, 0, 0],
[ 1, 0,-1]]
You should also use something like
[[-1, 0, 1],
[-2, 0, 2],
[-1, 0, 1]]]
when calculating the directional derivatives.
If you really want to understand how all of that works, look for the excellent book "Digital Filters" by Richard Hamming! Too many people use these oversimple filters. Try to learn about windowing and Lanczos smoothing. Also there is little reason for anyone not to be using stuff like Shigeru Ando's consistent gradient operators.
OK, so I suspect that this might be rather easy, but cannot find any good help online except for bits and pieces.
I have a NxN-matrix that I want to do sort of an edge detect for. I want to substract a factor of all neighbouring values, if they exist.
So if my matrix consists of [5, 5, 5 ; 5, 10, 5 ; 5, 5, 5] I want it to return [4, 3, 4 ; 3, 8, 3 ; 4, 3, 4] (incredibly rough estimate just to give an example).
I can see how it would be done with for-loops, but I'm thinking it may be doable in an easier and less taxing way. So far, nlfilter seems to be a possible way out, but I cannot seem to figure it out completely on my own.
The mathematical operation you're describing is called convolution.
Convolution basically amounts to replacing every pixel in an image with a weighted sum of itself and its neighbours. The weights are given in a (usually small) matrix called a kernel, or sometimes impulse response.
For edge detection I recommend either the Sobel or discrete Laplacian kernels.
The MATLAB function conv2 can do the image convolution for you.
kernel = [ 0 1 0
1 -4 1
0 1 0 ];
edges = conv2(image,kernel,'same');
You're probably looking for something like filter2(h,X)
Given your example, h would be something like
h = [ 0 -0.1 0;
-0.1 1 -0.1;
0 -0.1 0];
This takes the value at the center and subtracts 1/10 of each of its 4 neighbors. If you use filter2(h,X,'same'), where X is your original matrix, it will pad with zeros, which appears to be what you want to get the edge values right.
I would like to compute the weighted maxima of a vector in Matlab. For weighted maxima I intend the following:
Given a vector of 2*N+1 weights W={w[-N], w[-N+1] .. w[0] .. w[N]} and given an input sequence A, weighted maxima is a vector M where m[i]=max(w[-N]*a[i-N], w[-N+1]*a[i-N+1], ... w[N]*a[i+N])
So for example given a vector A= [1, 4, 12, 2, 4] and weights W=[0.5, 1, 0.5], the weighted maxima would be M=[2, 6, 12, 6, 4].
This can be done using ordfilt2, but ordfilt2 uses weights as additive rather then multiplicative.
I am actually working on 4D matrixes, but any 1D solution would work as the 4D weight matrix is separable.
My current solution is to generate shifted copies of the input array A, weight them according to the shift and maximize all the arrays. Shift is performed using circshift and is the bottleneck in the process. generating shifted matrixes "manually" trough indexing turned out to be even slower.
Can you suggest any more efficient solution?
EDIT: For a positive A, M=exp(ordfilt2(log(A), length(W), ones(size(W)), log(W))) does the job, but still takes longer than the circshift solution above. I am still looking for more efficient solutions.
>> B = padarray(A, [0 floor(numel(W)/2)], 0); % Pad A with zeros
>> B = bsxfun(#times, B(bsxfun(#plus, 1:numel(B)-numel(W)+1, (0:numel(W)-1)')), W(:)); % Apply the weights
>> M = max(B) % Compute the local maxima
M =
2 6 12 6 4