# MOD for optimization variable

18 views (last 30 days)
annazy on 22 Aug 2019
Commented: Matt J on 25 Aug 2019
Hi,
I have to optimize matrix to obtain quantities that will be divisible by certain numbers. When I use MOD on numbers, it works fine, for example MOD(10,3)=1. However, when I try to create constraint that I want my optimization variable x to be divisible by let's say 3 MOD(x,3), I get an error
Undefined function 'mod' for input arguments of type 'optim.problemdef.OptimizationVariable'.
Is there anything I can do to solve this issue?

Matt J on 24 Aug 2019
Edited: Matt J on 24 Aug 2019
No need to use constraints. Just declare x as an OptimizationExpression,
x=3*optimvar('z','Type', 'Integer','LowerBound',0)
x =
OptimizationExpression
3*z
Now use x freely to build the objective and constraints as you did previously. E.g.,
x=3*optimvar('z','Type', 'integer','LowerBound',0);
y=optimvar('y','LowerBound',0);
prob=optimproblem;
prob.Objective=2*x+4*y;
prob.Constraints=x+y>=7;
sol=solve(prob);
The solver will solve for z, not x,
>> sol
sol =
struct with fields:
y: 1.0000
z: 2.0000
but you can easily convert the optimal z to a corresponding result for x.
>> x_optimal=evaluate(x,sol)
x_optimal =
6.0000

Walter Roberson on 24 Aug 2019
Nice!
Matt J on 25 Aug 2019
annazy's comment moved here:
This is wonderful. What I actually need is this 'z', as I optimize quantities of products which must be divisible by number of products per cartoon. However this number varies depending on products. Also, I have multiple percentage constraints on quantities (not cartoons) which is why I can't focus on cartoons only, but in the end number of cartoons is what I need.
You are both amazing people, I hope one day I will be clever enough to help other lost souls like you do help me :)
Matt J on 25 Aug 2019

Walter Roberson on 22 Aug 2019
Introduce an extra integer variable and constrain equality x-3*extra = 1

Show 1 older comment
Walter Roberson on 23 Aug 2019
For a definitive answer as to whether there is any way to make mod() work, you will need to open a support case with Mathworks. Perhaps they have an in-house implementation that they might be willing to let you experiment with; I do not know.
What I do know is that there is no mod() available for optimization variables in any released version.
"I can't influence on values of x with some random integers as I have other requirements to be met :( "
I suspect you do not understand the process.
Suppose that you have a value of x = 16 and you want to check whether mod(x,3)=1 . If so, then by definition, there must be some integer N (that is not necessarily positive) such that 3*N+1 = x . This is not a "random integer": for 16 it is satisfied only by N = 5, 3*5 + 1 = 16. Likewise, if there is no integer N such that 3*N+1 = x, then mod(x,3)=1 is not true -- for example, for x = 17, then there is no such integer N.
Therefore if you introduce an integer-constrained variable N into the process and put in the equality constraint 3*N+1 = x, or 1 = x - 3*N or x - 3*N = 1 then N will not be random: it will be the exact integer needed such that 3*N+1 = x. You would not use the value of N in the calculation of your objective: it is enough to know that the constraint was met that there is some integer N such that x - 3*N = 1 is true.
annazy on 24 Aug 2019
Wow, thank you a lot for such detailed answer and your patience. Honestly, this is my first experience with Matlab and I am a bit confused with its options. I used to solve simple optimization problems with Excel Solver, however due to the dimension of the matrix, in this case I cannot use Solver as it can't hadle such large size. I was forced to learn basic optimization tools in Matlab within a week :(
I understand the process, I just don't know how to create such Integer variable correctly. I only add new variables with numbers or create optimization variables for objective funtion. Is it supposed to be a new optimization variable? Something like N=optimvar('N','Type','integer')?
Thanks in advance, you're saving my life.
Walter Roberson on 24 Aug 2019
Yes, N=optimvar('N','Type','integer') is good.
If you have upper and/or lower bound on x then you can use it to figure out upper and lower bounds on N to make the optimization more efficient.