<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Julia Community 🟣: lucaferranti</title>
    <description>The latest articles on Julia Community 🟣 by lucaferranti (@lucaferranti).</description>
    <link>https://forem.julialang.org/lucaferranti</link>
    <image>
      <url>https://forem.julialang.org/images/nX4jsgM37KypLeAEiOyw0iRwsRMVXq1Q8_Q1rw2paUU/rs:fill:90:90/g:sm/mb:500000/ar:1/aHR0cHM6Ly9mb3Jl/bS5qdWxpYWxhbmcu/b3JnL3JlbW90ZWlt/YWdlcy91cGxvYWRz/L3VzZXIvcHJvZmls/ZV9pbWFnZS84Ni85/YzRlN2YwOC0zMDAy/LTRjYjMtOWRmMy0w/OTlkODJjMzE0NjQu/anBlZw</url>
      <title>Julia Community 🟣: lucaferranti</title>
      <link>https://forem.julialang.org/lucaferranti</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.julialang.org/feed/lucaferranti"/>
    <language>en</language>
    <item>
      <title>GSoC 2022 -- Sparse Polynomial Zonotopes in JuliaReach</title>
      <dc:creator>lucaferranti</dc:creator>
      <pubDate>Mon, 12 Sep 2022 13:30:16 +0000</pubDate>
      <link>https://forem.julialang.org/lucaferranti/gsoc-2022-sparse-polynomial-zonotopes-in-juliareach-52mo</link>
      <guid>https://forem.julialang.org/lucaferranti/gsoc-2022-sparse-polynomial-zonotopes-in-juliareach-52mo</guid>
      <description>&lt;p&gt;Hi there,&lt;/p&gt;

&lt;p&gt;My Google Summer of Code (GSoC) journey has (again) come to an end, so here are some highlights.&lt;/p&gt;

&lt;h2&gt;
  
  
  whoami
&lt;/h2&gt;

&lt;p&gt;I participated in GSoC already last year, working on &lt;a href="https://github.com/JuliaIntervals/IntervalLinearAlgebra.jl"&gt;IntervalLinearAlgebra.jl&lt;/a&gt; with David Sanders and Marcelo Forets as my mentors.&lt;/p&gt;

&lt;p&gt;Given the experience was very positive, I decided this year to participate again. Given my interest in scientific computing and particularly rigorous computations, I ended up working in the &lt;a href="https://github.com/juliareach"&gt;JuliaReach&lt;/a&gt; organization with mentors &lt;a href="https://github.com/mforets"&gt;Marcelo Forets&lt;/a&gt; and &lt;a href="https://github.com/schillic"&gt;Christian Schilling&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The goals
&lt;/h2&gt;

&lt;p&gt;Before getting into the nerdy parts, let's put some numbers on the table. My main goals for GSoC were mainly two-folded&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;implement sparse polynomial zonotopes in LazySets.jl and reachability algorithms using those.&lt;/li&gt;
&lt;li&gt;Revamp &lt;a href="https://github.com/juliareach/RangeEnclosures.jl"&gt;RangeEnclosures.jl&lt;/a&gt;, to make it a working and useful package.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At the time of writing, I had 41 merged PRs related to GSoC. More details for each subgoal. I also had a JuliaCon talk and with Marcelo and Christian we are going to submit an extended abstract to the JuliaCon proceedings. Now let's dive into more details.&lt;/p&gt;

&lt;h3&gt;
  
  
  RangeEnclosures.jl
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/juliareach/RangeEnclosures.jl"&gt;RangeEnclosures.jl&lt;/a&gt; is a package to rigorously bound function ranges. That is if you have a function 

