<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://govindchari.com/feed.xml" rel="self" type="application/atom+xml"/><link href="https://govindchari.com/" rel="alternate" type="text/html" hreflang="en"/><updated>2026-06-17T23:44:17+00:00</updated><id>https://govindchari.com/feed.xml</id><title type="html">blank</title><subtitle>A simple, whitespace theme for academics. Based on [*folio](https://github.com/bogoli/-folio) design. </subtitle><entry><title type="html">Resource list</title><link href="https://govindchari.com/blog/2025/resource-list/" rel="alternate" type="text/html" title="Resource list"/><published>2025-03-09T00:00:00+00:00</published><updated>2025-03-09T00:00:00+00:00</updated><id>https://govindchari.com/blog/2025/resource-list</id><content type="html" xml:base="https://govindchari.com/blog/2025/resource-list/"><![CDATA[<p>This post is a collection of good resources I have used during my studies to learn topics in convex optimization and computer systems and my review of each resource. This is intended to be a living document, and I will update this list every once in a while.</p> <p>Disclaimer: I am not an expert in optimization or computing, but I am writing this post because I feel like I have spent enough time learning both to be able to recommend good resources.</p> <h2 id="optimization">Optimization</h2> <p>This section mostly focuses on convex optimization.</p> <h3 id="convex-optimization-by-boyd-and-vandenberghe">Convex Optimization by Boyd and Vandenberghe</h3> <p>This textbook which can freely be found <a href="https://web.stanford.edu/~boyd/cvxbook/bv_cvxbook.pdf">here</a> is the classic introduction resource to convex optimization. This textbook has corresponding lectures by Stephen Boyd which can be found <a href="https://www.youtube.com/playlist?list=PL3940DD956CDF0622">here</a>. Additionally, Professor Boyd teaches this course at Stanford University and the course webpage which has all the lecture notes can be found <a href="https://web.stanford.edu/class/ee364a/">here</a>.</p> <p>The textbook has three parts: theory, application, and algorithms. The theory part of the textbook mostly focuses on what is convexity, why is it important, and what are operations that preserve convexity. Then it covers the classical convex optimization problems such as linear programs, quadratic programs, second-order cone programs, and semidefinite programs. Finally, it covers duality and the Karush-Kuhn-Tucker (KKT) conditions.</p> <p>I think this book is a good introduction to convex optimization, but it is not my favorite textbook to learn optimization algorithms from. Although part 3 of the textbook does cover optimization algorithms, it mostly focuses on primal interior point methods, which are not used much by popular convex solvers. Additionally, I do not care much for the presentation of duality, it feels quite prescriptive in my opinion and a bit unmotivated. Boyd presents duality as a “structured way to create lower bounds for optimization problems”, which although that is true, I believe the real importance of duality in convex optimization is to aid in algorithm design.</p> <p>Nevertheless, I recommend any beginner to read the first part of this book before reading any other textbook on this list.</p> <h3 id="numerical-optimization-by-nocedal-and-wright">Numerical Optimization by Nocedal and Wright</h3> <p>This is one of the best textbooks for learning about optimization algorithms. The beginning of the book discusses optimization algorithms for unconstrained nonconvex problems. To be honest I have not read much of that part. Chapters 12-17 are a goldmine for learning about algorithms for constrained convex optimization. I also love the presentation of duality in Chapter 12 far more than Boyd’s treatment. In this textbook duality is presented as a tool in algorithm design.</p> <p>I also enjoy the historical perspective this textbook brings on optimization algorithms. First, the simplex method for linear programming is discussed, then its drawbacks (worst case exponential runtime) are presented, then interior point methods are presented. This textbook in my opinion, has the best explanation for how primal and primal-dual interior point methods work. My only complaint is that the primal-dual interior point method is only described for linear programming and quadratic programming and does not include second-order cone programming and semidefinite cone programming. The book also discusses active set methods for quadratic programming and presents the material is a very clear way.</p> <p>My only complaints about this book is that primal-dual interior point methods are not described for second-order cone programming and semidefinite programming. Also operator splitting methods such as forward-backwards splitting, ADMM, and PDHG are not discussed.</p> <h3 id="large-scale-convex-optimization-by-ryu-and-yin">Large-Scale Convex Optimization by Ryu and Yin</h3> <p>This textbook can be freely found <a href="https://large-scale-book.mathopt.com/LSCOMO.pdf">here</a> with accompanying videos <a href="https://www.youtube.com/@large-scaleconvexoptimizat2973/videos">here</a>.</p> <p>This is my favorite textbook of all time by a long shot, and is the best resource I have found to understand operator-splitting methods. I have always heard about projected gradient descent, the proximal point method, ISTA, augmented Lagrangian methods, Douglas-Rachford Splitting, ADMM, PDHG etc, and always viewed them as separate concepts in my mind. However, this textbook unifies all of these algorithms as fixed-point iterations with some averaged operator. Even reading the first three chapters will be an extremely eye-opening experience to those interested in operator-splitting methods.</p> <h3 id="convex-analysis-and-nonsmooth-optimization-by-drusvyatskiy">Convex Analysis and Nonsmooth Optimization by Drusvyatskiy</h3> <p><a href="https://sites.math.washington.edu/~ddrusv/crs/Math_516_2020/bookwithindex.pdf">This set of course notes</a> discusses the fundemental concepts in convex analysis in a rigorous way. I used these notes in my Convex Analysis class and enjoyed them.</p> <h3 id="convex-analysis-and-monotone-operator-theory-by-baushke-and-combettes">Convex Analysis and Monotone Operator Theory by Baushke and Combettes</h3> <p>Disclaimer: I have not read this textbook, but it has been highly praised for rigorously discussed Monotone operator theory which is fundamental for rigorously analyzing operator splitting methods.</p> <h2 id="computing">Computing</h2> <h3 id="the-cherno">The Cherno</h3> <p>The YouTube playlist is <a href="https://www.youtube.com/playlist?list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb">here</a>. This is the best video series to learn C++. I love that he discusses not only C++ syntax, but what is happening under the hood in terms how data and the program is stored in memory.</p> <h3 id="building-an-8-bit-computer">Building an 8-bit computer</h3> <p><a href="https://www.youtube.com/playlist?list=PLowKtXNTBypGqImE405J2565dvjafglHU">This video series</a> by Ben Eater is a fantastic introduction to computer architecture. He starts from simple and/or/not gates and builds an 8-bit computer on a breadboard while explaining everything you need to know along the way.</p> <p>Although this series does not discuss important topics for performance such as cache and branch prediction, this is a fantastic video series for a beginner who wants to understand how a CPU works.</p> <h3 id="computer-systems-programming">Computer Systems Programming</h3> <p>This <a href="https://scs.hosted.panopto.com/Panopto/Pages/Sessions/List.aspx#folderID=%22b96d90ae-9871-4fae-91e2-b1627b43e25e%22">video series</a> is from the 15-213: Introduction to Computer Systems course at Carnegie Mellon University and follows <a href="https://www.cs.cmu.edu/~213/textbook.html">this textbook</a>.</p> <p>This is my favorite resource to learn about lower level concepts in computing such as assembly, memory cache, and writing more performant code.</p> <h3 id="performance-aware-programming">Performance Aware Programming</h3> <p><a href="https://www.computerenhance.com/p/table-of-contents">This course</a> by Casey Muratori is fantastic for understanding how to write code in a performance oriented way. I am currently working through it.</p> <h2 id="math">Math</h2> <h3 id="elementary-analysis-by-kenneth-ross">Elementary Analysis by Kenneth Ross</h3> <p>I learned basic analysis from this textbook. The book is well written, I like the examples and I like that the textbook is not overly rigorous like Rudin. I think it is a good intro to analysis.</p> <h3 id="introductory-functional-analysis-by-erwin-kreyszig">Introductory Functional Analysis by Erwin Kreyszig</h3> <p>I have skimmed the first few chapters. The author does a good job of motivating the need for the abstraction of metric and Banach spaces. Most of the material in the first two chapters was pretty easy to grasp with knowledge of proofs, linear algebra, and analysis. I started reading this textbook so I could understand Convex Analysis and Monotone Operator Theory by Baushke and Combettes, as they work in Hilbert spaces. I also think this material is pretty interesting in its own right.</p> <hr/>]]></content><author><name>Govind Chari</name></author><category term="optimization"/><summary type="html"><![CDATA[Various useful resources for learning optimization and computing]]></summary></entry><entry><title type="html">Solving the Lasso Problem</title><link href="https://govindchari.com/blog/2023/solving-lasso/" rel="alternate" type="text/html" title="Solving the Lasso Problem"/><published>2023-10-25T00:00:00+00:00</published><updated>2023-10-25T00:00:00+00:00</updated><id>https://govindchari.com/blog/2023/solving-lasso</id><content type="html" xml:base="https://govindchari.com/blog/2023/solving-lasso/"><![CDATA[<h2 id="introduction">Introduction</h2> <p>Lasso regression is and important regularization technique for linear regression that can also perform variable selection. What this means is that solutions to the lasso problem tend to be sparse (contain zeros) which allows us to rule out certain independent variables in our model. A great resource to familiarize yourself with lasso is <a href="https://www.youtube.com/watch?v=GaXfqoLR_yI&amp;ab_channel=SteveBrunton">this video</a>.</p> <p>Lasso is of incredible importance in statistics, signal processing, compressed sensing, and image processing. In this post we will look at a variety of optimization technique for solving the lasso problem.</p> <p>The lasso optimization problem is an unconstrained optimization problem which can be written as follows:</p> \[\begin{split} \underset{x}{\text{minimize}} \quad &amp; \frac{1}{2}\|Ax-b\|_2^2 + \lambda \|x\|_1 \\ \end{split}\] <p>where $A \in \mathbb{R}^{m \times n}$</p> <p>A first thought to solve this problem might be gradient descent, however the objective function is non-smooth (due to the l1 penalty), so we cannot use gradient descent. A second thought is to use subgradient descent, which is a generalization of gradient descent to non-smooth functions. This would work, but subgradient descent has an extremely slow worst-case convergence rate of $\mathcal{O}(1 / \sqrt{t})$ (meaning you need four times the iterations to double the accuracy) so we will look at better algorithms.</p> <h2 id="reformulating-as-quadratic-program">Reformulating as Quadratic Program</h2> <p>One of the easiest things to do would be reformulating this problem as a Quadratic Program (QP) as follows:</p> \[\begin{split} \underset{x}{\text{minimize}} \quad &amp; \frac{1}{2}\|Ax-b\|_2^2 + \lambda \sum_{i=1}^n t_i \\ \text{subject to} \quad &amp; -t_i \leq x_i \leq t_i \quad \forall i \in [1,n] \end{split}\] <p>To see how this was done reference the <a href="https://docs.mosek.com/modeling-cookbook/linear.html#the-ell-1-norm">Mosek Modeling Cookbook</a></p> <p>We can then feed this into a QP solver such as OSQP and then get an answer. This works, but it feels wasteful to turn an unconstrained problem into a constrained one and then use a generic QP solver. There should be better algorithms that exploit the structure of our problem where we have a smooth plus a non-smooth term.</p> <h2 id="ista">ISTA</h2> <p>ISTA or iterative shrinking threshold algorithm is an application of the proximal gradient method to the Lasso problem.</p> <p>The proximal gradient method solves problems of the following form, where $f$ is differentiable</p> \[\begin{split} \underset{x}{\text{minimize}} \quad &amp; f(x) + g(x) \\ \end{split}\] <p>The algorithm looks as follows:</p> \[x_{k+1} = \boldsymbol{\text{prox}}_{\eta g}(x_k - \eta \nabla f(x_k))\] <p>where $\eta$ is the gradient descent stepsize for $f$ which will be the inverse of the Lipschitz constant of $f$.</p> <p>The proximal operator $\boldsymbol{\text{prox}}_{\eta g}$ is a generalization of the projection operation and is defined as follows</p> \[\boldsymbol{\text{prox}}_{\eta f}(v) = \underset{x}{\text{argmin}} \left(f(x) + \frac{1}{2\eta}\|x-v\|_2^2\right)\] <p>You can think of the proximal operator as returning a point which balances minimizing the function and staying close to the current point. The proximal operator for many function are well known in closed form. For more information on proximal operators and algorithms using proximal operators, refer to <d-cite key="Parikh2014Proximal"></d-cite>.</p> <p>The idea behind the proximal gradient method is to perform a gradient descent step assuming we are just going to be minimizing the smooth function $f$ and then do an evaluation of the proximal operator for $g$ which can be interpreted as a gradient descent step on the smoothed version of $g$. More technically we do a gradient descent step on the Moreau envelope of $g$.</p> <p>Alternating between these two steps, we eventually minimize our original objective function.</p> <p>For Lasso we will take,</p> \[\begin{split} f(x) &amp;= \frac{1}{2}\|Ax-b\|_2^2 \\ g(x) &amp;= \|x\|_1 \\ \end{split}\] <p>It can be shown that the proximal operator for the l1 norm is the soft threshold operator</p> \[\boldsymbol{\text{prox}}_{\eta \|\cdot\|_1}(v) = \mathcal{S}_\eta(v) = \text{sign}(v)\max(|v|-\eta,0)\] <p>We can now write out the ISTA iterates as follows</p> \[x_{k+1} = \mathcal{S}_{\lambda/L}\left(x_k - \frac{1}{L}A^\top(Ax_k-b)\right)\] <p>Where $L$ is the maximum eigenvalue of $A^TA$. This can quickly be computed via <a href="https://en.wikipedia.org/wiki/Power_iteration">power iteration</a>.</p> <p>It can be shown that this algorithm has a worst-case convergence rate of $\mathcal{O}(1 / t)$ meaning that if we double the number of iterations, we double the accuracy of the solution. This is already better than subgradient method, but is not the best we can do.</p> <h2 id="fista">FISTA</h2> <p>ISTA was used for a while, but many researchers noticed that it can be painfully slow to converge. In 2009, Beck and Teboulle introduced FISTA (Fast Iterative Shrinking Threshold Algorithm) where they used momentum to accelerate ISTA and were able to achieve the worst-case convergence rate of $\mathcal{O}(1 / t^2)$ , meaning that if we double the number of iterations, we quadruple the accuracy of the solution <d-cite key="Beck2009Fast"></d-cite>. FISTA can be thought of as applying ideas from <a href="https://web.archive.org/web/20210302210908/https://blogs.princeton.edu/imabandit/2013/04/01/acceleratedgradientdescent/">Nesterov’s Accelerated Gradient</a> to ISTA.</p> <p>This algorithm can be written as follows</p> \[\begin{align} x_k &amp;= \mathcal{S}_{\lambda/L}\left(y_k - \frac{1}{L}A^\top(Ay_k-b)\right) \\ t_{k+1} &amp;= \frac{1+\sqrt{1+4t_k^2}}{2} \\ y_{k+1} &amp;= x_k + \left(\frac{t_k-1}{t_{k+1}}\right)(x_k-x_{k-1}) \end{align}\] <h2 id="admm">ADMM</h2> <p>The final algorithm we will consider for Lasso is the Alternating Direction Method of Multiplers (ADMM). This algorithm was introduced in the mid-1970s, but became popular again after Stephen Boyd <em>et al</em> published their paper in 2011 <d-cite key="Boyd2011-lv"></d-cite>. This algorithm attempts to solve problems of the following form</p> \[\begin{split} \underset{x,z}{\text{minimize}} \quad &amp; f(x) + g(z) \\ \text{subject to} \quad &amp; x = z, \\ \end{split}\] <p>The iterates of the algorithm are as follows:</p> \[\begin{align} x_{k+1} &amp;= \underset{x}{\text{argmin}} \; \mathcal{L}_\rho(x,z_k,y_k) \\ z_{k+1} &amp;= \underset{z}{\text{argmin}} \;\mathcal{L}_\rho(x_{k+1},z,y_k) \\ y_{k+1} &amp;= y_k + \rho(x_{k+1}-z_{k+1}) \end{align}\] <p>where</p> \[\mathcal{L}_\rho(x,z,y) = f(x) + g(z) + y^T(x-z) + \frac{\rho}{2}\|x-z\|_2^2\] <p>For the case of Lasso, we have</p> \[\begin{align} f(x) &amp;= \frac{1}{2}\|Ax-b\|_2^2 \\ g(z) &amp;= \|z\|_1 \end{align}\] <p>and the ADMM iterates become</p> \[\begin{align} x_{k+1} &amp;= (A^TA+\rho I)^{-1}(A^Tb+\rho z_k -y_k) \\ z_{k+1} &amp;= \mathcal{S}_{\lambda/\rho} (x_{k+1}+y_k/\rho) \\ y_{k+1} &amp;= y_k + \rho(x_{k+1}-z_{k+1}) \end{align}\] <p>Here, $\rho &gt; 0$ is a stepsize.</p> <h2 id="results">Results</h2> <p>Now we will test the QP version of Lasso, ISTA, FISTA, and ADMM to see which is fastest. To generate the data, I generated a random $A \in \mathbb{R}^{m \times n}$ with $m &lt; n$, then generated a random sparse vector $x_{*}$, and calculated $b=Ax_*$.</p> <p>The stopping criteria for all solver was coming within $0.0001$ of the optimal objective function value.</p> <div class="row mt-3"> <div class="col-sm mt-3 mt-md-0"> <figure> <picture> <source class="responsive-img-srcset" srcset="/assets/img/Ista-Fista-480.webp 480w,/assets/img/Ista-Fista-800.webp 800w,/assets/img/Ista-Fista-1400.webp 1400w," type="image/webp" sizes="95vw"/> <img src="/assets/img/Ista-Fista.png" class="img-fluid rounded z-depth-1" width="100%" height="auto" loading="lazy" onerror="this.onerror=null; document.querySelectorAll('.responsive-img-srcset').forEach(function (n) { n.remove(); });"/> </picture> </figure> </div> <div class="col-sm mt-3 mt-md-0"> <figure> <picture> <source class="responsive-img-srcset" srcset="/assets/img/ADMM-480.webp 480w,/assets/img/ADMM-800.webp 800w,/assets/img/ADMM-1400.webp 1400w," type="image/webp" sizes="95vw"/> <img src="/assets/img/ADMM.png" class="img-fluid rounded z-depth-1" width="100%" height="auto" loading="lazy" onerror="this.onerror=null; document.querySelectorAll('.responsive-img-srcset').forEach(function (n) { n.remove(); });"/> </picture> </figure> </div> </div> <div class="caption"> Convergence of ISTA, FISTA, and ADMM with varying stepsizes </div> <table> <thead> <tr> <th>Algorithm</th> <th>Solve Time (sec)</th> </tr> </thead> <tbody> <tr> <td>ADMM (rho=50)</td> <td>0.197</td> </tr> <tr> <td>ADMM (rho=100)</td> <td>0.202</td> </tr> <tr> <td>ADMM (rho=10)</td> <td>1.097</td> </tr> <tr> <td>FISTA</td> <td>1.652</td> </tr> <tr> <td>OSQP</td> <td>2.271</td> </tr> <tr> <td>ISTA</td> <td>8.880</td> </tr> </tbody> </table> <p>It should be mentioned that the ISTA, FISTA, and ADMM implementations are quite naive and unoptimized, but the OSQP solver is written is pure C. The slowest algorithm by far is ISTA followed by reformulating Lasso as a QP and using OSQP, followed by FISTA, and the fastest algorithm was ADMM. The code to generate the plots can be found <a href="https://github.com/govindchari/blog-code/tree/main/lasso">here</a>.</p> <hr/>]]></content><author><name>Govind Chari</name></author><category term="optimization"/><summary type="html"><![CDATA[Comparing optimization algorithms for Lasso]]></summary></entry><entry><title type="html">Hypothesis Testing</title><link href="https://govindchari.com/blog/2023/hypo/" rel="alternate" type="text/html" title="Hypothesis Testing"/><published>2023-09-01T00:00:00+00:00</published><updated>2023-09-01T00:00:00+00:00</updated><id>https://govindchari.com/blog/2023/hypo</id><content type="html" xml:base="https://govindchari.com/blog/2023/hypo/"><![CDATA[<h2 id="introduction">Introduction</h2> <p>Lets say you flip a coin ten times and it comes up heads six out of ten times. Would you think this coin is biased? Probably not.</p> <p>Now lets say you flip a coin a thousand times and it comes up heads six hundred times. You would probably think it is biased. But why?</p> <p>In both cases the coin comes up heads 60% of the time. How can we quantify our intuition here? We will turn to the world of hypothesis testing to answer this question.</p> <h2 id="null-and-alternative-hypothesis">Null and Alternative Hypothesis</h2> <p>The null hypothesis is the statement we are trying develop evidence against and the alternative hypothesis is its complement.</p> <p>Here our null hypothesis is that the coin is fair. The alternative hypothesis is that the coin is biased.</p> <h2 id="p-value">P-Value</h2> <p>One useful question for us to ask is what is the chance that we see an event this or more extreme due to random chance assuming the coin where unbiased?</p> <p>The statistical term for this is p-value.</p> <p>If our p-value is small it means that it is unlikely that we see six hundred heads out of one thousand flips coming up heads if the coin were fair. So a smaller p-value would make us conclude that the coin is indeed biased.</p> <h2 id="level-of-significance">Level of Significance</h2> <p>But how small of a p-value is small enough for us to conclude the coin is biased? In statistics, this value is called $\alpha$ and a typical value for $\alpha$ is 0.05. But what does this $\alpha$ really mean?</p> <p>It is the chance that we conclude that the coin is biased when in reality it isn’t. This kind of error is called type I error.</p> <p>So if $p &lt; 0.05$ then we will conclude that the coin is biased, and we know there is a 5% chance that we conclude the coin is biased when in reality it is not.</p> <h2 id="example">Example</h2> <p>Let’s dig into the math of computing p-values. By definition, the p-value is the chance that we see six hundred or more heads out of a thousand flips assuming the coin where unbiased.</p> <p>Let $X$ be a <a href="https://en.wikipedia.org/wiki/Bernoulli_distribution">Bernoulli</a> random variable. If $X=0$ then the coin landed on tails, and if $X=1$ the coin landed on heads. Since we are assuming the coin is unbiased we can write the probability mass function, expected value, and variance of $X$ as follows</p> \[\mathbb{P}[X=0] = 0.5\] \[\mathbb{P}[X=1] = 0.5\] \[\mathbb{E}[X] = 0.5\] \[\mathbb{V}[X] = 0.25\] <p>The number of heads that we get is the sum of X from 1 to a thousand. We will define this new random variable as $H$. We can write its expected value and variance as follows</p> \[\mathbb{E}[H] = 500\] \[\mathbb{V}[H] = 250\] <p>Since H is the sum of a large number of independent and identically distrubuted random variables, we can use the <a href="https://www.youtube.com/watch?v=zeJD6dqJ5lo&amp;ab_channel=3Blue1Brown">central limit theorem</a> to conclude that in addition to having the expected value and variance written above we know that $H$ is normally distributed. We can then calculate the <a href="https://en.wikipedia.org/wiki/Standard_score">z-score</a> of flipping 6 million heads as follows:</p> \[z = \frac{x-\mu}{\sigma} = \frac{600 - \mathbb{E}[H]}{\sqrt{\mathbb{V}[H]}} \approx 6.32\] <p>To get the p-value from the z-score we use the standard gaussian cumulative density function as follows:</p> \[p = 2(1 - \phi(z)) \approx 2 \times 10^{-10}\] <p>This p-value is less than 0.05 so we can conclude that the coin is biased.</p> <h2 id="code">Code</h2> <p>Below is some Julia code that conducts a hypothesis test for a coin flip example. The input parameters are the number of heads and the number of coin flips. The source file can be found <a href="https://github.com/govindchari/blog-code/blob/main/statistics/hypothesis_testing.jl">here</a>. I encourage you to play around with the number of heads and total number of flips to get an intuition for what is statistically significant and what isn’t.</p> <figure class="highlight"><pre><code class="language-julia" data-lang="julia"><span class="k">using</span> <span class="n">Distributions</span>

