How to add a constraint to my optimization? - matlab

I am working on formulating an optimization problem where I have a 2-D matrix A.
A= [0 f1 0 f2]
[f3 f3 0 0]
.........
And I have another 2-D matrix B that I should fill. B has the same size of A. I need b_ij (element of B) to be zero if a_ij=0 (element of A) and I need b_ij to be greater than zero and less than or equal to a_ij if a_ij is not zero.
How can I represent this in my formulation? I have added this constraint/condition:
b_ij<=a_ij
But this does not satisfy the condition that states that b_ij is not equal zero when a_ij is not equal zero. Any help?

If all elements are positive, keep the smallest element of each matrix by doing an element by element comparison :
B2 = min(A,B)
Alternatively, create a logical matrix indicating if a condition is answered and multiply element by element with the matrix B , only elements who satisfy the condition remain, others are set to zero:
B = B.*(A~=0)
Then keep elements of B that are smaller or equal to elements of A, and replace them by the value of A otherwise.
B = B.*(B<=A) + A.*(B>A) )
This option lets you generalize your constraint.
You indicate needing elements of b_ij to be greater than zero if elements of a_ij are greater than zero. An option is to use the function max to ensure that all elements of B are positive.
B = max(1e-2,B); % exact value is yours to set.
This step is up to you and depend on your problem.

You want to implement the implication
a = 0 => b = 0
a <> 0 => 0 < b <= a
If a is (constant) data this is trivial. If a is a variable then things are not so easy.
You implemented part of the implications as
b <= a
This implies a is non-negative: a>=0. It also implies b is non-negative. The remaining implication a>0 => b>0 can now be implemented as
a <= δ * 1000
b >= δ / 1000
δ in {0,1}
Many MIP solvers support indicator constraints. That would allow you to say:
δ = 0 -> a = 0
δ = 1 -> b >= 0.001
δ in {0,1}

Related

Explanation for a function within xcorr in MATLAB

Looking within the xcorr function, most of it is pretty straightforward, except for one function within xcorr called "findTransformLength".
function m = findTransformLength(m)
m = 2*m;
while true
r = m;
for p = [2 3 5 7]
while (r > 1) && (mod(r, p) == 0)
r = r / p;
end
end
if r == 1
break;
end
m = m + 1;
end
With no comments, i fail to understand what this function is meant to acheive and what is the significance of p = [2 3 5 7]. Why those numbers specifically? Why not take a fixed FFT size instead? Is there a disadvantage(cause errors) to taking a fixed FFT size?
This part is used to get the integer closest to 2*m that can be written in the form:
Either:
m is already of this form, then the loop
for p = [2 3 5 7]
while (r > 1) && (mod(r, p) == 0)
r = r / p;
end
end
Will decrease r down to 1 and the break will be reached.
Or m has at least one other prime factor, and r will not reach 1. You go back to the look with m+1 and so on until you reach a number of the right form.
As per why they do this, you can see on the fft doc, in the Input arguments section:
n — Transform length [] (default) | nonnegative integer scalar
Transform length, specified as [] or a nonnegative integer scalar.
Specifying a positive integer scalar for the transform length can
increase the performance of fft. The length is typically specified as
a power of 2 or a value that can be factored into a product of small
prime numbers. If n is less than the length of the signal, then fft
ignores the remaining signal values past the nth entry and returns the
truncated result. If n is 0, then fft returns an empty matrix.
Example: n = 2^nextpow2(size(X,1))

how to compare all vector indexes with a constant value and switch the value of another variable (0 1) based on that

I have a 1x24 vector (a). I should define a command in Matlab which compare all 24 values of a vector (a) with a certain value (mean (b)) and if the vector (a) item is greater than certain value (mean (b)), ''I'' sets 1 and if the vector item is less than certain value ''I'' sets 0. I wrote the below code:
for i=1:length(a)
if a(i) >= mean(b)
I = 1;
else
I = 0;
end
end
But it implements the comparison only for the last index of vector a and sets I=0. How can I fix the command that do the comparison for all indexes of vector a?
In MATLAB, you can use the following syntax to do so:
I = a >= mean(b);
If you want to use your code for doing so, you'll need to initialize I as a vector, and modify its indices as follows:
I = zeros(length(a),1)
for ii=1:length(a)
if a(ii) >= mean(b)
I(ii) = 1;
else
I(ii) = 0;
end
end
You should read about logical indexing in matlab. You don't need for loops for what you are doing. For example, if you have,
rng(5);
a = rand(1,10);
b = 0.5;
then, I = a > b; will return a logical array with zeros and ones, where one indicates the position in the array where the given condition is satisfied,
I =
0 1 0 1 0 1 1 1 0 0
Using these indices, you can modify your original array. For example, if you wish to change all values of a greater than b to be 10, you would simply do,
a(a > b) = 10;
Specifically, if you need indices where the condition is satisfied, you can use, find(a > b), which in this example will give you,
ans =
2 4 6 7 8