&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;f:Rn→Rf : \mathbf{R}^n\rightarrow\mathbf{R} &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;:&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathbf"&gt;R&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;→&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathbf"&gt;R&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 and you want to evaluate the function over a rectangle domain 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;X⊆RnX \subseteq \mathbf{R}^n&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;X&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;⊆&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathbf"&gt;R&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 you want to compute an interval 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;Y⊇f(X)Y\supseteq f(X)&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;Y&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;⊇&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;X&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
. The following pictures give a visualization of the range bounding concept.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://forem.julialang.org/images/ZMZAkdOQMUH2V_kEGBYJLYE5ySZ4tAr-gWRX0CfcsoA/w:880/mb:500000/ar:1/aHR0cHM6Ly9mb3Jl/bS5qdWxpYWxhbmcu/b3JnL3JlbW90ZWlt/YWdlcy91cGxvYWRz/L2FydGljbGVzL2J5/MGZzcTIyOHBwMW9r/bHdkNW9qLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://forem.julialang.org/images/ZMZAkdOQMUH2V_kEGBYJLYE5ySZ4tAr-gWRX0CfcsoA/w:880/mb:500000/ar:1/aHR0cHM6Ly9mb3Jl/bS5qdWxpYWxhbmcu/b3JnL3JlbW90ZWlt/YWdlcy91cGxvYWRz/L2FydGljbGVzL2J5/MGZzcTIyOHBwMW9r/bHdkNW9qLnBuZw" alt="Image description" width="596" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you may be wondering, isn't this what interval arithmetic does? Do you need a whole package for it? The answer is yes and no. It is true that interval arithmetic (assuming it's properly implemented) will give you a rigorous enclosure. That is, opening a Julia REPL and evaluating the function with &lt;a href="https://github.com/JuliaIntervals/IntervalArithmetic.jl"&gt;IntervalArithmetic.jl&lt;/a&gt; will give you an interval which is probably &lt;em&gt;bigger&lt;/em&gt; than the true range. Observe the following picture, where the function 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;f(x)=x2−2x+1f(x) = x^2 - 2x + 1&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 is evaluated with interval arithmetic.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://forem.julialang.org/images/ACOGyrrstmeJlNehafZtKmkBwJ2ylOfMvGQtFUyUQhc/w:880/mb:500000/ar:1/aHR0cHM6Ly9mb3Jl/bS5qdWxpYWxhbmcu/b3JnL3JlbW90ZWlt/YWdlcy91cGxvYWRz/L2FydGljbGVzL2Q4/eTdicDlmNzIxc3A5/bjdnemFkLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://forem.julialang.org/images/ACOGyrrstmeJlNehafZtKmkBwJ2ylOfMvGQtFUyUQhc/w:880/mb:500000/ar:1/aHR0cHM6Ly9mb3Jl/bS5qdWxpYWxhbmcu/b3JnL3JlbW90ZWlt/YWdlcy91cGxvYWRz/L2FydGljbGVzL2Q4/eTdicDlmNzIxc3A5/bjdnemFkLnBuZw" alt="Image description" width="600" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why? Because interval arithmetic suffers from the so called &lt;em&gt;dependency problem&lt;/em&gt;, which means that if your expression has the same variable repeated multiple times, then evaluating it with interval arithmetic will most likely introduce some overestimation.&lt;/p&gt;

&lt;p&gt;So now the question is: how do you compute the range? The answer is: &lt;strong&gt;there is not one solution&lt;/strong&gt;. There are several approaches, each one with its pros and cons&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Evaluate with interval arithmetic: this is good for simple functions and fast. But it is not recommended if you need tight enclosures.&lt;/li&gt;
&lt;li&gt;Use affine arithmetic: this makes the dependency problem milder, but can be worse for wider intervals&lt;/li&gt;
&lt;li&gt;Solve two global optimization problems: find the global maximum and global minimum, that gives you the range.&lt;/li&gt;
&lt;li&gt;Branch and bound: recursively split the domain into subdomains and evaluate on each subdomain until some ending condition is met, then take the union of all intervals&lt;/li&gt;
&lt;li&gt;use &lt;a href="https://github.com/JuliaIntervals/TaylorModels.jl"&gt;TaylorModels.jl&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;this is why we created RangeEnclosures.jl, it does not give you one method, but it is a flexible API that allows you to easily choose what approach you want to use in your application. It has some built-in algorithms, so it is battery included, but it also integrates algorithms implemented in different packages.&lt;/p&gt;

