optimeq

Create empty optimization equality array

Description

example

eq = optimeq(N) creates an N-by-1 array of empty optimization equalities. Use eq to initialize a loop that creates equalities. Use the resulting equalities as constraints in an optimization problem or as equations in an equation problem.

example

eq = optimeq(cstr) creates an array of empty optimization equalities that are indexed by cstr, a cell array of character vectors or string vectors .

If cstr is 1-by-ncstr, where ncstr is the number of elements of cstr, then eq is also 1-by-ncstr. Otherwise, eq is ncstr-by-1.

eq = optimeq(cstr1,N2,...,cstrk) or eq = optimeq({cstr1,cstr2,...,cstrk}) or eq = optimeq([N1,N2,...,Nk]), for any combination of cstr and N arguments, creates an ncstr1-by-N2-by-...-by-ncstrk array of empty optimization equalities, where ncstr is the number of elements in cstr.

Examples

collapse all

Create equality constraints for an inventory model. The stock of goods at the start of each period is equal to the stock at the end of the previous period. During each period, the stock increases by buy and decreases by sell. The variable stock is the stock at the end of the period.

N = 12;
stock = optimvar('stock',N,1,'Type','integer','LowerBound',0);
buy = optimvar('buy',N,1,'Type','integer','LowerBound',0);
sell = optimvar('sell',N,1,'Type','integer','LowerBound',0);
initialstock = 100;

stockbalance = optimeq(N,1);

for t = 1:N
    if t == 1
        enterstock = initialstock;
    else
        enterstock = stock(t-1);
    end
    stockbalance(t) = stock(t) == enterstock + buy(t) - sell(t);
end

show(stockbalance)
(1, 1)

  -buy(1) + sell(1) + stock(1) == 100

(2, 1)

  -buy(2) + sell(2) - stock(1) + stock(2) == 0

(3, 1)

  -buy(3) + sell(3) - stock(2) + stock(3) == 0

(4, 1)

  -buy(4) + sell(4) - stock(3) + stock(4) == 0

(5, 1)

  -buy(5) + sell(5) - stock(4) + stock(5) == 0

(6, 1)

  -buy(6) + sell(6) - stock(5) + stock(6) == 0

(7, 1)

  -buy(7) + sell(7) - stock(6) + stock(7) == 0

(8, 1)

  -buy(8) + sell(8) - stock(7) + stock(8) == 0

(9, 1)

  -buy(9) + sell(9) - stock(8) + stock(9) == 0

(10, 1)

  -buy(10) + sell(10) - stock(9) + stock(10) == 0

(11, 1)

  -buy(11) + sell(11) - stock(10) + stock(11) == 0

(12, 1)

  -buy(12) + sell(12) - stock(11) + stock(12) == 0

Include the constraints in an optimization problem.

prob = optimproblem;
prob.Constraints.stockbalance = stockbalance;

Instead of using a loop, you can create the same constraints by using matrix operations on the variables.

stockbalance2 = optimeq(12, 1);
t = 2:12;
stockbalance2(t) = stock(t) == stock(t-1) + buy(t) - sell(t);
stockbalance2(1) = stock(1) == initialstock + buy(1) - sell(1);

Display the new constraints. Note that they are the same as the constraints in stockbalance.

show(stockbalance2)
(1, 1)

  -buy(1) + sell(1) + stock(1) == 100

(2, 1)

  -buy(2) + sell(2) - stock(1) + stock(2) == 0

(3, 1)

  -buy(3) + sell(3) - stock(2) + stock(3) == 0

(4, 1)

  -buy(4) + sell(4) - stock(3) + stock(4) == 0

(5, 1)

  -buy(5) + sell(5) - stock(4) + stock(5) == 0

(6, 1)

  -buy(6) + sell(6) - stock(5) + stock(6) == 0

(7, 1)

  -buy(7) + sell(7) - stock(6) + stock(7) == 0

(8, 1)

  -buy(8) + sell(8) - stock(7) + stock(8) == 0

(9, 1)

  -buy(9) + sell(9) - stock(8) + stock(9) == 0

(10, 1)

  -buy(10) + sell(10) - stock(9) + stock(10) == 0

(11, 1)

  -buy(11) + sell(11) - stock(10) + stock(11) == 0

(12, 1)

  -buy(12) + sell(12) - stock(11) + stock(12) == 0

Creating constraints in a loop can be more time consuming than creating constraints by using matrix operations.

Create indexed equalities for a problem that involves shipping goods between airports. First, create indices representing airports.

airports = ["LAX" "JFK" "ORD"];

Create indices representing goods to be shipped from one airport to another.

goods = ["Electronics" "Foodstuffs" "Clothing" "Raw Materials"];

