Akshay Agrawal commited on
Commit
f56200e
·
1 Parent(s): 94e0f7b

optimization: qps

Browse files
Files changed (1) hide show
  1. optimization/04_quadratic_program.py +136 -0
optimization/04_quadratic_program.py ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # /// script
2
+ # requires-python = ">=3.13"
3
+ # dependencies = [
4
+ # "cvxpy==1.6.0",
5
+ # "marimo",
6
+ # "numpy==2.2.2",
7
+ # ]
8
+ # ///
9
+
10
+ import marimo
11
+
12
+ __generated_with = "0.11.0"
13
+ app = marimo.App()
14
+
15
+
16
+ @app.cell(hide_code=True)
17
+ def _(mo):
18
+ mo.md(
19
+ r"""
20
+ # Quadratic program
21
+
22
+ A quadratic program is an optimization problem with a quadratic objective and
23
+ affine equality and inequality constraints. A common standard form is the
24
+ following:
25
+
26
+ \[
27
+ \begin{array}{ll}
28
+ \text{minimize} & (1/2)x^TPx + q^Tx\\
29
+ \text{subject to} & Gx \leq h \\
30
+ & Ax = b.
31
+ \end{array}
32
+ \]
33
+
34
+ Here $P \in \mathcal{S}^{n}_+$, $q \in \mathcal{R}^n$, $G \in \mathcal{R}^{m \times n}$, $h \in \mathcal{R}^m$, $A \in \mathcal{R}^{p \times n}$, and $b \in \mathcal{R}^p$ are problem data and $x \in \mathcal{R}^{n}$ is the optimization variable. The inequality constraint $Gx \leq h$ is elementwise.
35
+
36
+ **Why quadratic programming?** Quadratic programs are convex optimization problems that generalize both least-squares and linear programming.They can be solved efficiently and reliably, even in real-time.
37
+
38
+ **An example from finance.** A simple example of a quadratic program arises in finance. Suppose we have $n$ different stocks, an estimate $r \in \mathcal{R}^n$ of the expected return on each stock, and an estimate $\Sigma \in \mathcal{S}^{n}_+$ of the covariance of the returns. Then we solve the optimization problem
39
+
40
+ \[
41
+ \begin{array}{ll}
42
+ \text{minimize} & (1/2)x^T\Sigma x - r^Tx\\
43
+ \text{subject to} & x \geq 0 \\
44
+ & \mathbf{1}^Tx = 1,
45
+ \end{array}
46
+ \]
47
+
48
+ to find a nonnegative portfolio allocation $x \in \mathcal{R}^n_+$ that optimally balances expected return and variance of return.
49
+
50
+ When we solve a quadratic program, in addition to a solution $x^\star$, we obtain a dual solution $\lambda^\star$ corresponding to the inequality constraints. A positive entry $\lambda^\star_i$ indicates that the constraint $g_i^Tx \leq h_i$ holds with equality for $x^\star$ and suggests that changing $h_i$ would change the optimal value.
51
+ """
52
+ )
53
+ return
54
+
55
+
56
+ @app.cell(hide_code=True)
57
+ def _(mo):
58
+ mo.md(
59
+ r"""
60
+ ## Example
61
+
62
+ In this example, we use CVXPY to construct and solve a quadratic program.
63
+ """
64
+ )
65
+ return
66
+
67
+
68
+ @app.cell
69
+ def _():
70
+ import cvxpy as cp
71
+ import numpy as np
72
+ return cp, np
73
+
74
+
75
+ @app.cell(hide_code=True)
76
+ def _(mo):
77
+ mo.md("""First we generate synthetic data.""")
78
+ return
79
+
80
+
81
+ @app.cell
82
+ def _(np):
83
+ m = 15
84
+ n = 10
85
+ p = 5
86
+
87
+ np.random.seed(1)
88
+ P = np.random.randn(n, n)
89
+ P = P.T @ P
90
+ q = np.random.randn(n)
91
+ G = np.random.randn(m, n)
92
+ h = G @ np.random.randn(n)
93
+ A = np.random.randn(p, n)
94
+ b = np.random.randn(p)
95
+ return A, G, P, b, h, m, n, p, q
96
+
97
+
98
+ @app.cell(hide_code=True)
99
+ def _(mo):
100
+ mo.md(r"""Next, we specify the problem. Notice that we use the `quad_form` function from CVXPY to create the quadratic form $x^TPx$.""")
101
+ return
102
+
103
+
104
+ @app.cell
105
+ def _(A, G, P, b, cp, h, n, q):
106
+ x = cp.Variable(n)
107
+
108
+ problem = cp.Problem(
109
+ cp.Minimize((1 / 2) * cp.quad_form(x, P) + q.T @ x),
110
+ [G @ x <= h, A @ x == b],
111
+ )
112
+ _ = problem.solve()
113
+ return problem, x
114
+
115
+
116
+ @app.cell(hide_code=True)
117
+ def _(mo, problem, x):
118
+ mo.md(
119
+ f"""
120
+ The optimal value is {problem.value:.04f}.
121
+
122
+ A solution $x$ is {mo.as_html(list(x.value))}
123
+ A dual solution is is {mo.as_html(list(problem.constraints[0].dual_value))}
124
+ """
125
+ )
126
+ return
127
+
128
+
129
+ @app.cell
130
+ def _():
131
+ import marimo as mo
132
+ return (mo,)
133
+
134
+
135
+ if __name__ == "__main__":
136
+ app.run()