&lt;p&gt;If you want to know more, check out the &lt;a href="https://juliareach.github.io/RangeEnclosures.jl/dev/"&gt;package documentation&lt;/a&gt; and/or my talk at JuliaCon.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/hMIwqoLj6S8"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;(shameless advertisement: although not related to GSoC, I also gave another talk at JuliaCon about automated theorem proving in Euclidean geometry, check it out &lt;a href="https://youtu.be/q_08LE4UOU8"&gt;here&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Overall, I am pretty satisfied with how the package developed, sure there are still improvements that can be done, but the package should already be usable. If you ever need to bound the range of a function, you know where to go 😃&lt;/p&gt;

&lt;h2&gt;
  
  
  LazySets and Reachability Analysis
&lt;/h2&gt;

&lt;p&gt;Before we go into the second goal, let's have a crash course in reachability analysis.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In one sentence&lt;/strong&gt;: &lt;em&gt;If you don't exactly know where you are at the beginning, reachability analysis tells you where you can possibly be at the end.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now more formally, reachability analysis propagates rigorously uncertainty through dynamical systems. That is, if you know your initial state is in some set 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;X0X_0&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;X&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 and you have a dynamical system 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;f(x,t)f(x, t) &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;x&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
, generally represented by an ordinary differential equation, reachability analysis will give you a set 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;XtX_t&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;X&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;t&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 guaranteed to contain the state of the system at time &lt;em&gt;t&lt;/em&gt;. Again let's have a picture&lt;/p&gt;

&lt;p&gt;&lt;a href="https://forem.julialang.org/images/75mXVpFwRVeRl-y1RDjUyA3_kg3Ia7qstAILitSgaUk/w:880/mb:500000/ar:1/aHR0cHM6Ly9mb3Jl/bS5qdWxpYWxhbmcu/b3JnL3JlbW90ZWlt/YWdlcy91cGxvYWRz/L2FydGljbGVzL2tp/Y3RtbjJhcmQzb2xm/NGQ1dDg5LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://forem.julialang.org/images/75mXVpFwRVeRl-y1RDjUyA3_kg3Ia7qstAILitSgaUk/w:880/mb:500000/ar:1/aHR0cHM6Ly9mb3Jl/bS5qdWxpYWxhbmcu/b3JnL3JlbW90ZWlt/YWdlcy91cGxvYWRz/L2FydGljbGVzL2tp/Y3RtbjJhcmQzb2xm/NGQ1dDg5LnBuZw" alt="Image description" width="786" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The yellow rectangle represent the initial set. You know your initial state is somewhere in that box, but you don't know exactly where. The picture shows the &lt;em&gt;flowpipe&lt;/em&gt; modeling the evolution of the system. If you observe the picture carefully enough, you will notice it is composed by small blue sets, each one giving a set guaranteed to contain the system state at a given time instant.  &lt;/p&gt;

&lt;p&gt;Reachability analysis is a fairly new research area with an active research community. It also has a wide range of applications where safety is critical. For example, robotics and autonomous vehicles. You may not know exactly where your drone is at the beginning, but you still need to make sure it does not hit a tree at any point.&lt;/p&gt;

&lt;p&gt;In Julia, there is &lt;a href="https://github.com/JuliaReach/ReachabilityAnalysis.jl"&gt;ReachabilityAnalysis.jl&lt;/a&gt;, developed by Marcelo and Christian. This is a state-of-the-art library. If you want to learn more, make sure to checkout &lt;a href="https://youtu.be/P4I7pTvQ4nk"&gt;this workshop&lt;/a&gt; from last year JuliaCon.&lt;/p&gt;
&lt;h3&gt;
  
  
  Reachability and interval arithmetic.
&lt;/h3&gt;