Create an array giving the weight of each unit of the goods.

weights = [1 20 5 100];

Create a variable array representing quantities of goods to be shipped from each airport to each other airport. quantities(airport1,airport2,goods) represents the quantity of goods being shipped from airport1 to airport2.

quantities = optimvar('quantities',airports,airports,goods,'LowerBound',0);

Create an equality constraint that the sum of the weights of goods being shipped from each airport is equal to the sum of the weights of goods being shipped to the airport.

eq = optimeq(airports);
outweight = optimexpr(size(eq));
inweight = optimexpr(size(eq));
for i = 1:length(airports)
    temp = optimexpr;
    temp2 = optimexpr;
    for j = 1:length(airports)
        for k = 1:length(goods)
            temp = temp + quantities(i,j,k)*weights(k);
            temp2 = temp2 + quantities(j,i,k)*weights(k);
        end
    end
    outweight(i) = temp;
    inweight(i) = temp2;
    eq(i) = outweight(i) == inweight(i);
end

Examine the equalities.

show(eq)
(1, 'LAX')

  -quantities('JFK', 'LAX', 'Electronics') - quantities('ORD', 'LAX', 'Electronics')
+ quantities('LAX', 'JFK', 'Electronics') + quantities('LAX', 'ORD', 'Electronics')
- 20*quantities('JFK', 'LAX', 'Foodstuffs') - 20*quantities('ORD', 'LAX', 'Foodstuffs')
+ 20*quantities('LAX', 'JFK', 'Foodstuffs') + 20*quantities('LAX', 'ORD', 'Foodstuffs')
- 5*quantities('JFK', 'LAX', 'Clothing') - 5*quantities('ORD', 'LAX', 'Clothing')
+ 5*quantities('LAX', 'JFK', 'Clothing') + 5*quantities('LAX', 'ORD', 'Clothing')
- 100*quantities('JFK', 'LAX', 'Raw Materials') - 100*quantities('ORD', 'LAX', 'Raw Materials')
+ 100*quantities('LAX', 'JFK', 'Raw Materials') + 100*quantities('LAX', 'ORD', 'Raw Materials') == 0

(1, 'JFK')

  quantities('JFK', 'LAX', 'Electronics') - quantities('LAX', 'JFK', 'Electronics')
- quantities('ORD', 'JFK', 'Electronics') + quantities('JFK', 'ORD', 'Electronics')
+ 20*quantities('JFK', 'LAX', 'Foodstuffs') - 20*quantities('LAX', 'JFK', 'Foodstuffs')
- 20*quantities('ORD', 'JFK', 'Foodstuffs') + 20*quantities('JFK', 'ORD', 'Foodstuffs')
+ 5*quantities('JFK', 'LAX', 'Clothing') - 5*quantities('LAX', 'JFK', 'Clothing')
- 5*quantities('ORD', 'JFK', 'Clothing') + 5*quantities('JFK', 'ORD', 'Clothing')
+ 100*quantities('JFK', 'LAX', 'Raw Materials') - 100*quantities('LAX', 'JFK', 'Raw Materials')
- 100*quantities('ORD', 'JFK', 'Raw Materials') + 100*quantities('JFK', 'ORD', 'Raw Materials') == 0

(1, 'ORD')

  quantities('ORD', 'LAX', 'Electronics') + quantities('ORD', 'JFK', 'Electronics')
- quantities('LAX', 'ORD', 'Electronics') - quantities('JFK', 'ORD', 'Electronics')
+ 20*quantities('ORD', 'LAX', 'Foodstuffs') + 20*quantities('ORD', 'JFK', 'Foodstuffs')
- 20*quantities('LAX', 'ORD', 'Foodstuffs') - 20*quantities('JFK', 'ORD', 'Foodstuffs')
+ 5*quantities('ORD', 'LAX', 'Clothing') + 5*quantities('ORD', 'JFK', 'Clothing')
- 5*quantities('LAX', 'ORD', 'Clothing') - 5*quantities('JFK', 'ORD', 'Clothing')
+ 100*quantities('ORD', 'LAX', 'Raw Materials') + 100*quantities('ORD', 'JFK', 'Raw Materials')
- 100*quantities('LAX', 'ORD', 'Raw Materials') - 100*quantities('JFK', 'ORD', 'Raw Materials') == 0

To avoid the nested for loops, express the equalities using standard MATLAB® operators. Create the array of departing quantities by summing over the arrival airport indices. Squeeze the result to remove the singleton dimension.

departing = squeeze(sum(quantities,2));

Calculate the weights of the departing quantities.

departweights = departing * weights';

Similarly, calculate the weights of arriving quantities.

