You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: doc/mplp_tut.rst
+42-3Lines changed: 42 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -20,7 +20,7 @@ This optimization problem leads to the following multiparametric optimization pr
20
20
21
21
Using PPOPT, this is translated as the following python code. (The latex above was generated for me with ``prog.latex()`` if you were wondering if I typed that all out by hand.)
22
22
23
-
.. code:: python
23
+
.. code-block:: python
24
24
25
25
import numpy
26
26
from ppopt.mpqp_program importMPLP_Program
@@ -35,6 +35,45 @@ Using PPOPT, this is translated as the following python code. (The latex above w
35
35
36
36
prog = MPLP_Program(A, b, c, H, CRa, CRb, F)
37
37
38
+
Alternatively, we can use ``MPModeler`` to build the program. This can be a more user-friendly way to build the program, and it is easier to read and understand. It does not require the user to specify the problem data as matrices, but uses an interface that is more similar to a mathematical formulation.
# make a variable for each factory-market production pair
54
+
x = {(f, m): model.add_var(name=f'x[{f},{m}]') for f, m in product(factories, markets)}
55
+
56
+
# make a parameter for each market demand
57
+
d = {m: model.add_param(name=f'd_[{m}]') for m in markets}
58
+
59
+
# bounds on the production capacity of each factory
60
+
model.add_constrs(sum(x[f, m] for m in markets) <= capacities[f] for f in factories)
61
+
62
+
# demand satisfaction for each market
63
+
model.add_constrs(sum(x[f, m] for f in factories) >= d[m] for m in markets)
64
+
65
+
# bounds on the parametric demand
66
+
model.add_constrs(d[m] <=1000for m in markets)
67
+
model.add_constrs(d[m] >=0for m in markets)
68
+
69
+
# non-negativity of the production variables
70
+
model.add_constrs(x[f, m] >=0for f, m in product(factories, markets))
71
+
72
+
# set the objective to minimize the total cost
73
+
model.set_objective(sum(cost[f, m] * x[f, m] for f, m in product(factories, markets)))
74
+
75
+
prog = model.formulate_problem()
76
+
38
77
39
78
But before you go forward and solve this, I would always recommend processing the constraints. Removing all strongly and weakly redundant constraints and rescaling them leads to significant performance increases and robustifying the numerical stability. In PPOPT, processing the constraints is a simple task.
40
79
@@ -57,15 +96,15 @@ This results in the following (identical) multiparametric optimization problem.
57
96
58
97
That wasn't that bad, and we were able to cut away some constraints that didn't matter in the process! Now we are ready to solve it. We import the solver functionalities and then specify an algorithm to use. Here we are specifying the combinatorial algorithm. Even though we are using the ``solve_mpqp`` function, this is also the main backend to solve mpLPs!
59
98
60
-
.. code:: python
99
+
.. code-block:: python
61
100
62
101
from ppopt.mp_solvers.solve_mpqp import solve_mpqp, mpqp_algorithm
Now we have the solution, we can either export the solution via the micropop module, or we can plot it. Let's plot it here. The extra arguments mean we are saving a picture of the plot and displaying it to the user (you can give a file path, so it saves somewhere that is not the current working directory).
Copy file name to clipboardExpand all lines: doc/portfolio.rst
+34-1Lines changed: 34 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -25,7 +25,7 @@ Here the covariance matrix and the return coefficients were generated from rando
25
25
S = S@S.T /10
26
26
mu = numpy.random.rand(num_assets)/100
27
27
28
-
Here is the problem that we are going to be tackling in this post. Some of the constraints have been noticeably modified. This is due to a standard preprocessing pass that ``ppopt`` runs. This modification increases numerical stability for ill-conditioned optimization problems but has nearly for the problem we are looking at in this example, as it is numerically well conditioned.
28
+
Here is the problem that we are going to be tackling in this tutorial. Some of the constraints have been noticeably modified. This is due to a standard preprocessing pass that ``ppopt`` runs. This modification increases numerical stability for ill-conditioned optimization problems but has nearly for the problem we are looking at in this example, as it is numerically well conditioned.
29
29
30
30
.. code-block:: python
31
31
@@ -42,6 +42,39 @@ Here is the problem that we are going to be tackling in this post. Some of the c
Alternatively, we can use ``MPModeler`` to build the program. This can be a more user-friendly way to build the program, and it is easier to read and understand. It does not require the user to specify the problem data as matrices, but uses an interface that is more similar to a mathematical formulation.
46
+
47
+
.. code-block:: python
48
+
49
+
import numpy
50
+
from ppopt.mpmodel import MPModeler
51
+
52
+
model = MPModeler()
53
+
54
+
# make a variable for each asset
55
+
assets = [model.add_var(name=f'w[{i}]') for i inrange(num_assets)]
56
+
57
+
# define the parametric return
58
+
r = model.add_param(name='R')
59
+
60
+
# investment must add to one
61
+
model.add_constr(sum(assets) ==1)
62
+
63
+
# the expected return must be r
64
+
model.add_constr(sum(mu[i] * assets[i] for i inrange(num_assets)) == r)
65
+
66
+
# all assets must be non-negative (no shorting)
67
+
model.add_constrs(asset >=0for asset in assets)
68
+
69
+
# parametric return must be constrained to be [min(mu), max(mu)]
70
+
model.add_constr(r >=min(mu))
71
+
model.add_constr(r <=max(mu))
72
+
73
+
# set the objective to minimize the risk
74
+
model.set_objective(sum(S[i, j] * assets[i] * assets[j] for i inrange(num_assets) for j inrange(num_assets)))
75
+
76
+
portfolio = model.formulate_problem()
77
+
45
78
This formulates the parametric problem as follows, we want to parameterize the return :math:`R^*` as :math:`\theta`, so that we can solve over all feasible bounds of return.
Copy file name to clipboardExpand all lines: doc/tutorial.rst
+46-4Lines changed: 46 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -19,7 +19,7 @@ This optimization problem leads to the following multiparametric optimization pr
19
19
20
20
Using PPOPT, this is translated as the following python code. (The latex above was generated for me with ``prog.latex()`` if you were wondering if I typed that all out by hand.)
21
21
22
-
.. code:: python
22
+
.. code-block:: python
23
23
24
24
import numpy
25
25
from ppopt.mpqp_program importMPQP_Program
@@ -36,9 +36,51 @@ Using PPOPT, this is translated as the following python code. (The latex above w
36
36
prog = MPQP_Program(A, b, c, H, Q, CRa, CRb, F)
37
37
38
38
39
+
Alternatively, we can use ``MPModeler`` to build the program. This can be a more user-friendly way to build the program, and it is easier to read and understand. It does not require the user to specify the problem data as matrices, but uses an interface that is more similar to a mathematical formulation.
# make a variable for each factory-market production pair
55
+
x = {(f, m): model.add_var(name=f'x[{f},{m}]') for f, m in product(factories, markets)}
56
+
57
+
# make a parameter for each market demand
58
+
d = {m: model.add_param(name=f'd_[{m}]') for m in markets}
59
+
60
+
# bounds on the production capacity of each factory
61
+
model.add_constrs(sum(x[f, m] for m in markets) <= capacities[f] for f in factories)
62
+
63
+
# demand satisfaction for each market
64
+
model.add_constrs(sum(x[f, m] for f in factories) >= d[m] for m in markets)
65
+
66
+
# bounds on the parametric demand
67
+
model.add_constrs(d[m] <=1000for m in markets)
68
+
model.add_constrs(d[m] >=0for m in markets)
69
+
70
+
# non-negativity of the production variables
71
+
model.add_constrs(x[f, m] >=0for f, m in product(factories, markets))
72
+
73
+
# set the objective to minimize the total cost
74
+
model.set_objective(sum(cost[f, m] * x[f, m] **2+25* x[f, m] for f, m in product(factories, markets)))
75
+
76
+
prog = model.formulate_problem()
77
+
78
+
39
79
But before you go forward and solve this, I would always recommend processing the constraints. Removing all strongly and weakly redundant constraints and rescaling them leads to significant performance increases and robustifying the numerical stability. In PPOPT, processing the constraints is a simple task.
40
80
41
-
.. code:: python
81
+
82
+
83
+
.. code-block:: python
42
84
43
85
prog.process_constraints()
44
86
@@ -57,15 +99,15 @@ This results in the following (identical) multiparametric optimization problem.
57
99
58
100
That wasn't that bad, and we were able to cut away some constraints that didn't matter in the process! Now we are ready to solve it. We import the solver functionalities and then specify an algorithm to use. Here we are specifying the combinatorial algorithm.
59
101
60
-
.. code:: python
102
+
.. code-block:: python
61
103
62
104
from ppopt.mp_solvers.solve_mpqp import solve_mpqp, mpqp_algorithm
Now we have the solution, we can either export the solution via the micropop module, or we can plot it. Let's plot it here. The extra arguments mean we are saving a picture of the plot and displaying it to the user (you can give a file path, so it saves somewhere that is not the current working directory).
0 commit comments