I would need to express this condition:
a - b(a,x) < 0, for any a such that 0 < a < Inf
% b(a,x) is a function depending on a and x, the vector to be optimized
% a is an additional variable, of length 1
I have come across fseminf function, which seems to be exactly what I was looking to. However, it only takes into account close intervals for 'a'. I would need this constraint to be met for any positive real value of a with a precision of thousandths.
In another post in Stackoverflow and in Matlab documentation it is mentioned that it is impossible to cover the whole range of positive real numbers, and a guess about which values of a are expected must be done. I wonder if there is another way of doing this, because in my case the possible values of a do actually depend of another variable s, and depending on the value of s these values of a could vary up to infinity.
Many thanks in advance, and best regards.
Actually the substraction I need to implement is the one above in this image:
That is, the term of the left in that equality minus the one on the right must be lower than 0 for any value of m_u greater than 0. When the number of iterations (l) tends to infinity, so must do the value of m_u --which starts being 0 when (l)=0. That is equivalent to say, for any value of m_u, the one provided in next iteration should be greater than it.
The parameters to be optimized in this expresion are lambda and rho, not m_u.
What could I do?
Many thanks in advance and BR.
First, define a function for nonlinear condition:
function [c,ceq] = nonLinear(x)
c = x - b(x);
ceq = [];
Then, apply fmincon likes the following on target function f(x):
fun = #(x)f(x);
nonlcon = #nonLinear;
A = [-1]; % x > 0
b = [0];
Aeq = [];
beq = [];
lb = [];
ub = [];
x0 = [0]; %initial point
[x,fval,exitflag,output] = fmincon(fun,x0,A,b,Aeq,beq,lb,ub,nonlcon);
Related
I am trying to optimize a nonlinear function with 1500 variables(instantaneous phase), with the help of fmincon in Matlab. The constraint to the optimum variable is that the difference between consecutive elements in the optimal variable obtained should be greater than 0. How can I implement this in the cost function? I have used a nonlinear constraint:
function [c,ceq] = insta_freq(phase)
f=diff(phase);
c=-1*double(min(f));
ceq = [];
The optimization is performed by:
nonlcon=#insta_freq;
[variable_opt,fval,exitflag,output] = fmincon(fun,ph0,[],[],[],[],[],[],nonlcon,options);
The optimization should be such that the constraint nonlcon<=0 but while optimizing with fmincon, these constraints are not satisfied. Thus, is there any other way to make sure that difference of the optimal variable vector is always greater than 0?
You could try and reduce the constraint tolerance. Also in the question it seems you are referring to the derivatives of the objective function, whereas in the question itself it seems you want every single term to be greater than the preceding one as in x1 <= x2 <= x3 <= ... <= xn. I am suggesting a possible solution for the latter problem (the first one would not even define a local optimum, so I am assuming the reported condition is what you want).
You could rewrite the condition in a matrix for as in
A = [ 1 -1 0 ... 0 ; 0 1 -1 0 ... 0 ; .... 1 -1 ] so your constraints are inequality linear constraints, simply written Aineq x <= b where b = [0;...; 0];
you just then call
[variable_opt,fval,exitflag,output] = fmincon(fun,ph0,A,b,[],[],[],[],nonlcon,options);
where A and b are the ones defined above.
I'm trying to use MatLab code as a way to learn math as a programmer.
So reading I'm this post about subspaces and trying to build some simple matlab functions that do it for me.
Here is how far I got:
function performSubspaceTest(subset, numArgs)
% Just a quick and dirty function to perform subspace test on a vector(subset)
%
% INPUT
% subset is the anonymous function that defines the vector
% numArgs is the the number of argument that subset takes
% Author: Lasse Nørfeldt (Norfeldt)
% Date: 2012-05-30
% License: http://creativecommons.org/licenses/by-sa/3.0/
if numArgs == 1
subspaceTest = #(subset) single(rref(subset(rand)+subset(rand))) ...
== single(rref(rand*subset(rand)));
elseif numArgs == 2
subspaceTest = #(subset) single(rref(subset(rand,rand)+subset(rand,rand))) ...
== single(rref(rand*subset(rand,rand)));
end
% rand just gives a random number. Converting to single avoids round off
% errors.
% Know that the code can crash if numArgs isn't given or bigger than 2.
outcome = subspaceTest(subset);
if outcome == true
display(['subset IS a subspace of R^' num2str(size(outcome,2))])
else
display(['subset is NOT a subspace of R^' num2str(size(outcome,2))])
end
And these are the subset that I'm testing
%% Checking for subspaces
V = #(x) [x, 3*x]
performSubspaceTest(V, 1)
A = #(x) [x, 3*x+1]
performSubspaceTest(A, 1)
B = #(x) [x, x^2, x^3]
performSubspaceTest(B, 1)
C = #(x1, x3) [x1, 0, x3, -5*x1]
performSubspaceTest(C, 2)
running the code gives me this
V =
#(x)[x,3*x]
subset IS a subspace of R^2
A =
#(x)[x,3*x+1]
subset is NOT a subspace of R^2
B =
#(x)[x,x^2,x^3]
subset is NOT a subspace of R^3
C =
#(x1,x3)[x1,0,x3,-5*x1]
subset is NOT a subspace of R^4
The C is not working (only works if it only accepts one arg).
I know that my solution for numArgs is not optimal - but it was what I could come up with at the current moment..
Are there any way to optimize this code so C will work properly and perhaps avoid the elseif statments for more than 2 args..?
PS: I couldn't seem to find a build-in matlab function that does the hole thing for me..
Here's one approach. It tests if a given function represents a linear subspace or not. Technically it is only a probabilistic test, but the chance of it failing is vanishingly small.
First, we define a nice abstraction. This higher order function takes a function as its first argument, and applies the function to every row of the matrix x. This allows us to test many arguments to func at the same time.
function y = apply(func,x)
for k = 1:size(x,1)
y(k,:) = func(x(k,:));
end
Now we write the core function. Here func is a function of one argument (presumed to be a vector in R^m) which returns a vector in R^n. We apply func to 100 randomly selected vectors in R^m to get an output matrix. If func represents a linear subspace, then the rank of the output will be less than or equal to m.
function result = isSubspace(func,m)
inputs = rand(100,m);
outputs = apply(func,inputs);
result = rank(outputs) <= m;
Here it is in action. Note that the functions take only a single argument - where you wrote c(x1,x2)=[x1,0,x2] I write c(x) = [x(1),0,x(2)], which is slightly more verbose, but has the advantage that we don't have to mess around with if statements to decide how many arguments our function has - and this works for functions that take input in R^m for any m, not just 1 or 2.
>> v = #(x) [x,3*x]
>> isSubspace(v,1)
ans =
1
>> a = #(x) [x(1),3*x(1)+1]
>> isSubspace(a,1)
ans =
0
>> c = #(x) [x(1),0,x(2),-5*x(1)]
>> isSubspace(c,2)
ans =
1
The solution of not being optimal barely scratches the surface of the problem.
I think you're doing too much at once: rref should not be used and is complicating everything. especially for numArgs greater then 1.
Think it through: [1 0 3 -5] and [3 0 3 -5] are both members of C, but their sum [4 0 6 -10] (which belongs in C) is not linear product of the multiplication of one of the previous vectors (e.g. [2 0 6 -10] ). So all the rref in the world can't fix your problem.
So what can you do instead?
you need to check if
(randn*subset(randn,randn)+randn*subset(randn,randn)))
is a member of C, which, unless I'm mistaken is a difficult problem: Conceptually you need to iterate through every element of the vector and make sure it matches the predetermined condition. Alternatively, you can try to find a set such that C(x1,x2) gives you the right answer. In this case, you can use fminsearch to solve this problem numerically and verify the returned value is within a defined tolerance:
[s,error] = fminsearch(#(x) norm(C(x(1),x(2)) - [2 0 6 -10]),[1 1])
s =
1.999996976386119 6.000035034493023
error =
3.827680714104862e-05
Edit: you need to make sure you can use negative numbers in your multiplication, so don't use rand, but use something else. I changed it to randn.
I am trying to solve an optimization problem on MATLAB or CPLEX. We have two sets A (n elements), and B (m elements). We have to assign exactly one element in A to one element in B.
A single element in B can be assigned as many elements in A as needed (maximum n). There is a cost of assigning an element i in A to an j element in B = cij.
Moreover, there is another cost associated with the NUMBER of elements in A assigned to a element in B (load). That cost is: lj = ( sum (number of elements assigned to j) ^2 )
The overall cost is therefore: sum (cij+lj)
We would like to find the optimal assignment such that: sum (cij+lj) is minimized.
The problem can be formulated as a binary integer programming IF there was no load. My concern is how can I write such a function in either MATLAB or CPLEX.
You wish to minimize the cost of this assignment from one vector to another, subject to the number of variables to be assigned, from 1 to n inclusive? If so:
[x,fval] = fminsearch(#(x) sum(arrayfun( #(y) y*cij+y^2,1:n)),1)
or
function out = minFunc(x,n)
out = 0
for ii=1:n
out = out + cij*ii + n^2;
end
end
Where cij=1 for demonstration purposes and Ij = N^2, N = number of elements assigned to j. This seems to simplistic for your needs since it will always return x = 1. However, the variable to be minimized x, is not used, so I'm not sure what you are trying to minimize. Please let me know if I may help further.
how to pick values from matrix closest to or equal to K = 0.5? I know I could obtain values from the matrix, by taking the absolute values and its min. However, I want to be able to loop through the matrix, check if the the first element is equal K, if it is equal,take its index and break. But if the first element is not equal to K, loop until you find value equal to K. Continue until all values equal to K is exhausted. Can anybody point me in the right direction? Thanks in advance.
Here is my code:
data = rand(10,2);k =0.5;
indr = find(data(:,1));
cNum = data(1,1);
if cNum < k
old_distance = abs(k - cNum);
else
old_distance = abs(cNum - k);
end
Xdata = data(2:end,:);
indeX = find(Xdata(:,1));
for i = 1:size(Xdata,1)
if Xdata(i,1) < k
min_Val = abs(k-Xdata(i,1));
new_distance = min(min_Val);
else
min_Val = abs(Xdata(i,1) -k);
new_distance = min(min_Val);
end
if (new_distance < old_distance)
old_distance = new_distance;
cNum = Xdata(i,1);
end
end
cNum_indeX = indr(indeXm);
Y = cNum;
X = indr(cNum_indeX);'
To find the closest value in a vector to a particular value you can do this:
>> data = rand(10, 1)
data =
0.7060
0.0318
0.2769
0.0462
0.0971
0.8235
0.6948
0.3171
0.9502
0.0344
>> k = 0.5;
>> [~, index] = min(abs(data - k));
>> closestValue = data(index)
closestValue =
0.3171
For loops are rarely the answer in MATLAB. Let's say you want to check if your array elements are within K ± tol, where tol is some tolerance that you've set. You can do that by simple logical indexing.
K=0.5;
tol=0.001; %# set your tolerance here
boolIndex=xVector<=K+tol & xVector>=K-tol; %# xVector is your vector
Now boolIndex is just a logical index array of 0's and 1's. It gives a 1 wherever your array element has satisfied this criteria. You can use this directly in indexing your vector for further manipulation. If, for some reason, you need the exact index, you can get them by doing find(boolIndex==1).
The constraints of the problem aren't clear enough (and I don't have enough points to make this a comment rather than an answer.)
Is speed critical here? If so, then you should avoid any sort of explicit loop. It's usually better to use builtin functions unless the matrix is really huge and you want to break when you find something close enough. If it's millions of entries long, I'd break it into chunks of 10000 or so and let MATLAB use the min function on chunks. Or rows. Or columns. Depends on what you want to do.
How close is close enough? You demonstrate with a random matrix, but are you expecting something within rounding error of 0.5?
Are you aware that [value,index]=min(x) will give the value and index of minimum?
I assume the matrix must be large, otherwise there would be no downside to letting MATLAB do the vectorized:
[colminval,colminind]=min(abs(x-0.5));
[minval,rowminind]=min(colminval);
That's the best I can do for direction without more... direction.
I have two matrices x and y, both are results from different algorithms/routines that are supposed to calculate the same result. While I know that the isequal() would check if x and y are the same matrix, the entries in those matrices would not be exactly the same (i.e. some entries may be with 5% off in worst case scenario). In this scenario, what would be the best method of comparing them to see if they are close enough to be considered the same result? Thanks in advance for the advices.
Try this:
tf = abs((A-B)./B)<0.05
This will return a logical matrix which will be true for each element if the relative difference between A and B with respect to B is less than 5 percent.
If you want to ask if all of these are true (they all satisfy the above condition):
all(tf(:))
Modifying Edric's solution:
absTol = 1e-3; % You choose this value to be what you want!
relTol = 0.05; % This one too!
absError = x(:)-y(:);
relError = absError./x(:);
relError(~isfinite(relError)) = 0; % Sets Inf and NaN to 0
same = all( (abs(absError) < absTol) & (abs(relError) < relTol) );
The variable same will be false if either the absolute or the relative error of any element is larger than whatever tolerances you choose. Also, if any elements of x happen to be exactly 0, then some of the elements of relError could end up being either infinite or not-a-number, so I used the ISFINITE function to ignore those values by setting them to 0.
I wouldn't suggest using IMAGESC to compare plots, since 1) the data is scaled when it is displayed, 2) the colormap for the display has a discrete number of color values (which I think is 256 by default, hence lots of rounding), and 3) subtle variations in color may not be all that apparent from visual comparison of two plots.
I would consider doing something like this with an absolute tolerance as well as a relative tolerance:
function same = tol( x, y )
absTol = 1e-3;
relTol = 0.05;
errVec = abs( x(:) - y(:) );
same = all( (errVec < absTol) | (errVec./x(:) < relTol) );
When you have very small value pairs in x and y, the result would return 0 although the values are ignorable themselves. So, an addition to the accepted solution
relError(x < absTol) = 0;
might be used to discard very small errors. Thus, the relative error is not considered for these values.
For matrices x and y containing floating point values, you may check if array elements are within a given tolerance of one another.
Sample code:
tol = 0.05;
result = abs(x - y) <= tol;
make use of 'isequal(a,b) where a and b are two matrices, if 1 it is true