&lt;p&gt;Now you may be wondering, can I use interval arithmetic for this? The answer is (again) yes and no. Sure you could only use interval boxes, but this will (again) give huge overestimate. This is mainly for two reasons, the dependency problem we discussed before and the so called &lt;em&gt;wrapping effect&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The idea of the wrapping effect is fairly simple, if you can only use interval boxes (i.e. rectangles) and your set is not a rectangle, then you need to overapproximate that, as the following picture demonstrates.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://forem.julialang.org/images/qfj7N3Mq6Fz-7DatGkjk0XlE_vKJ6ZSR7irXHH8O3Gs/w:880/mb:500000/ar:1/aHR0cHM6Ly9mb3Jl/bS5qdWxpYWxhbmcu/b3JnL3JlbW90ZWlt/YWdlcy91cGxvYWRz/L2FydGljbGVzLzhs/eHozeTY2cG42cDlu/OXE5enJyLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://forem.julialang.org/images/qfj7N3Mq6Fz-7DatGkjk0XlE_vKJ6ZSR7irXHH8O3Gs/w:880/mb:500000/ar:1/aHR0cHM6Ly9mb3Jl/bS5qdWxpYWxhbmcu/b3JnL3JlbW90ZWlt/YWdlcy91cGxvYWRz/L2FydGljbGVzLzhs/eHozeTY2cG42cDlu/OXE5enJyLnBuZw" alt="Image description" width="600" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And now you may be asking, if I use the tightest interval box (called &lt;em&gt;interval hull&lt;/em&gt;), wouldn't that be enough? Maybe, in some applications the interval hull would be enough. The problem is in general you do &lt;em&gt;not&lt;/em&gt; get the interval hull. To understand this, look at the picture above again. You may notice you don't go straight from the initial state to the final one, but you take small steps in the middle. If you overapproximated by an interval box at every step, all these overapproximations would sum up and the final result will be much wider.&lt;/p&gt;
&lt;h3&gt;
  
  
  Beyond intervals: LazySets.jl
&lt;/h3&gt;

&lt;p&gt;So we have seen interval and interval boxes are not accurate enough for reachability analysis. That's where &lt;a href="https://github.com/JuliaReach/LazySets.jl"&gt;LazySets.jl&lt;/a&gt; kicks in! We will not discuss here the &lt;em&gt;lazy&lt;/em&gt; part, if you are interested have a look at this &lt;a href="https://proceedings.juliacon.org/papers/10.21105/jcon.00097"&gt;great paper&lt;/a&gt; from last year JuliaCon proceedings.&lt;/p&gt;

&lt;p&gt;The idea of LazySets.jl is to represent other sets than intervals and compute efficiently operations with them. The following picture gives a quick overview of sets you can represent and manipulate in LazySets.jl&lt;/p&gt;

&lt;p&gt;&lt;a href="https://forem.julialang.org/images/N9vZXgzZ_pi4kDBAXKx7y_86hHbq_DJp7RRey5ZZ8fE/w:880/mb:500000/ar:1/aHR0cHM6Ly9mb3Jl/bS5qdWxpYWxhbmcu/b3JnL3JlbW90ZWlt/YWdlcy91cGxvYWRz/L2FydGljbGVzL3Rk/OTBteG83cDM1cnQ3/bXZhNTAxLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://forem.julialang.org/images/N9vZXgzZ_pi4kDBAXKx7y_86hHbq_DJp7RRey5ZZ8fE/w:880/mb:500000/ar:1/aHR0cHM6Ly9mb3Jl/bS5qdWxpYWxhbmcu/b3JnL3JlbW90ZWlt/YWdlcy91cGxvYWRz/L2FydGljbGVzL3Rk/OTBteG83cDM1cnQ3/bXZhNTAxLnBuZw" alt="Image description" width="512" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using LazySets.jl we are able to get more accurate estimates in ReachabilityAnalysis.jl, for example the picture in the previous paragraph obtained using LazySets.jl and ReachabilityAnalysis.jl&lt;/p&gt;
&lt;h2&gt;
  
  
  Sparse Polynomial Zonotopes
&lt;/h2&gt;

