 # How to assign value to a matrix in an indicator constraint

Is it possible and how to assign values to POSITION[R,C] matrix in the indicator constraint

``````
@variable(premex, ROLNA[R in keys(_ROWS), C in keys(_COLS), i_k in keys(_IMAGES_ALL)], Bin)
@variable(premex, POSITION[R in keys(_ROWS), C in keys(_COLS)], Bin)
@constraint(
premex,
SOMETHING[R in _ROWS, C in _COLS, i_k in keys(_IMAGES_ALL)],
ROLNA[R, C, i_k]  => {
POSITION[R1 + R - 1, C1 + C - 1]
# for R1 in collect(UnitRange(1, _IMAGES_ALL[i_k]["ROWS"])), C1 in collect(UnitRange(1, _IMAGES_ALL[i_k]["COLS"]))
# if (R1 + R - 1 <= length(_ROWS))
# for C1 in collect(UnitRange(1, _IMAGES_ALL[i_k]["COLS"]))
# if  (C1 + C - 1 <= length(_ROWS))
== 1
}
)
``````

My goal is to assign 1 to some values in POSITION matrix when ROLNA[R, C, i_k] = 1

What are these objects? Are `ROLNA` and `POSITION` both arrays of `Variable`s?

I’ve updated my question by adding their definitions.

So it looks like they’re both arrays of binary variables. In that case, at the index of interest, can you simply say `p == 1` and `r == 1`?

Also, I think it is better to omit the constraint name entirely than to name it something like `dsadasd`… unless that actually means something. I hope it isn’t rude to suggest there could be improvement to readability here Ok let me write this in C#

``````      int[] _ROWS = new int;
int[] _COLS = new int;
int[] _IMAGES = new int;
int[,] POSITION = new int[10, 10];
int[,,] ROLNA = new int[10, 10, 10];

int R, C, i_k, R1, C1;

for (R = 0; R < _ROWS.Length; R++)
{
for (C = 0; C < _COLS.Length; C++)
{
for (i_k = 0; i_k < _IMAGES.Length; i_k++)
{
if (ROLNA[R,C,i_k] == 1)
{
for (R1 = 0; R1 < 4; R1++)
{
for (C1 = 0; C1 < 4; C1++)
{
if (R1 + R - 1 <= _ROWS.Length && C1 + C - 1 <= _COLS.Length)
POSITION[R1 + R - 1,C1 + C - 1] = 1;
}
}
}
}
}
}
``````

So, iterate through all ROLNA and if one point is == 1 then assign 1 (ones) to a square in the POSITION matrix that way that upper left point matches the coordinates and add 4 x 4 to the right and down from that point - but really I don;t care this coordinates calculation, I need someone to help me how to assign values to a multidimensional array in indicator constraint and that is it, nothing more .

How to write this in Julia / Jump indicator constraint?

Is this an accurate translation?

``````for cartesian_index in eachindex(ROLNA)
r, c, i = Tuple(cartesian_index)
if value(ROLNA[r, c, i]) == 1
@constraint(premex, [r1 = 0:3, c1 = 0:3], POSITION[r+r1, c+c1] == 1)
end
end
``````

Even if not, the point is you can write all of the logic outside the `@constraint` macro and do the `@constraint` in the same place you seem to be doing it in the C# code. (I did a bit of a hybrid; one of the loops is external and the other is internal, but they can both be internal or both be external and that works too.)

edit: with both loops external and accounting for the bounds, it now looks like this

``````for cartesian_index in eachindex(ROLNA)
r, c, i = Tuple(cartesian_index)
if value(ROLNA[r, c, i]) == 1
for r′ in r:min(r+3, size(ROLNA, 1)),
c′ in c:min(c+3, size(ROLNA, 2))

@constraint(premex, POSITION[r′, c′] == 1)
end
end
end
``````

It’s a bit suspicious though that we’re iterating over the last index (`i`, above) and not using it anywhere. If for each `(r, c)`, if any `i` leads to a 1 constraint the rest don’t matter anymore, you could iterate on each coordinate `(R, C, I)` in a separate loop (like your C# code) and break the `i` loop if you encounter a 1 after setting the constraint. Could save you a tiny bit of repeated constraint setting . You could also use this to inform the loops on r, and c, since they should skip in increments of 4 in those cases… too complicated for me right now.

1 Like

Thanks, @tomerarnon that is exactly what I’ve needed -> so it is quite possible to iterate and then add it to the @constraint macro. Great! I will try this now.

Indeed it is! That is my preferred method, personally.

Thanks for your assistance, you’ve opened just another gate for me so I can move on 1 Like

This advice is incorrect, because it will be based on the previously solved value of `ROLNA`.

Since both are binary, use

``````for r′ in r:min(r+3, size(ROLNA, 1))
for c′ in c:min(c+3, size(ROLNA, 2))
@constraint(premex, POSITION[r′, c′] >= ROLNA[r, c, i])
end
end
``````
1 Like

I assumed this was the intention. The fact that the constraint was described as an “indicator” should have suggested that was not so, but I didn’t think through that.

1 Like

No worries. It’s useful to see different examples of more advanced things you can do with JuMP (adding constraints conditionally in a loop based on a previous solution).

I’ve tried what have @tomerarnon advised but I didn’t get the correct results. Let me explain what I am trying to do here. I want to allow ROLNA to hold only the top-left coordinate of an image from a set of images. Then I would assign all 1 to the remaining points of that image to POSITION matrix, So if POSITION has a value on x,y ROLNA cannot. How to write that.

Here is what I’ve tried from the last suggestion:

``````    @timeit to "02. this should put ones to POSITION matrix" begin
for R in _ROWS, C in _COLS, i_k in keys(_IMAGES_ALL)
if ROLNA[R, C, i_k] == 1
for R1 in collect(UnitRange(1, _IMAGES_ALL[i_k]["ROWS"])),
C1 in collect(UnitRange(1, _IMAGES_ALL[i_k]["COLS"]))
if (R1 == 1 && C1 == 1)
@constraint(premex, ROLNA[R, C, i_k] => {POSITION[R, C] == 0})
elseif (R1 + R - 1 <= length(_ROWS)) && (C1 + C - 1 <= length(_COLS))
@constraint(premex, ROLNA[R, C, i_k] => {POSITION[R1 + R - 1, C1 + C - 1] == 1})
end
end
end
end
end

@timeit to "03.this will prohibit ROLNA to take place that POSITION already holds" begin
for i_k in keys(_IMAGES_ALL)
@constraint(
premex,
[R in _ROWS, C in _COLS],
POSITION[R, C] => {ROLNA[R, C, i_k] == 0}
)
end
end
``````

I think the way to do this is:

``````1 - POSITION[R, C] >= ROLNA[R, C, I_k]
``````

so when `p == 1` you get `0 >= r` (ROLNA is 0), and when `p == 0`, `1 >= r`, which does nothing to a binary variable.

Yes, that is a good idea too, so the thing here is to build a huge amount of constraints (predefined) with all possible indexes, is that the way this works?

So if I have an image, let’s say 500 x 200 mm and I divide ROLE to mm grid, so to assign all 1 (ones) to POSITION system will have to create 500 x 200 constraints, is that?

Honestly, I don’t know… Maybe? I think posing this problem (I looked at the previous threads) as an MIP like you’re doing is more intuitive to conceptualize, but computationally will be difficult to solve. I have been wondering if the problem can be posed as e.g. a geometric program (and solved with Convex.jl), but I don’t know of some simple mapping that will make it so. Anyway, for me this is uncharted territory, so I can’t predict what the results of this approach will be Good luck!

1 Like