Matlab - indexing

I have a matrix A which is 21x1 and contains only ones and twos.
Then I have a matrix B which is 6 * 600 matrix of numbers ranging between 0 and 21.
I want to generate a matrix C which is 6 * 600 matrix containing ones and twos such that:
If B matrix has a zero, matrix C should have a zero on that place. If B matrix has number 5, then matrix C should have the element on row 5 of matrix A and so on and so forth.
Please let me know if this is not clear.
Let us generate some sample inputs:
A = randi(2,21,1);
B = randi(22,6,600)-1;
The output C will then be:
C = B*0; %// preallocation + take care of the elements that need to be 0
C(B>0) = A(B(B>0)); %// logical indexing
The explanation of the 2nd line is as follows:
RHS
B>0 - return a logical array the size of B which has the meaning of whether this specific element of B is larger-than-0 value.
B(B>0) - return the elements of B for which there are true values in B>0 (i.e. numbers that can be used to index into A).
A(...) - return the elements of A that correspond to the valid indices from B.
% Generate matrices fitting the description
A = round(rand(21,1))+1;
B = round(rand(6,600)*21);
C = zeros(6,600);
% Indexing impossible since zeroes cannot be used as index. So treat per element using linear indexing.
for ii = 1:(6*600)
if B(ii) == 0
C(ii) = 0;
else
C(ii) = A(B(ii));
end
end
Although the piece of code could be optimized further this is the most clear way of creating understanding and speed is not needed if it's only this small matrix evaluated a limited number of times.

What is the Haskell / hmatrix equivalent of the MATLAB pos function?

