guys,I wrote the code and got the following error: #constraint is not defined. What did I wrong. How to fix it? Thanks
#constraintref restrição[1:2]
for j=1:2
#constraint(m, restrição[j], sum(A[j,i]*x[i] for i=1:3) <= b[j])`
end
```
You are using an old syntax that was valid in JuMP 0.18 (you can see the link for more details)
As of today you can just use an assignment operator instead of #constraintref macro and your code could look like this:
using GLPK
m = Model(with_optimizer(GLPK.Optimizer))
#variable(m, x[1:5] >= 0)
myCons = Vector{ConstraintRef}(undef, 5)
for i = 1:5
myCons[i] = #constraint(m, x[i] >= i)
end
Related
I'm new to Julia and JuMP, a library I'm going to use.
Trying to define the following constraint, after having defined the variables, I receive an error:
for r = 1:11
for d = 1:7
for s = 1:12
#constraint(model, mod(ris_day_ora[r,d,s],0.5)==0)
end
end
end
Here the error:
ERROR: LoadError: MethodError: no method matching mod(::VariableRef, ::Float64)
Could you please help me?
Thanks a lot in advance!
You cannot have a mod in a JuMP constraint.
You need to reformulate the model and there are many ways to do that.
In your case the easiest thing would be to declare ris_day_ora as Int and then divide it everywhere by 2.
#variable(model, ris_day_ora[1:11, 1:7, 1:12] >=0, Int)
And now everywhere in the code use ris_day_ora[r,d,s]/2.0 instead of ris_day_ora[r,d,s].
Edit:
if your variable ris_day_ora takes three values 0, 0.5, 1 you just model it as:
#variable(model, 0 <= ris_day_ora[1:11, 1:7, 1:12] <= 2, Int)
And in each place in model use it as 0.5 * ris_day_ora[r,d,s]
Edit 2
Perhaps you are looking for a more general solution. Consider x that can only be either 0.1, 0.3, 0.7 this could be written as:
#variable(model, x)
#variable(model, helper[1:3], Bin)
#contraint(model, x == 0.1*helper[1] + 0.3*helper[2] + 0.7*helper[3])
#contraint(model, sum(helper) == 1)
Is there a minimumby function for Julia (or some idiomatic substitute)? That is, I want something that works like:
julia> minimumby(length, ["Julion", "Julia", "Jule"])
"Jule"
I came up with the following, which seems to do what I want. Not sure how optimal it is.
function minimumby(keyf, a)
keymap = item -> (keyf(item), item)
keymin = (x, y) -> if y[1] < x[1] y else x end
mapreduce(keymap, keymin, a)[2]
end
No, unfortunately not. This had been requested for years, but no-one got around to implementing it.
Best I can do is:
julia> reduce((a, b) -> length(a) < length(b) ? a : b, ["Julion", "Julia", "Jule"])
"Jule"
I write a R function using if & else if in it. See the code below:
i_ti_12 <- function(x){
if (x <= 44)
{ti = exp(-13.2238 + 0.152568*x)}
else if (x >= 49)
{ti = -0.01245109 + 0.000315605*x}
else (x > 44 & x < 49)
{ti = (x-44)*(i_ti_12(49))/(49-44) + (49-x)*(i_ti_12(44))/(49-44)}
return(ti)
}
I want to use this function's output, i_ti_12(49) within this function, but the above code doesn't work. The output is:
> i_ti_12(49)
Error: C stack usage 7974292 is too close to the limit
The simple solution is just replace i_ti_12(49) by -0.01245109 + 0.000315605*49, but its not a clear way to solve it and might not work in complex cases.
So I really want to know and to learn if there are clear methods to do this? I mean, like above simple example, write a conditional function using one condition's output in this function. Any help is highly appreciate.
Your last else is followed by a condition (x > 44 & x < 49), which actually is not correct. If you have (x > 44 & x < 49) there, that means you will execute that statement, and ti = (x-44)*(i_ti_12(49))/(49-44) + (49-x)*(i_ti_12(44))/(49-44) is something independent with your if-else structure.
In that case, when you call i_ti_12(49), your function does not know when the recursion should be terminated since you did not define that case.
You can try the code below:
i_ti_12 <- function(x){
if (x <= 44)
{ti = exp(-13.2238 + 0.152568*x)}
else if (x >= 49)
{ti = -0.01245109 + 0.000315605*x}
else
{ti = (x-44)*(i_ti_12(49))/(49-44) + (49-x)*(i_ti_12(44))/(49-44)}
return(ti)
}
such that
> i_ti_12(49)
[1] 0.003013555
Is there a way to make certain functions such as isinteger() work with JuMPArrays?
I am using Julia/JuMP to solve an optimization problem, and after I get the solution, I want to check if the solution is integer. So here is what I wrote:
#defVar(m, 0<= x[1:3] <= 1)
...
xstar = getValue(x)
if isinteger(xstar)
...
end
And I get an error saying isinteger() has no method matching isinteger(::JuMPArray).
Thanks
So in general you can get an underlying array from a JuMPArray by using [:], e.g.
m = Model()
#variable(m, 0 <= x[1:3] <= 1)
#variable(m, 0 <= y[1:10, 1:10] <= 1)
solve(m)
xstar = getvalue(x)[:]
ystar = getvalue(y)[:,:]
Note that the reason for this is that JuMPArrays don't have to start with index 1, so the user needs to explicitly say they want a normal Julia array before doing things.
Regardless, you shouldn't use isinteger. Solvers don't always return very precise answers, e.g. they might say x[1] = 0.999996 but they really mean it is 1. You should do something like
for i in 1:3
if getvalue(x[i]) >= 0.999
println("x[$i] is 1!")
elseif getvalue(x[i]) <= 0.001
println("x[$i] is 0!")
end
end
to make sure you don't get any false negatives. If the variable is restricted to be integer or binary, use iround, e.g.
for i in 1:3
v = iround(getvalue(x[i]))
if v == 1
println("x[$i] is 1!")
elseif v == 0
println("x[$i] is 0!")
end
end
but it looks like in this case you are just seeing if the solution is naturally 0 or 1.
I have the image and the vector
a = imread('Lena.tiff');
v = [0,2,5,8,10,12,15,20,25];
and this M-file
function y = Funks(I, gama, c)
[m n] = size(I);
for i=1:m
for j=1:n
J(i, j) = (I(i, j) ^ gama) * c;
end
end
y = J;
imshow(y);
when I'm trying to do this:
f = Funks(a,v,2)
I am getting this error:
??? Error using ==> mpower
Integers can only be combined with integers of the same class, or scalar doubles.
Error in ==> Funks at 5
J(i, j) = (I(i, j) ^ gama) * c;
Can anybody help me, with this please?
The error is caused because you're trying to raise a number to a vector power. Translated (i.e. replacing formal arguments with actual arguments in the function call), it would be something like:
J(i, j) = (a(i, j) ^ [0,2,5,8,10,12,15,20,25]) * 2
Element-wise power .^ won't work either, because you'll try to "stuck" a vector into a scalar container.
Later edit: If you want to apply each gamma to your image, maybe this loop is more intuitive (though not the most efficient):
a = imread('Lena.tiff'); % Pics or GTFO
v = [0,2,5,8,10,12,15,20,25]; % Gamma (ar)ray -- this will burn any picture
f = cell(1, numel(v)); % Prepare container for your results
for k=1:numel(v)
f{k} = Funks(a, v(k), 2); % Save result from your function
end;
% (Afterwards you use cell array f for further processing)
Or you may take a look at the other (more efficient if maybe not clearer) solutions posted here.
Later(er?) edit: If your tiff file is CYMK, then the result of imread is a MxNx4 color matrix, which must be handled differently than usual (because it 3-dimensional).
There are two ways I would follow:
1) arrayfun
results = arrayfun(#(i) I(:).^gama(i)*c,1:numel(gama),'UniformOutput',false);
J = cellfun(#(x) reshape(x,size(I)),results,'UniformOutput',false);
2) bsxfun
results = bsxfun(#power,I(:),gama)*c;
results = num2cell(results,1);
J = cellfun(#(x) reshape(x,size(I)),results,'UniformOutput',false);
What you're trying to do makes no sense mathematically. You're trying to assign a vector to a number. Your problem is not the MATLAB programming, it's in the definition of what you're trying to do.
If you're trying to produce several images J, each of which corresponds to a certain gamma applied to the image, you should do it as follows:
function J = Funks(I, gama, c)
[m n] = size(I);
% get the number of images to produce
k = length(gama);
% Pre-allocate the output
J = zeros(m,n,k);
for i=1:m
for j=1:n
J(i, j, :) = (I(i, j) .^ gama) * c;
end
end
In the end you will get images J(:,:,1), J(:,:,2), etc.
If this is not what you want to do, then figure out your equations first.