<span class="c"># Input Parameters</span>

<span class="n">num_heads</span> <span class="o">=</span> <span class="mi">60</span>
<span class="n">num_flips</span> <span class="o">=</span> <span class="mi">100</span>
<span class="nd">@assert</span> <span class="n">num_heads</span> <span class="o">&lt;=</span> <span class="n">num_flips</span> <span class="s">"Number of heads must be less than or equal to the number of flips"</span>

<span class="n">alpha</span> <span class="o">=</span> <span class="mf">0.05</span> <span class="c"># Significance level</span>

<span class="c"># Mean and variance of number of heads if the coin were unbiased</span>

<span class="n">mu</span> <span class="o">=</span> <span class="mf">0.5</span> <span class="n">_</span> <span class="n">num_flips</span>
<span class="n">var</span> <span class="o">=</span> <span class="mf">0.25</span> <span class="n">_</span> <span class="n">num_flips</span>

<span class="c"># Z-Score of our observation of num_heads</span>

<span class="n">z</span> <span class="o">=</span> <span class="x">(</span><span class="n">num_heads</span> <span class="o">-</span> <span class="n">mu</span><span class="x">)</span> <span class="o">/</span> <span class="n">sqrt</span><span class="x">(</span><span class="n">var</span><span class="x">)</span>