I'm translating some MATLAB code to Haskell using the hmatrix library. It's going well, but
I'm stumbling on the pos function, because I don't know what it does or what it's Haskell equivalent will be.
The MATLAB code looks like this:
[U,S,V] = svd(Y,0);
diagS = diag(S);
...
A = U * diag(pos(diagS-tau)) * V';
E = sign(Y) .* pos( abs(Y) - lambda*tau );
M = D - A - E;
My Haskell translation so far:
(u,s,v) = svd y
diagS = diag s
a = u `multiply` (diagS - tau) `multiply` v
This actually type checks ok, but of course, I'm missing the "pos" call, and it throws the error:
inconsistent dimensions in matrix product (3,3) x (4,4)
So I'm guessing pos does something with matrix size? Googling "matlab pos function" didn't turn up anything useful, so any pointers are very much appreciated! (Obviously I don't know much MATLAB)
Incidentally this is for the TILT algorithm to recover low rank textures from a noisy, warped image. I'm very excited about it, even if the math is way beyond me!
Looks like the pos function is defined in a different MATLAB file:
function P = pos(A)
P = A .* double( A > 0 );
I can't quite decipher what this is doing. Assuming that boolean values cast to doubles where "True" == 1.0 and "False" == 0.0
In that case it turns negative values to zero and leaves positive numbers unchanged?
It looks as though pos finds the positive part of a matrix. You could implement this directly with mapMatrix
pos :: (Storable a, Num a) => Matrix a -> Matrix a
pos = mapMatrix go where
go x | x > 0 = x
| otherwise = 0
Though Matlab makes no distinction between Matrix and Vector unlike Haskell.
But it's worth analyzing that Matlab fragment more. Per http://www.mathworks.com/help/matlab/ref/svd.html the first line computes the "economy-sized" Singular Value Decomposition of Y, i.e. three matrices such that
U * S * V = Y
where, assuming Y is m x n then U is m x n, S is n x n and diagonal, and V is n x n. Further, both U and V should be orthonormal. In linear algebraic terms this separates the linear transformation Y into two "rotation" components and the central eigenvalue scaling component.
Since S is diagonal, we extract that diagonal as a vector using diag(S) and then subtract a term tau which must also be a vector. This might produce a diagonal containing negative values which cannot be properly interpreted as eigenvalues, so pos is there to trim out the negative eigenvalues, setting them to 0. We then use diag to convert the resulting vector back into a diagonal matrix and multiply the pieces back together to get A, a modified form of Y.
Note that we can skip some steps in Haskell as svd (and its "economy-sized" partner thinSVD) return vectors of eigenvalues instead of mostly 0'd diagonal matrices.
(u, s, v) = thinSVD y
-- note the trans here, that was the ' in Matlab
a = u `multiply` diag (fmap (max 0) s) `multiply` trans v
Above fmap maps max 0 over the Vector of eigenvalues s and then diag (from Numeric.Container) reinflates the Vector into a Matrix prior to the multiplys. With a little thought it's easy to see that max 0 is just pos applied to a single element.
(A>0) returns the positions of elements of A which are larger than zero,
so forexample, if you have
A = [ -1 2 -3 4
5 6 -7 -8 ]
then B = (A > 0) returns
B = [ 0 1 0 1
1 1 0 0]
Note that we have ones corresponding to an elemnt of A which is larger than zero, and 0 otherwise.
Now if you multiply this elementwise with A using the .* notation, then you are multipling each element of A that is larger than zero with 1, and with zero otherwise. That is, A .* B means
[ -1*0 2*1 -3*0 4*1
5*1 6*1 -7*0 -8*0 ]
giving finally,
[ 0 2 0 4
5 6 0 0 ]
So you need to write your own function that will return positive values intact, and negative values set to zero.
And also, u and v does not match in dimension, for a generall SVD decomposition, so you actually would need to REDIAGONALIZE pos(diagS - Tau), so that u* diagnonalized_(diagS -tau) agrres to v

Solving for variables in an over-parameterised system

I am trying to write a Matlab program that accepts variables for a system from the user, but there are more variables than system parameters. To be specific, six variables in three equations:
w - d - M = 0
l - d - T = 0
N - T + M = 0
This could be represented in matrix form as A*x=0 where
A = [1 0 0 -1 0 -1;
0 1 0 -1 -1 0;
0 0 1 0 -1 1];
x = [w l N d T M]';
I would like to be able to solve this system given a known subset of the variables. For example, if the user gives d, T, M, then the system is trivially solved for the other three variables. If the user supplies w, N, M, then it becomes a solvable 3-DOF system. And so on. (If the user over- or under-specifies the system then an error may of course result.)
Given any one of these combinations it's simple to (a priori) use matrix algebra to calculate the unknown quantities. But I don't know how to solve the general case, aside from using the symbolic toolbox (which I prefer not to do for compatibility reasons).
When I started with this approach I thought this step would be easy, but my linear algebra is rusty; am I missing something simple?
First, let x be a vector with NaN for the unknown values. This allows you to use ISNAN to find the indeces of the unknowns. If you calculate A*x for only the user-specified terms, that gives you a column of constants b. Take those constants to the right-hand side of the equation, and you have an equation of the form A*x = -b.
A = [1 0 0 -1 0 -1;
0 1 0 -1 -1 0;
0 0 1 0 -1 1];
idx = ~isnan(x);
b = A(:,idx)*x(idx); % user provided constants
z = A(:,~idx)\(-b); % solution of Ax = -b
x(~idx) = z;
With input x = [NaN NaN NaN 1 1 1]', for instance, you get the result [2 2 0 1 1 1]'. This uses MLDIVIDE, I'm not well versed enough in linear algebra to know whether PINV or something else would be better.
Given the linear system
A = [1 0 0 -1 0 -1;
0 1 0 -1 -1 0;
0 0 1 0 -1 1];
A*x = 0
Where the elements of x are identified as:
x = [w l N d T M]';
Now, suppose that {d,T,M} have known, fixed values. What we need are the indices of these elements in x. We've chosen the 4th, 5th and 6th elements of x to be knowns.
known_idx = [4 5 6];
unknown_idx = setdiff(1:6,known_idx);
Now, let me pick some arbitrary numbers for those known variables.
xknown = [1; -3; 7.5];
We will partition A into two submatrices, corresponding to the known and unknown variables.
Aknown = A(:,known_idx);
Aunknown = A(:,unknown_idx);
Now, move the known values to the right hand side of the equality, and solve. See that Aknown is a 3x3 matrix, so the problem is (hopefully) well posed.
xunknown = Aunknown\(-Aknown*xknown)
xunknown =
-8.5
2
10.5
Combine it all into the final solution.
x = zeros(6,1);
x(known_idx) = xknown;
x(unknown_idx) = xunknown;
x =
-8.5
2
10.5
1
-3
7.5
Note that I've expanded this all out into a few lines to show what is happening more clearly. But I could have done it all in just a line or two of code had I wanted to be parsimonious.
Finally, see that had I chosen some other sets of numbers to be the knowns, such as {l,d,T}, then the resulting system would be singular. So you must watch for that event. A test on the rank of Aunknown might be useful to weed out the problems. Or you might choose to employ pinv to build the solution.
The system of equations is fixed? What if you store the variables present in your three equations in a list per equation:
(w, d, M)
(l, d, T)
(N, T, M)
Then you get the user input and you can calculate the number of variables given in each equation:
User input: w, N, M
Given variables:
(w, d, M) -> 2
(l, d, T) -> 0
(N, T, M) -> 1
This would trivially give you d from the first equation. Therefore you end up with two equations containing two variables and you know you the equation system you have to solve.
It's basically your own simple symbolic solver for a single system of equations.