&lt;p&gt;Until recently, LazySets.jl could only represent convex sets. This is a limitation because, similarly to the wrapping effect for intervals, if your set is not convex, you need to overapproximate by a convex set and if you do this at each step of the reachability algorithm the final result might be pretty poor. The following picture visualizes the phenomenon.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://forem.julialang.org/images/Anvl1s-iKNIV-A-IHrwrO3S8hnY2kYSMf96qFK8v7LI/w:880/mb:500000/ar:1/aHR0cHM6Ly9mb3Jl/bS5qdWxpYWxhbmcu/b3JnL3JlbW90ZWlt/YWdlcy91cGxvYWRz/L2FydGljbGVzL3Y1/NGZqNGg1d2Q4aTdt/cHZ3MDZrLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://forem.julialang.org/images/Anvl1s-iKNIV-A-IHrwrO3S8hnY2kYSMf96qFK8v7LI/w:880/mb:500000/ar:1/aHR0cHM6Ly9mb3Jl/bS5qdWxpYWxhbmcu/b3JnL3JlbW90ZWlt/YWdlcy91cGxvYWRz/L2FydGljbGVzL3Y1/NGZqNGg1d2Q4aTdt/cHZ3MDZrLnBuZw" alt="Image description" width="600" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To overcome this limitation, recently &lt;em&gt;Sparse Polynomial Zonotopes&lt;/em&gt; were introduced. They are a novel set representation introduced in [1] that allows to manipulate also non-convex sets.&lt;/p&gt;

&lt;p&gt;Most of my GSoC has been implementing sparse polynomial zonotopes in LazySets.jl. This was a very interesting challenge, because this new set representation and its application to reachability is still an active research area, with several open challenges.&lt;/p&gt;

&lt;p&gt;Roughly speaking, a sparse polynomial zonotope is a set whose coordinates can be parametrized by a multivariate polynomial. The following equation gives an example and the next plot visualizes the set.&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;PZ=[2α1+α2+2α13α22α2+2α13α2],α1,α2∈[−1,1]
PZ={\begin{bmatrix}
&amp;amp;2\alpha_1+\alpha_2+2\alpha_1^3\alpha_2\\&amp;amp;2\alpha_2+2\alpha_1^3\alpha_2
\end{bmatrix},\alpha_1,\alpha_2\in[-1,1]}
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;PZ&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="minner"&gt;&lt;span class="mopen delimcenter"&gt;&lt;span class="delimsizing size3"&gt;[&lt;/span&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mtable"&gt;&lt;span class="col-align-c"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="arraycolsep"&gt;&lt;/span&gt;&lt;span class="arraycolsep"&gt;&lt;/span&gt;&lt;span class="col-align-c"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;α&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;α&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;α&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;α&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;α&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;α&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;α&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose delimcenter"&gt;&lt;span class="delimsizing size3"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;α&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;α&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;∈&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;[&lt;/span&gt;&lt;span class="mord"&gt;−&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mpunct"&gt;,&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;span class="mclose"&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://forem.julialang.org/images/UFRQ3yGkUAPTghgwMSCeLMyaTNGAJxK7NI8-Y8y3qaw/w:880/mb:500000/ar:1/aHR0cHM6Ly9mb3Jl/bS5qdWxpYWxhbmcu/b3JnL3JlbW90ZWlt/YWdlcy91cGxvYWRz/L2FydGljbGVzL3Aw/am1kNzFoOTFrOHM4/M2t5dDl0LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://forem.julialang.org/images/UFRQ3yGkUAPTghgwMSCeLMyaTNGAJxK7NI8-Y8y3qaw/w:880/mb:500000/ar:1/aHR0cHM6Ly9mb3Jl/bS5qdWxpYWxhbmcu/b3JnL3JlbW90ZWlt/YWdlcy91cGxvYWRz/L2FydGljbGVzL3Aw/am1kNzFoOTFrOHM4/M2t5dDl0LnBuZw" alt="Image description" width="600" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;During GSoC, I implemented sparse polynomial zonotopes in two flavours: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;SimpleSparsePolynomialZonotopes&lt;/code&gt;: a simplified version which can be more efficient but lead to wider sets&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SparsePolynomialZonotope&lt;/code&gt;: the "proper" polynomial zonotopes as described in [1].&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also implemented a plotting recipe (which allowed the pictures above) and several set operations. A summary of what has been implemented so far can be found at this &lt;a href="https://github.com/JuliaReach/LazySets.jl/issues/3018"&gt;epic issue&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[1] Kochdumper, Niklas &amp;amp; Althoff, Matthias. (2019). Sparse Polynomial Zonotopes: A Novel Set Representation for Reachability Analysis. &lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
  </channel>
</rss>