<span class="c"># Compute p-value</span>

<span class="n">p</span> <span class="o">=</span> <span class="mi">2</span> <span class="o">\*</span> <span class="x">(</span><span class="mi">1</span> <span class="o">-</span> <span class="n">cdf</span><span class="x">(</span><span class="n">Normal</span><span class="x">(),</span> <span class="n">abs</span><span class="x">(</span><span class="n">z</span><span class="x">)))</span>

<span class="n">println</span><span class="x">(</span><span class="s">"p-value: "</span><span class="x">,</span> <span class="n">p</span><span class="x">)</span>
<span class="k">if</span> <span class="x">(</span><span class="n">p</span> <span class="o">&lt;</span> <span class="n">alpha</span><span class="x">)</span>
<span class="n">println</span><span class="x">(</span><span class="s">"p &lt; 0.05 so we can reject the null hypothesis and conclude the coin is biased"</span><span class="x">)</span>
<span class="k">else</span>
<span class="n">println</span><span class="x">(</span><span class="s">"p &gt; 0.05 so we cannot reject the null hypothesis and we cannot conclude that the coin is biased"</span><span class="x">)</span>
<span class="k">end</span></code></pre></figure> <hr/>]]></content><author><name>Govind Chari</name></author><category term="statistics"/><summary type="html"><![CDATA[Testing for statistical significance]]></summary></entry><entry><title type="html">Convex Solvers</title><link href="https://govindchari.com/blog/2023/optimization-algorithms/" rel="alternate" type="text/html" title="Convex Solvers"/><published>2023-02-03T00:00:00+00:00</published><updated>2023-02-03T00:00:00+00:00</updated><id>https://govindchari.com/blog/2023/optimization-algorithms</id><content type="html" xml:base="https://govindchari.com/blog/2023/optimization-algorithms/"><![CDATA[<h2 id="introduction">Introduction</h2> <p>Convex optimization is a class of optimization concerned with minimizing a convex function over a convex set. One important feature of convex optimization is that any local minimum for a convex problem is the global minimum, this means that the global minimum can be found very quickly. Mathamatically, a convex problem can be written as follows</p> \[\begin{align*} \min_{x} &amp; \; f(x) \\ \textrm{s.t.} &amp; \; h_{i}(x) = 0, \quad i = 1, \ldots, m \\ &amp; \; g_{i}(x) \leq 0, \quad i = 1, \ldots, p \end{align*}\] <p>where $x \in \mathbb{R}^n$ is the optimization variable, $f(x)$ is a convex objective function, $h_{i}(x)=0$ are affine equality constraints, and $g_{i}(x) \leq 0$ are convex inequality constraints.</p> <p>This post focuses on stressing the intuition of different classes of convex solver and provides references for further reading at the end of each section.</p> <hr/> <h2 id="active-set-methods">Active Set Methods</h2> <p>A constraint is said to be active at a point $x_0$ if $g_i(x_0) = 0$. We can define the optimal active set as the set of all constraints that are active at the optimal solution $x^*$. We can see that all the equality constraints will be in the optimal active set.</p> <p>Active set methods take advantage of the fact that equality constrainted problems are easier to solve than inequality constrainted problems. These methods start with a guess of the optimal active set and solve this equality constrained subproblem. Then it uses information from the solution of the subproblem, for example the sign of the dual variables, to add and remove constraints from the current guess of the active set.</p> <p>If a good guess of the optimal active set is known, these methods can be be very fast and only take a handful of iterations. As a result these methods warmstart well and would be advantageous in applications like model predictive control since it is is unlikely that the optimal active set drastically changes between two solves.</p> <p>The disadvantage of active set methods is that the theoretical worst-case runtime is exponential in the number of constraints since in the worst case, all combinations of constraints must be tested.</p> <p>One famous example of an active set algorithm is Simplex, which was invented by George Dantzig for Linear Programs (LPs). In Simplex, all iterates are vertices of the feasible set (which is a polytope), however this is not the case for quadratic programs (QPs) or any more complex optimization problem. Another active set solver is <a href="https://github.com/coin-or/qpOASES">qpOASES</a>.</p> <p>Each iteration of an active set method for QPs solves an equality constrained QP. Now we will see how equality constrained QPs can be solved in a simple way. For equality constrained QPs, the KKT conditions which are necessary and sufficient conditions for optimality are linear and thus they can be solved in one Newton step. We can write the equality constrained QP as follows where $Q&gt;0$.</p> \[\begin{align*} \min_{x} &amp; \; \frac{1}{2}x^\top Qx + q^\top x \\ \textrm{s.t.} &amp; \; Ax=b\\ \end{align*}\] <p>we can write the KKT conditions for this problem as follows, where $\lambda$ is a vector of dual variables</p> \[\begin{align*} Qx+q+A^\top \lambda &amp;= 0 \\ Ax-b &amp;= 0 \end{align*}\] <p>We can see that this system of equations is linear in the primal and dual variables so we can find the optimal primal and dual solution by solving the following system of equations</p> \[\begin{bmatrix} Q &amp; A^\top \\ A &amp; 0 \end{bmatrix} \begin{bmatrix} x \\ \lambda \end{bmatrix} = \begin{bmatrix} -q \\ b \end{bmatrix}\] <p>Thus we can see that solving the equality constrained quadratic program amounts to nothing more than solving a linear system.</p> <p>To learn more about the details of active set methods reference Chapter 16 Section 5 of <em>Numerical Optimization</em> by Nocedal and Wright.</p> <hr/> <h2 id="interior-point-methods-ipms">Interior Point Methods (IPMs)</h2> <p>As the name suggests, interior point methods solve optimization problems in a way that the iterates lie in the interior of the feasible set. There are two main variants of IPMs: primal and primal-dual. In primal IPMs, we only compute iterates of the primal variables, and in primal-dual IPMs we compute iterates of both the primal and dual variables.</p> <p>Primal IPMs make use of the fact that the following two problems are equivalent:</p> \[\begin{align*} \min_{x} &amp; \; f(x) \\ \textrm{s.t.} &amp; \; x \in \mathcal{D}\\ \end{align*}\] <p>where $\mathcal{D}$ is some convex set and</p> \[\begin{align*} \min_{x} &amp; \; f(x) + \mathcal{I}_{\mathcal{D}}(x)\\ \end{align*}\] <p>where $\mathcal{I}_{\mathcal{D}}(x)$ is the indicator function on $\mathcal{D}$ which is defined as</p> \[\mathcal{I}_{\mathcal{D}}(x) = \begin{cases} 0 &amp; \text{if} \; x \in \mathcal{D} \\ \infty &amp; \text{if} \; x \notin \mathcal{D} \end{cases}\] <p>However, we cannot directly solve the minimization problem with the indicator function since it is nonsmooth at the boundary of the set $\mathcal{D}$, since it jumps from some finite value to infinity. This primal IPMs seek to replace the indicator function with a smooth approximation called a log-barrier function. This log-barrier function is roughly zero when $x \in \mathcal{D}$ and steeply approches infinity when you approach the boundary of $\mathcal{D}$.</p> <p>This steepness is controlled by a “barrier parameter.” The steeper the barrier function is, the better it approximates the indicator function, but the less smooth and worse conditioned the minimization becomes. Initially the unconstrained problem is solved with a shallow barrier parameter and then is successively solved with steeper and steeper barrier parameters. This barrier can be thought of as a force-field that pushes the iterates away from the boundary of the feasible set and amount that this force field pushes the iterates is controlled by the barrier paramter.</p> <p>Primal-Dual IPMs take a slightly different approach. They attempt to use Newton’s method on the KKT conditions of the problem with some other fancy tricks such as taking a prediction step then a correction step which allows the algorithm to reuse the factorization of the KKT matrix. This famed trick is called Mehrotra’s Predictor-Corrector. The Primal Dual IPM is famously used by SpaceX in their rocket landing algorithm <d-cite key="Blackmore2016Autonomous"></d-cite>, <d-cite key="Mattingley2011CVXGEN"></d-cite>.</p> <p>One large drawback to using IPMs in real-time systems is the fact that they cannot be warmstarted which is a desirable property of real-time solvers.</p> <p>One example of an IPM is <a href="https://github.com/embotech/ecos">ECOS</a>.</p> <p>To learn more about primal IPMs reference Chapter 11 in <em>Convex Optimization</em> by Boyd and Vanderberghe and to learn more about primal-dual IPMs reference Chapter 14 and Chapter 16 Section 6 in Nocedal and Wright.</p> <hr/> <h2 id="first-order-methods">First-Order Methods</h2> <p>Both Active Set methods and IPMs typically rely on “second-order” information. Second order information is the information about the curvature of a function which is given by its second derivative, or for the multivariable case its Hessian. Using second order information allows these methods to converge quickly in few iterations, but each iteration requires the factorization of a large matrix which is a very expensive operation.</p> <p>The number of floating point operations for matrix factorization scales with $\mathcal{O}(n^3)$ and storing the Hessian scales with $\mathcal{O}(n^2)$ where $n$ is the number of variables in your problem.</p> <p>First Order methods on the other hand only use first-order information, which is information about the slope of a function which is given by its first derivative, or gradient in the multivariable case. First-order methods do not require matrix factorizations at each iteration and only require Matrix-vector multiplications. The number of floating point operations for matrix-vector multiplication scales with $\mathcal{O}(n^2)$, thus each iteration of a first-order method can be done quicker than an iteration of a second order method, but first order methods require more iterations to converge, since each iteration uses less information.</p> <p>First order methods are more or less gradient descent algorithms with some modifications to handle constraints such as projections. For extremely large scale problems first order methods are preferable due to the high cost of factorizing and storing large matrices.</p> <p>All of this performance of first order methods does have some drawbacks. First order methods are extremely sensitive to ill conditioned objectives and badly scaled problem data. Thus an extrememly fast and robust implementation of a first-order method must scale and precondition the problem data.</p> <p>Some examples of first order solvers are <a href="https://osqp.org/">OSQP</a> and <a href="https://github.com/cvxgrp/scs">SCS</a>.</p> <h2 id="summary">Summary</h2> <p>Here we will quickly sumamrize the advantages and disadvantages of each method.</p> <p><strong>Active Set</strong></p> <p>Advantages: Easy to warmstart, fast if you have a good guess for the active set</p> <p>Disadvantages: Worse case exponential runtime in the number of constraints, bad for large problems</p> <p><strong>IPMs</strong></p> <p>Advantages: Fast and robust for medium sized problems</p> <p>Disadvantages: Bad for large problems, cannot warmstart, large code footprint</p> <p><strong>First-Order</strong></p> <p>Advantages: Small code footprint, good for large problems, can be good for medium sized problems with customization, ease of customization, easy to warmstart</p> <p>Disadvantages: Highly sensitive to scaling and conditioning so they need scaling and preconditioning</p> <hr/>]]></content><author><name>Govind Chari</name></author><category term="optimization"/><summary type="html"><![CDATA[A survey of the different classes of solvers for convex optimization problems]]></summary></entry></feed>