arriving = squeeze(sum(quantities,1));
arriveweights = arriving*weights';

Create the constraints that the departing weights equal the arriving weights.

eq2 = departweights == arriveweights;

Include the appropriate index names for the equalities by setting the IndexNames property.

eq2.IndexNames = {airports,{}};

Display the new equalities. Note that they match the previous equalities, but are transposed vectors.

show(eq2)
('LAX', 1)

  -quantities('JFK', 'LAX', 'Electronics') - quantities('ORD', 'LAX', 'Electronics')
+ quantities('LAX', 'JFK', 'Electronics') + quantities('LAX', 'ORD', 'Electronics')
- 20*quantities('JFK', 'LAX', 'Foodstuffs') - 20*quantities('ORD', 'LAX', 'Foodstuffs')
+ 20*quantities('LAX', 'JFK', 'Foodstuffs') + 20*quantities('LAX', 'ORD', 'Foodstuffs')
- 5*quantities('JFK', 'LAX', 'Clothing') - 5*quantities('ORD', 'LAX', 'Clothing')
+ 5*quantities('LAX', 'JFK', 'Clothing') + 5*quantities('LAX', 'ORD', 'Clothing')
- 100*quantities('JFK', 'LAX', 'Raw Materials') - 100*quantities('ORD', 'LAX', 'Raw Materials')
+ 100*quantities('LAX', 'JFK', 'Raw Materials') + 100*quantities('LAX', 'ORD', 'Raw Materials') == 0

('JFK', 1)

  quantities('JFK', 'LAX', 'Electronics') - quantities('LAX', 'JFK', 'Electronics')
- quantities('ORD', 'JFK', 'Electronics') + quantities('JFK', 'ORD', 'Electronics')
+ 20*quantities('JFK', 'LAX', 'Foodstuffs') - 20*quantities('LAX', 'JFK', 'Foodstuffs')
- 20*quantities('ORD', 'JFK', 'Foodstuffs') + 20*quantities('JFK', 'ORD', 'Foodstuffs')
+ 5*quantities('JFK', 'LAX', 'Clothing') - 5*quantities('LAX', 'JFK', 'Clothing')
- 5*quantities('ORD', 'JFK', 'Clothing') + 5*quantities('JFK', 'ORD', 'Clothing')
+ 100*quantities('JFK', 'LAX', 'Raw Materials') - 100*quantities('LAX', 'JFK', 'Raw Materials')
- 100*quantities('ORD', 'JFK', 'Raw Materials') + 100*quantities('JFK', 'ORD', 'Raw Materials') == 0

('ORD', 1)

  quantities('ORD', 'LAX', 'Electronics') + quantities('ORD', 'JFK', 'Electronics')
- quantities('LAX', 'ORD', 'Electronics') - quantities('JFK', 'ORD', 'Electronics')
+ 20*quantities('ORD', 'LAX', 'Foodstuffs') + 20*quantities('ORD', 'JFK', 'Foodstuffs')
- 20*quantities('LAX', 'ORD', 'Foodstuffs') - 20*quantities('JFK', 'ORD', 'Foodstuffs')
+ 5*quantities('ORD', 'LAX', 'Clothing') + 5*quantities('ORD', 'JFK', 'Clothing')
- 5*quantities('LAX', 'ORD', 'Clothing') - 5*quantities('JFK', 'ORD', 'Clothing')
+ 100*quantities('ORD', 'LAX', 'Raw Materials') + 100*quantities('ORD', 'JFK', 'Raw Materials')
- 100*quantities('LAX', 'ORD', 'Raw Materials') - 100*quantities('JFK', 'ORD', 'Raw Materials') == 0

Creating constraints in a loop can be more time consuming than creating constraints by using matrix operations.

Input Arguments

collapse all

Size of the constraint dimension, specified as a positive integer.

  • The size of constr = optimeq(N) is N-by-1.

  • The size of constr = optimeq(N1,N2) is N1-by-N2.

  • The size of constr = optimeq(N1,N2,...,Nk) is N1-by-N2-by-...-by-Nk.

Example: 5

Data Types: double

Names for indexing, specified as a cell array of character vectors or a string vector.

Example: {'red','orange','green','blue'}

Example: ["red";"orange";"green";"blue"]

Data Types: string | cell

Output Arguments

collapse all

Equalities, returned as an empty OptimizationEquality array. Use eq to initialize a loop that creates equalities.

For example:

x = optimvar('x',8);
eq = optimeq(4);
for k = 1:4
    eq(k) = 5*k*(x(2*k) - x(2*k-1)) == 10 - 2*k;
end

Tips

  • You can use optimconstr instead of optimeq to create equality constraints for optimization problems or equations for equation problems.

Introduced in R2019b