<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>pavel.pink</title><description>My personal blog about software development and other stuff.</description><link>https://pavel.pink/</link><language>en-us</language><item><title>Managing Agent Skills with Your Package Manager</title><link>https://pavel.pink/blog/pixi-skills/</link><guid isPermaLink="true">https://pavel.pink/blog/pixi-skills/</guid><description>AI coding agents use skills — markdown files that teach them domain-specific tasks. We publish ours as conda packages and manage them with pixi, getting versioning, lockfiles, and supply chain security for free.</description><pubDate>Mon, 09 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;AI coding agents like Claude Code can be extended with &lt;em&gt;skills&lt;/em&gt;, markdown files
that contain domain-specific instructions for how to approach certain tasks.
A skill for polars, for example, might teach the agent to prefer lazy evaluation,
use &lt;code&gt;collect&lt;/code&gt; sparingly, and follow specific patterns for joins.&lt;/p&gt;
&lt;p&gt;Skills are just text files. But as your team grows and you accumulate more of them,
managing these text files becomes a real problem.&lt;/p&gt;
&lt;h1 id=&quot;the-state-of-the-art&quot;&gt;&lt;a href=&quot;#the-state-of-the-art&quot;&gt;The state of the art&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;One of the current approaches is &lt;a href=&quot;https://skills.sh&quot;&gt;skills.sh&lt;/a&gt;, a community registry that lets you
fetch skills with a single command:&lt;/p&gt;
&lt;pre class=&quot;astro-code catppuccin-mocha&quot; style=&quot;background-color:#1e1e2e;color:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code class=&quot;code-highlight&quot;&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#89B4FA;font-style:italic&quot;&gt;npx&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; skills&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; add&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; https://github.com/davila7/claude-code-templates&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; --skill&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; polars&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;button class=&quot;copy-btn&quot; aria-label=&quot;Copy code&quot; data-copy-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;rect x=&amp;#34;9&amp;#34; y=&amp;#34;9&amp;#34; width=&amp;#34;13&amp;#34; height=&amp;#34;13&amp;#34; rx=&amp;#34;2&amp;#34; ry=&amp;#34;2&amp;#34;/&gt;&lt;path d=&amp;#34;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&amp;#34;/&gt;&lt;/svg&gt;&quot; data-check-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;polyline points=&amp;#34;20 6 9 17 4 12&amp;#34;/&gt;&lt;/svg&gt;&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;&lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/pre&gt;
&lt;p&gt;This downloads the skill markdown file into your project and you’re done.
Simple and effective for getting started.&lt;/p&gt;
&lt;h2 id=&quot;whats-missing&quot;&gt;&lt;a href=&quot;#whats-missing&quot;&gt;What’s missing&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As soon as skills become part of real workflows, across projects, teams, or corporate environments, a few problems emerge:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Markdown sprawl in git.&lt;/strong&gt; Skills are vendored into your repository. Every
project gets its own copy. Updates mean committing diffs of markdown files
you didn’t write. Your git history fills up with skill updates that have
nothing to do with your project.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;No version pinning.&lt;/strong&gt; &lt;code&gt;npx skills add&lt;/code&gt; fetches from &lt;code&gt;main&lt;/code&gt;. There’s no
lockfile, no version constraint. A skill that worked yesterday might behave
differently today because someone pushed an update upstream. If a skill is
updated to target a new major version of a library, your project breaks
silently and the agent just starts writing code for an API you’re not using.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Enterprise environments.&lt;/strong&gt; In locked-down corporate networks, access to
github.com may be restricted or unavailable. Getting skills
into these environments requires manual workarounds.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Supply chain security.&lt;/strong&gt; Skills are instructions an AI agent follows.
A malicious skill could subtly steer an agent toward specific commercial services, leak information through generated code, or introduce unsafe patterns.
You might install a polars skill that injects adversarial context: the &lt;a href=&quot;https://github.com/K-Dense-AI/claude-scientific-skills/blob/3a5f2e2227d64679bbe998acfea53007102b4d94/scientific-skills/polars/SKILL.md?plain=1#L386-L387&quot;&gt;&lt;code&gt;K-Dense-AI/claude-scientific-skills&lt;/code&gt; polars skill&lt;/a&gt; does just that!
Skills can also &lt;a href=&quot;https://www.aikido.dev/blog/agent-skills-spreading-hallucinated-npx-commands&quot;&gt;spread hallucinated package names&lt;/a&gt;: an LLM-generated skill referenced a non-existent npm package, got copy-pasted across 200+ repositories, and agents started trying to install it, creating a supply chain attack vector.
A mature packaging ecosystem is a possible way to mitigate some of these problems.
It might offer well-defined release processes, auditability and change history to be able to track changes and ensure integrity.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These are not hypothetical problems. These are exactly the problems software package management solved decades ago.&lt;/p&gt;
&lt;h1 id=&quot;skills-as-packages&quot;&gt;&lt;a href=&quot;#skills-as-packages&quot;&gt;Skills as packages&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Turns out: skills are text files. Software packages exist to distribute text files. Package managers already handle versioning, locking, distribution, and security. So why not ship skills as packages?&lt;/p&gt;
&lt;p&gt;We use &lt;a href=&quot;https://pixi.sh&quot;&gt;pixi&lt;/a&gt; for dependency management across our projects. Since pixi is built on
the conda ecosystem and is language-agnostic, it can manage any kind of package,
including ones that just contain markdown files.&lt;/p&gt;
&lt;h2 id=&quot;creating-a-skill-package&quot;&gt;&lt;a href=&quot;#creating-a-skill-package&quot;&gt;Creating a skill package&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A conda package for a skill is straightforward. Here’s a &lt;code&gt;recipe.yaml&lt;/code&gt; for a
polars skill:&lt;/p&gt;
&lt;pre class=&quot;astro-code catppuccin-mocha&quot; style=&quot;background-color:#1e1e2e;color:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;yaml&quot;&gt;&lt;code class=&quot;code-highlight&quot;&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;schema_version&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;package&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;  name&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; agent-skill-polars&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;  version&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; &amp;quot;0.2.0&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;build&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;  noarch&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; generic&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;  script&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;    -&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; mkdir -p $PREFIX/share/agent-skills/polars&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;    -&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; cp $RECIPE_DIR/SKILL.md $PREFIX/share/agent-skills/polars/&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;    -&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; cp -R $RECIPE_DIR/references $PREFIX/share/agent-skills/polars/&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;requirements&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;  run_constraints&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;    -&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; polars &amp;gt;=1.38.0,&amp;lt;2.0&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;about&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;  summary&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; Agent skill for writing polars code&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;  license&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; MIT&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;button class=&quot;copy-btn&quot; aria-label=&quot;Copy code&quot; data-copy-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;rect x=&amp;#34;9&amp;#34; y=&amp;#34;9&amp;#34; width=&amp;#34;13&amp;#34; height=&amp;#34;13&amp;#34; rx=&amp;#34;2&amp;#34; ry=&amp;#34;2&amp;#34;/&gt;&lt;path d=&amp;#34;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&amp;#34;/&gt;&lt;/svg&gt;&quot; data-check-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;polyline points=&amp;#34;20 6 9 17 4 12&amp;#34;/&gt;&lt;/svg&gt;&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;&lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code catppuccin-mocha&quot; style=&quot;background-color:#1e1e2e;color:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code class=&quot;code-highlight&quot;&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;$CONDA_PREFIX/share/agent-skills/polars&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;├── references&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   ├── best_practices.md&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   ├── ...&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   └── transformations&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;└── SKILL.md&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;noarch: generic&lt;/code&gt; build means this package is platform-independent — it’s
just markdown files. The skill files get installed to &lt;code&gt;share/agent-skills/&lt;/code&gt;
in the conda prefix.&lt;/p&gt;
&lt;p&gt;The interesting part is &lt;code&gt;run_constraints&lt;/code&gt;. This tells the solver: &lt;em&gt;if&lt;/em&gt; polars
is installed in this environment, it must be &lt;code&gt;&amp;gt;=1.38.0,&amp;lt;2.0&lt;/code&gt;. The skill package
doesn’t pull in polars as a dependency, but it ensures that the skill matches
the version of the library you’re actually using. If you’re on polars 0.x,
the solver will refuse to install this skill: you’d need &lt;code&gt;agent-skill-polars&lt;/code&gt; of a different version targeting the older API instead.&lt;/p&gt;
&lt;h3 id=&quot;do-it-yourself&quot;&gt;&lt;a href=&quot;#do-it-yourself&quot;&gt;Do it yourself&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;You can ship your own skills! Here is a prompt for your favorite agent that can be used to create a skill.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I would like to create a skill for &lt;code&gt;scikit-learn&lt;/code&gt;. Do it in the same way as described in &lt;code&gt;https://github.com/pavelzw/skill-forge/blob/main/AGENTS.md&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;installing-skills&quot;&gt;&lt;a href=&quot;#installing-skills&quot;&gt;Installing skills&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Adding skills to a project is now just a pixi dependency:&lt;/p&gt;
&lt;pre class=&quot;astro-code catppuccin-mocha&quot; style=&quot;background-color:#1e1e2e;color:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;toml&quot; data-title=&quot;pixi.toml&quot;&gt;&lt;code class=&quot;code-highlight&quot;&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;workspace&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;channels &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;quot;conda-forge&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; &amp;quot;https://prefix.dev/skill-forge&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;platforms &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;quot;linux-64&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; &amp;quot;osx-arm64&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; &amp;quot;win-64&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;dependencies&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;polars &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; &amp;quot;&amp;gt;=1,&amp;lt;2&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;agent-skill-polars &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; &amp;quot;*&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;button class=&quot;copy-btn&quot; aria-label=&quot;Copy code&quot; data-copy-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;rect x=&amp;#34;9&amp;#34; y=&amp;#34;9&amp;#34; width=&amp;#34;13&amp;#34; height=&amp;#34;13&amp;#34; rx=&amp;#34;2&amp;#34; ry=&amp;#34;2&amp;#34;/&gt;&lt;path d=&amp;#34;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&amp;#34;/&gt;&lt;/svg&gt;&quot; data-check-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;polyline points=&amp;#34;20 6 9 17 4 12&amp;#34;/&gt;&lt;/svg&gt;&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;&lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code catppuccin-mocha&quot; style=&quot;background-color:#1e1e2e;color:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code class=&quot;code-highlight&quot;&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#89B4FA;font-style:italic&quot;&gt;pixi&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; install&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;button class=&quot;copy-btn&quot; aria-label=&quot;Copy code&quot; data-copy-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;rect x=&amp;#34;9&amp;#34; y=&amp;#34;9&amp;#34; width=&amp;#34;13&amp;#34; height=&amp;#34;13&amp;#34; rx=&amp;#34;2&amp;#34; ry=&amp;#34;2&amp;#34;/&gt;&lt;path d=&amp;#34;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&amp;#34;/&gt;&lt;/svg&gt;&quot; data-check-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;polyline points=&amp;#34;20 6 9 17 4 12&amp;#34;/&gt;&lt;/svg&gt;&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;&lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/pre&gt;
&lt;p&gt;The skill version is pinned in &lt;code&gt;pixi.lock&lt;/code&gt; alongside all your other dependencies.
It is reproducible across machines and across time.&lt;/p&gt;
&lt;p&gt;We maintain a set of pre-packaged skills on the conda channel &lt;a href=&quot;https://prefix.dev/channels/skill-forge&quot;&gt;prefix.dev/skill-forge&lt;/a&gt;.
As mentioned above, skills can lead to arbitrary code execution, so please always read through them before using them.&lt;/p&gt;
&lt;h2 id=&quot;pixi-skills-connecting-skills-to-your-agent&quot;&gt;&lt;a href=&quot;#pixi-skills-connecting-skills-to-your-agent&quot;&gt;&lt;code&gt;pixi-skills&lt;/code&gt;: connecting skills to your agent&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Installed packages end up in &lt;code&gt;.pixi/envs/default/&lt;/code&gt;. My friend &lt;a href=&quot;https://moritzwilksch.de&quot;&gt;Moritz&lt;/a&gt; and I wrote a small tool (&lt;a href=&quot;https://github.com/pavelzw/pixi-skills&quot;&gt;pavelzw/pixi-skills&lt;/a&gt;) that can symlink the skill files from there to wherever your agent expects them:&lt;/p&gt;
&lt;pre class=&quot;astro-code catppuccin-mocha&quot; style=&quot;background-color:#1e1e2e;color:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code class=&quot;code-highlight&quot;&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#89B4FA;font-style:italic&quot;&gt;pixi&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; exec&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; pixi-skills&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; manage&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;button class=&quot;copy-btn&quot; aria-label=&quot;Copy code&quot; data-copy-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;rect x=&amp;#34;9&amp;#34; y=&amp;#34;9&amp;#34; width=&amp;#34;13&amp;#34; height=&amp;#34;13&amp;#34; rx=&amp;#34;2&amp;#34; ry=&amp;#34;2&amp;#34;/&gt;&lt;path d=&amp;#34;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&amp;#34;/&gt;&lt;/svg&gt;&quot; data-check-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;polyline points=&amp;#34;20 6 9 17 4 12&amp;#34;/&gt;&lt;/svg&gt;&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;&lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/pre&gt;
&lt;p&gt;This scans the installed packages for files under &lt;code&gt;share/agent-skills/&lt;/code&gt; and
symlinks them into your project’s skill directory. The tool is trivial because the heavy lifting is done by the package manager.&lt;/p&gt;
&lt;h2 id=&quot;what-this-gets-us&quot;&gt;&lt;a href=&quot;#what-this-gets-us&quot;&gt;What this gets us&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;No markdown bloat in git.&lt;/strong&gt; Skills are installed dependencies, not vendored files.
Your &lt;code&gt;.gitignore&lt;/code&gt; covers the &lt;code&gt;.pixi/&lt;/code&gt; directory and skill symlinks, so you stop committing other people’s markdown.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Versions are pinned.&lt;/strong&gt; &lt;code&gt;pixi.lock&lt;/code&gt; pins the exact skill version, just like
any other dependency. Updates are intentional — you run &lt;code&gt;pixi update agent-skill-polars&lt;/code&gt;
when you’re ready. And with &lt;code&gt;run_constraints&lt;/code&gt;, a skill can express compatibility
with the library it targets.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Enterprise distribution works.&lt;/strong&gt; You probably already have infrastructure for
distributing packages internally, like &lt;a href=&quot;https://jfrog.com/artifactory&quot;&gt;Artifactory&lt;/a&gt;, an &lt;a href=&quot;https://prefix.dev/blog/s3-support-in-the-conda-ecosystem-pixi-and-co&quot;&gt;S3-backed conda channel&lt;/a&gt;, or a &lt;a href=&quot;https://github.com/conda-incubator/conda-mirror&quot;&gt;conda-mirror&lt;/a&gt;.
Skills move through the same channels as your other packages, with no special cases.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Your existing supply chain security applies.&lt;/strong&gt; Package signing&lt;sup&gt;&lt;a href=&quot;#user-content-fn-1&quot; id=&quot;user-content-fnref-1&quot; data-footnote-ref aria-describedby=&quot;footnote-label&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;, review workflows,
vulnerability scanning, access controls — whatever you’ve built for managing
software packages now applies to skills too. You can audit a skill before publishing
it to your internal channel, and restrict which skill packages are approved
for use.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;drawbacks&quot;&gt;&lt;a href=&quot;#drawbacks&quot;&gt;Drawbacks&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Since your skills are no longer tracked in Git, you cannot manually edit them and expect that these changes persist across devices.
If you want to edit a skill, you would need to update the package underneath it.
With a &lt;a href=&quot;https://github.com/pavelzw/skill-forge/blob/main/.github/workflows/package.yml&quot;&gt;solid packaging flow&lt;/a&gt;, this shouldn’t be a problem, though.&lt;/p&gt;
&lt;p&gt;The skills only become available after cloning once you run &lt;code&gt;pixi install&lt;/code&gt;.
For local development (for example via the Claude Code CLI), this is not an issue since you are running your code anyway.
For remote development, it depends on the specific setup and infrastructure you are using.
At the time of writing, in the Codex desktop app, you can specify custom setup scripts where you could add &lt;code&gt;pixi install&lt;/code&gt;. When using Codex with multiple worktrees locally, the skills get picked up automatically.
Strangely, this is not the case with the Codex web version (and mobile app). There, it doesn’t find the skills after running &lt;code&gt;pixi install&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The Claude Code web application (and mobile app) currently do not support this workflow.
There, you can create environments like in Codex but unfortunately, it’s only possible to create environment variables and not run custom setup scripts.
You could instruct your agent via an &lt;code&gt;AGENTS.md&lt;/code&gt; file to run &lt;code&gt;pixi install&lt;/code&gt; and look for skills in those locations.&lt;/p&gt;
&lt;h2 id=&quot;outlook&quot;&gt;&lt;a href=&quot;#outlook&quot;&gt;Outlook&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Everything described here is pixi-specific, but the core idea applies to any package
manager. pip or uv could install skill packages into &lt;code&gt;.venv/share/agent-skills/&lt;/code&gt;.
bun or npm could write them to &lt;code&gt;node_modules/&lt;/code&gt;. The details change, the principle does not.&lt;/p&gt;
&lt;p&gt;Skills are text files. Managing text files at scale is a solved problem.
The practices we built over decades for shipping software like versioning, lockfiles, registries, signing, and reviews, map directly onto distributing agent instructions.&lt;/p&gt;
&lt;section data-footnotes class=&quot;footnotes&quot;&gt;&lt;h2 class=&quot;sr-only&quot; id=&quot;footnote-label&quot;&gt;&lt;a href=&quot;#footnote-label&quot;&gt;Footnotes&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li id=&quot;user-content-fn-1&quot;&gt;
&lt;p&gt;Package signing is not yet fully supported by the Conda ecosystem but &lt;a href=&quot;https://github.com/conda/ceps/pull/142&quot;&gt;in the works&lt;/a&gt;. &lt;a href=&quot;#user-content-fnref-1&quot; data-footnote-backref aria-label=&quot;Back to reference 1&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded><category>claude-code</category><category>pixi</category><category>conda</category><category>ai-agents</category><author>pavelzw@gmail.com (Pavel Zwerschke)</author></item><item><title>Deploying JetBrains Gateway in a Corporate World</title><link>https://pavel.pink/blog/jetbrains-gateway-corporate/</link><guid isPermaLink="true">https://pavel.pink/blog/jetbrains-gateway-corporate/</guid><description>Deploying stuff in a corporate environment can sometimes be challenging due to proxies or firewalls. This article describes how I deployed JetBrains Gateway in a corporate environment with no internet access.</description><pubDate>Sun, 10 Sep 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;When you have worked in a corporate environment, you know that deploying stuff can
be challenging.
During my work, I deployed &lt;a href=&quot;https://jetbrains.com/remote-development/gateway&quot;&gt;JetBrains Gateway&lt;/a&gt;
in a corporate environment. In this article, I will describe how I did it and what
I had to consider.&lt;/p&gt;
&lt;h1 id=&quot;what-is-jetbrains-gateway&quot;&gt;&lt;a href=&quot;#what-is-jetbrains-gateway&quot;&gt;What is JetBrains Gateway?&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;JetBrains Gateway is a piece of software that allows you to remotely access your
JetBrains IDEs, similarly to how you use &lt;a href=&quot;https://code.visualstudio.com/docs/remote/ssh&quot;&gt;VSCode Remote Development&lt;/a&gt;.
With this, you can run your favorite JetBrains IDEs like IntelliJ IDEA or PyCharm
in ✨ ☁️ the cloud ☁️ ✨.&lt;/p&gt;
&lt;h1 id=&quot;how-it-usually-works&quot;&gt;&lt;a href=&quot;#how-it-usually-works&quot;&gt;How it usually works&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;In an open environment that you have control over, the installation of JetBrains
Gateway is pretty straightforward.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;install the Gateway Client on your local machine&lt;/li&gt;
&lt;li&gt;add an SSH connection to your server that should run the IDE&lt;/li&gt;
&lt;li&gt;click on &lt;code&gt;Check Connection and Continue&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;select the IDE you want to install as well as the remote project directory&lt;/li&gt;
&lt;li&gt;click &lt;code&gt;Download IDE and Connect&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;and you’re done! 🎉&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- Light mode image --&gt;&lt;img src=&quot;/_astro/gateway-1-light.DhLuFhf4_Z2hQorh.webp&quot; alt=&quot;Connection Screen&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;912&quot; height=&quot;762&quot; class=&quot;dark:hidden&quot;&gt; &lt;!-- Dark mode image --&gt; &lt;img src=&quot;/_astro/gateway-1-dark.DWVSmKmi_2dQAD4.webp&quot; alt=&quot;Connection Screen&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;912&quot; height=&quot;762&quot; class=&quot;hidden dark:block&quot;&gt;
&lt;!-- Light mode image --&gt;&lt;img src=&quot;/_astro/gateway-2-light.oGpGJDqC_HgaYt.webp&quot; alt=&quot;Connection Screen&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;1897&quot; height=&quot;967&quot; class=&quot;dark:hidden&quot;&gt; &lt;!-- Dark mode image --&gt; &lt;img src=&quot;/_astro/gateway-2-dark.B-lQiiAt_1ibazb.webp&quot; alt=&quot;Connection Screen&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;1897&quot; height=&quot;967&quot; class=&quot;hidden dark:block&quot;&gt;
&lt;h2 id=&quot;taking-a-closer-look&quot;&gt;&lt;a href=&quot;#taking-a-closer-look&quot;&gt;Taking a closer look&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;What happens under the hood when you click on &lt;code&gt;Download IDE and Connect&lt;/code&gt; is that
the Gateway application on your local machine tries to connect via SSH to the remote
server and then downloads your selected IDE from JetBrains’ servers.
This IDE is actually the exact same version that you would download as an end-user
from JetBrains’ website when you want to install PyCharm&lt;sup&gt;&lt;a href=&quot;#user-content-fn-1&quot; id=&quot;user-content-fnref-1&quot; data-footnote-ref aria-describedby=&quot;footnote-label&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; or IntelliJ IDEA&lt;sup&gt;&lt;a href=&quot;#user-content-fn-2&quot; id=&quot;user-content-fnref-2&quot; data-footnote-ref aria-describedby=&quot;footnote-label&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;
on your local machine.&lt;/p&gt;
&lt;p&gt;If you look closely into the downloaded file, you will see that there is a &lt;code&gt;bin&lt;/code&gt;
directory that contains a &lt;code&gt;remote-dev-server.sh&lt;/code&gt; script.
This script is (more or less) what’s executed on the remote server after your IDE
is downloaded.&lt;/p&gt;
&lt;h1 id=&quot;corporate-setup&quot;&gt;&lt;a href=&quot;#corporate-setup&quot;&gt;Corporate setup&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;In a corporate environment, you usually have to deal with proxies and firewalls.
In my case, I had the situation that in the environment to deploy Gateway in was
a docker container which I only had SSH access to.
The docker container itself had no internet access, but I could access the internet
from the host machine.&lt;/p&gt;
&lt;p&gt;So I had to download the IDE from my local machine and then copy it into the
remote server.&lt;/p&gt;
&lt;pre class=&quot;astro-code catppuccin-mocha&quot; style=&quot;background-color:#1e1e2e;color:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code class=&quot;code-highlight&quot;&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#89B4FA;font-style:italic&quot;&gt;scp&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; pycharm-professional-2023.2.1.tar.gz&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; remote-server:~/&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#89B4FA;font-style:italic&quot;&gt;ssh&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; remote-server&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#89B4FA;font-style:italic&quot;&gt;tar&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; xzf&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; pycharm-professional-2023.2.1.tar.gz&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; -C&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; /opt&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;button class=&quot;copy-btn&quot; aria-label=&quot;Copy code&quot; data-copy-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;rect x=&amp;#34;9&amp;#34; y=&amp;#34;9&amp;#34; width=&amp;#34;13&amp;#34; height=&amp;#34;13&amp;#34; rx=&amp;#34;2&amp;#34; ry=&amp;#34;2&amp;#34;/&gt;&lt;path d=&amp;#34;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&amp;#34;/&gt;&lt;/svg&gt;&quot; data-check-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;polyline points=&amp;#34;20 6 9 17 4 12&amp;#34;/&gt;&lt;/svg&gt;&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;&lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/pre&gt;
&lt;p&gt;Additionally, the only directory that was persisted in the docker container was
my home directory which was mounted from a network share.
PyCharm (and probably the other JetBrains IDEs too) requires a persistent directory
to store its configuration and caches.
The configuration is stored in in &lt;code&gt;~/.config/JetBrains&lt;/code&gt; by default and the caches
are stored in &lt;code&gt;~/.cache/JetBrains&lt;/code&gt;.
Unfortunately, PyCharm does not like working on a network share at all&lt;sup&gt;&lt;a href=&quot;#user-content-fn-3&quot; id=&quot;user-content-fnref-3&quot; data-footnote-ref aria-describedby=&quot;footnote-label&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;,
so I had to find a way to store the configuration and caches in a local directory
instead.
Creating a symlink from the network share to a local directory fixed the issue.&lt;/p&gt;
&lt;pre class=&quot;astro-code catppuccin-mocha&quot; style=&quot;background-color:#1e1e2e;color:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code class=&quot;code-highlight&quot;&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#89B4FA;font-style:italic&quot;&gt;ln&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; -s&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; /tmp/jetbrains-cache&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; ~/.cache/JetBrains&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;button class=&quot;copy-btn&quot; aria-label=&quot;Copy code&quot; data-copy-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;rect x=&amp;#34;9&amp;#34; y=&amp;#34;9&amp;#34; width=&amp;#34;13&amp;#34; height=&amp;#34;13&amp;#34; rx=&amp;#34;2&amp;#34; ry=&amp;#34;2&amp;#34;/&gt;&lt;path d=&amp;#34;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&amp;#34;/&gt;&lt;/svg&gt;&quot; data-check-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;polyline points=&amp;#34;20 6 9 17 4 12&amp;#34;/&gt;&lt;/svg&gt;&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;&lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/pre&gt;
&lt;p&gt;Since these are only cache files, we also won’t lose any meaningful data if the
container is restarted.&lt;/p&gt;
&lt;p&gt;So when you run this script, you will see some logging and after some time,
you will see the following message:&lt;/p&gt;
&lt;pre class=&quot;astro-code catppuccin-mocha&quot; style=&quot;background-color:#1e1e2e;color:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code class=&quot;code-highlight&quot;&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;$ REMOTE_DEV_NON_INTERACTIVE=1 /opt/pycharm-2023.2.1/bin/remote-dev-server.sh run \&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    &amp;quot;${project_dir}&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    --ssh-link-port 2222 \&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    --ssh-link-host remote-server \&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    --ssh-link-user remote-user \&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    -l 0.0.0.0&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;*********************************************************&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Join link: tcp://0.0.0.0:5990#jt=...&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Http link: https://code-with-me.jetbrains.com/remoteDev#idePath=%2Fopt%2Fpycharm-2023.2.1&amp;amp;projectPath=%2Fhome%2Fuser%2Fproject&amp;amp;host=remote-server&amp;amp;port=22&amp;amp;user=user&amp;amp;type=ssh&amp;amp;deploy=false&amp;amp;newUi=true&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Gateway link: jetbrains-gateway://connect#idePath=%2Fopt%2Fpycharm-2023.2.1&amp;amp;projectPath=%2Fhome%2Fuser%2Fproject&amp;amp;host=remote-server&amp;amp;port=22&amp;amp;user=user&amp;amp;type=ssh&amp;amp;deploy=false&amp;amp;newUi=true&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;*********************************************************&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;button class=&quot;copy-btn&quot; aria-label=&quot;Copy code&quot; data-copy-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;rect x=&amp;#34;9&amp;#34; y=&amp;#34;9&amp;#34; width=&amp;#34;13&amp;#34; height=&amp;#34;13&amp;#34; rx=&amp;#34;2&amp;#34; ry=&amp;#34;2&amp;#34;/&gt;&lt;path d=&amp;#34;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&amp;#34;/&gt;&lt;/svg&gt;&quot; data-check-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;polyline points=&amp;#34;20 6 9 17 4 12&amp;#34;/&gt;&lt;/svg&gt;&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;&lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/pre&gt;
&lt;p&gt;You can now either open the http link in your browser which will open the
JetBrains Gateway app for you or you can use the Gateway link and paste it into
the Gateway app directly&lt;sup&gt;&lt;a href=&quot;#user-content-fn-4&quot; id=&quot;user-content-fnref-4&quot; data-footnote-ref aria-describedby=&quot;footnote-label&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;And you’re done! 🚀&lt;/p&gt;
&lt;h2 id=&quot;plugins-and-drivers&quot;&gt;&lt;a href=&quot;#plugins-and-drivers&quot;&gt;Plugins and Drivers&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;What makes the JetBrains IDEs so powerful is the huge ecosystem of drivers and plugins.
These drivers and plugins are usually downloaded from the internet when you want
to install them.
In my case, I had no internet access, so I had to download them manually and copy
them into the container.&lt;/p&gt;
&lt;h3 id=&quot;drivers&quot;&gt;&lt;a href=&quot;#drivers&quot;&gt;Drivers&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Drivers are usually project-specific and go into &lt;code&gt;~/.config/JetBrains&lt;/code&gt;.
For example, when I want to download the Snowflake driver for a project in &lt;code&gt;~/project&lt;/code&gt;,
the &lt;code&gt;snowflake-jdbc-3.13.27.jar&lt;/code&gt; driver would need to go into&lt;/p&gt;
&lt;pre class=&quot;astro-code catppuccin-mocha&quot; style=&quot;background-color:#1e1e2e;color:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code class=&quot;code-highlight&quot;&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;~/.config/JetBrains/RemoteDev-PY/_home_user_project/net/snowflake/snowflake-jdbc/3.13.27/snowflake-jdbc-3.13.27.jar&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;button class=&quot;copy-btn&quot; aria-label=&quot;Copy code&quot; data-copy-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;rect x=&amp;#34;9&amp;#34; y=&amp;#34;9&amp;#34; width=&amp;#34;13&amp;#34; height=&amp;#34;13&amp;#34; rx=&amp;#34;2&amp;#34; ry=&amp;#34;2&amp;#34;/&gt;&lt;path d=&amp;#34;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&amp;#34;/&gt;&lt;/svg&gt;&quot; data-check-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;polyline points=&amp;#34;20 6 9 17 4 12&amp;#34;/&gt;&lt;/svg&gt;&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;&lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/pre&gt;
&lt;p&gt;Which jar exactly is needed depends on the driver you want to install.
You can find the exact name of the jar from the IDE error logs.
These drivers are usually downloaded from maven central.
If your corporate environment has a maven mirror like Nexus or Artifactory,
you could maybe even download the driver from there instead.
You can also provide your IDE a custom JAR by clicking on the plus sign in the
“Driver Files” section.&lt;/p&gt;
&lt;!-- Light mode image --&gt;&lt;img src=&quot;/_astro/gateway-3-light.BpeZ6fv4_2cDJFc.webp&quot; alt=&quot;Connection Screen&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;912&quot; height=&quot;788&quot; class=&quot;dark:hidden&quot;&gt; &lt;!-- Dark mode image --&gt; &lt;img src=&quot;/_astro/gateway-3-dark.DfvQaNSC_Z2qnSj8.webp&quot; alt=&quot;Connection Screen&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;912&quot; height=&quot;788&quot; class=&quot;hidden dark:block&quot;&gt;
&lt;h3 id=&quot;plugins&quot;&gt;&lt;a href=&quot;#plugins&quot;&gt;Plugins&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Plugins can be downloaded manually from the &lt;a href=&quot;https://plugins.jetbrains.com&quot;&gt;JetBrains Website&lt;/a&gt;.
For example, if you want to install the &lt;a href=&quot;https://plugins.jetbrains.com/plugin/7499-gittoolbox&quot;&gt;GitToolBox plugin&lt;/a&gt;,
you can just search for it on the website and download it for your IDE version.
The downloaded zip needs to be extracted to &lt;code&gt;~/.config/JetBrains/RemoteDev-PY/_home_user_project/plugins/gittoolbox/&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You need to differentiate between host plugins and client plugins.
Host plugins are installed on the remote server and client plugins
can be installed on the local machine (mostly theme-related plugins).
For example, &lt;a href=&quot;https://plugins.jetbrains.com/plugin/7499-gittoolbox&quot;&gt;GitToolBox&lt;/a&gt;
is a host plugin, but &lt;a href=&quot;https://plugins.jetbrains.com/plugin/164-ideavim&quot;&gt;IdeaVim&lt;/a&gt;
is a client plugin.&lt;/p&gt;
&lt;h1 id=&quot;putting-it-all-together&quot;&gt;&lt;a href=&quot;#putting-it-all-together&quot;&gt;Putting it all together&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;I’d like to end with a short summary of the steps that are needed to deploy
JetBrains Gateway in a corporate world.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;install the Gateway Client on your local machine&lt;/li&gt;
&lt;li&gt;download your ide from JetBrains’ website&lt;/li&gt;
&lt;li&gt;&lt;code&gt;scp &amp;lt;ide&amp;gt;-&amp;lt;version&amp;gt;.tar.gz remote-server:~/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;extract the tarball to your installation directory&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ln -s /tmp/jetbrains-cache ~/.cache/JetBrains&lt;/code&gt; (if &lt;code&gt;$HOME&lt;/code&gt; is a network share)&lt;/li&gt;
&lt;li&gt;add drivers and plugins to &lt;code&gt;~/.config/JetBrains/RemoteDev-PY/_home_user_project/&lt;/code&gt;&lt;sup&gt;&lt;a href=&quot;#user-content-fn-5&quot; id=&quot;user-content-fnref-5&quot; data-footnote-ref aria-describedby=&quot;footnote-label&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;
(if needed)&lt;/li&gt;
&lt;li&gt;if you need a proxy on your local machine, configure it in the Gateway app&lt;/li&gt;
&lt;li&gt;run the &lt;code&gt;remote-dev-server.sh&lt;/code&gt; script on the remote server&lt;/li&gt;
&lt;li&gt;???&lt;/li&gt;
&lt;li&gt;profit!!! 💸&lt;/li&gt;
&lt;/ul&gt;
&lt;section data-footnotes class=&quot;footnotes&quot;&gt;&lt;h2 class=&quot;sr-only&quot; id=&quot;footnote-label&quot;&gt;&lt;a href=&quot;#footnote-label&quot;&gt;Footnotes&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li id=&quot;user-content-fn-1&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.jetbrains.com/pycharm/download/?section=linux&quot;&gt;jetbrains.com/pycharm/download?section=linux&lt;/a&gt; or &lt;a href=&quot;https://download.jetbrains.com/product?code=PY&amp;#38;latest&amp;#38;distribution=linux&quot;&gt;download.jetbrains.com/product?code=PY&amp;amp;latest&amp;amp;distribution=linux&lt;/a&gt; &lt;a href=&quot;#user-content-fnref-1&quot; data-footnote-backref aria-label=&quot;Back to reference 1&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-2&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.jetbrains.com/idea/download/?section=linux&quot;&gt;jetbrains.com/idea/download/?section=linux&lt;/a&gt; or &lt;a href=&quot;https://download.jetbrains.com/product?code=IU&amp;#38;latest&amp;#38;distribution=linux&quot;&gt;download.jetbrains.com/product?code=IU&amp;amp;latest&amp;amp;distribution=linux&lt;/a&gt; &lt;a href=&quot;#user-content-fnref-2&quot; data-footnote-backref aria-label=&quot;Back to reference 2&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-3&quot;&gt;
&lt;p&gt;See issue &lt;a href=&quot;https://youtrack.jetbrains.com/issue/GTW-5697&quot;&gt;GTW-5697&lt;/a&gt; on YouTrack. &lt;a href=&quot;#user-content-fnref-3&quot; data-footnote-backref aria-label=&quot;Back to reference 3&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-4&quot;&gt;
&lt;p&gt;In corporate environments, it is usually the case that you cannot access the internet from your local machine directly but through a proxy. You may need to configure the proxy settings in the Gateway app. &lt;a href=&quot;https://github.com/genotrance/px&quot;&gt;px-proxy&lt;/a&gt; might come in handy if you use NTLM authentication since JetBrains products cannot handle this natively. &lt;a href=&quot;#user-content-fnref-4&quot; data-footnote-backref aria-label=&quot;Back to reference 4&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-5&quot;&gt;
&lt;p&gt;You need to update the paths accordingly to your project directory. Also, &lt;code&gt;RemoteDev-PY&lt;/code&gt; might be different for you depending on the IDE you want to use. &lt;a href=&quot;#user-content-fnref-5&quot; data-footnote-backref aria-label=&quot;Back to reference 5&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded><category>jetbrains</category><category>corporate</category><category>deployment</category><author>pavelzw@gmail.com (Pavel Zwerschke)</author></item><item><title>Automatically Transform Complex Python Methods to Polars Expressions</title><link>https://pavel.pink/blog/polarify/</link><guid isPermaLink="true">https://pavel.pink/blog/polarify/</guid><description>Tired of writing complicated Polars expressions? polarIFy automatically translates your easy-to-read Python methods into efficient Polars expressions!</description><pubDate>Fri, 25 Aug 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;Update 28.09.2023:&lt;/em&gt; My colleague Bela held a Lightning Talk at the Big PyData BBQ.
You can check it out on &lt;a href=&quot;https://youtu.be/G7TuIzKnd-c&quot;&gt;YouTube&lt;/a&gt;!&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;In this post, we introduce &lt;a href=&quot;https://github.com/quantco/polarify&quot;&gt;polarIFy&lt;/a&gt;, a Python function decorator that
gives you a simpler way to write logical statements for Polars. With polarIFy, you
can use Python’s language structures like &lt;code&gt;if / elif / else&lt;/code&gt; statements and transform
them into &lt;code&gt;pl.when(..).then(..).otherwise(..)&lt;/code&gt; statements. This makes your code
more readable and less cumbersome to write.&lt;/p&gt;
&lt;p&gt;At QuantCo, we frequently deal with insurance contracts where the calculation behavior
is contingent upon the exact tariff. For instance, we might calculate certain properties
differently for older contracts compared to newer ones.&lt;/p&gt;
&lt;p&gt;This introduces a degree of conditional business logic into our data processing pipelines.
When working with Polars, these conditional operations often translate into nested
&lt;code&gt;pl.when(..).then(..).otherwise(..)&lt;/code&gt; statements. While this structure is powerful
and allows for a great deal of flexibility, it can quickly become complex and difficult
to read, especially when dealing with multiple conditions or branches.&lt;/p&gt;
&lt;p&gt;This is where polarIFy comes in. By allowing us to write these conditional statements
in a more Pythonic way using &lt;code&gt;if / elif / else&lt;/code&gt; structures, polarIFy greatly simplifies
our code. It makes our Polars pipelines cleaner, more readable, and less prone to
errors, especially when dealing with the intricate conditional logic often required
in our work with insurance contracts.&lt;/p&gt;
&lt;h1 id=&quot;using-polarify&quot;&gt;&lt;a href=&quot;#using-polarify&quot;&gt;Using polarIFy&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;polarIFy can automatically transform Python functions using &lt;code&gt;if / elif / else&lt;/code&gt; statements
into Polars expressions. Here’s an example:&lt;/p&gt;
&lt;pre class=&quot;astro-code catppuccin-mocha&quot; style=&quot;background-color:#1e1e2e;color:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code class=&quot;code-highlight&quot;&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FAB387;font-style:italic&quot;&gt;@polarify&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#89B4FA;font-style:italic&quot;&gt; func&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC&quot;&gt; pl&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC&quot;&gt;Expr&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; pl&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;Expr&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    s &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt; 10&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; s &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt; 10&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;    else&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;        t &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt; 2&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; t&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;    else&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;s&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;button class=&quot;copy-btn&quot; aria-label=&quot;Copy code&quot; data-copy-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;rect x=&amp;#34;9&amp;#34; y=&amp;#34;9&amp;#34; width=&amp;#34;13&amp;#34; height=&amp;#34;13&amp;#34; rx=&amp;#34;2&amp;#34; ry=&amp;#34;2&amp;#34;/&gt;&lt;path d=&amp;#34;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&amp;#34;/&gt;&lt;/svg&gt;&quot; data-check-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;polyline points=&amp;#34;20 6 9 17 4 12&amp;#34;/&gt;&lt;/svg&gt;&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;&lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/pre&gt;
&lt;p&gt;This gets transformed into:&lt;/p&gt;
&lt;pre class=&quot;astro-code catppuccin-mocha&quot; style=&quot;background-color:#1e1e2e;color:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code class=&quot;code-highlight&quot;&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#89B4FA;font-style:italic&quot;&gt; func_polarified&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC&quot;&gt; pl&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC&quot;&gt;Expr&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; pl&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;Expr&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;        pl&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;when&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;x &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt; 10&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;then&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt; 10&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;otherwise&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;            pl&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;when&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;x &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;                .&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;then&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;                .&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;otherwise&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;        )&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;    )&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;button class=&quot;copy-btn&quot; aria-label=&quot;Copy code&quot; data-copy-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;rect x=&amp;#34;9&amp;#34; y=&amp;#34;9&amp;#34; width=&amp;#34;13&amp;#34; height=&amp;#34;13&amp;#34; rx=&amp;#34;2&amp;#34; ry=&amp;#34;2&amp;#34;/&gt;&lt;path d=&amp;#34;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&amp;#34;/&gt;&lt;/svg&gt;&quot; data-check-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;polyline points=&amp;#34;20 6 9 17 4 12&amp;#34;/&gt;&lt;/svg&gt;&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;&lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/pre&gt;
&lt;p&gt;polarIFy can also handle multiple statements and nested statements, making it a
versatile tool for simplifying your Polars code.&lt;/p&gt;
&lt;h1 id=&quot;how-it-works&quot;&gt;&lt;a href=&quot;#how-it-works&quot;&gt;How it works&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Let’s take a look at the above example in a control flow graph:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/static/images/polarify/polarify_1.mmd.svg&quot; alt=&quot;Control flow graph&quot;/&gt;&lt;/p&gt;
&lt;p&gt;In order to transform this control flow into a Polars expression, we need to keep
track of all possible assignments to variables to determine when to return what.
We do that by creating a dictionary &lt;code&gt;assignments&lt;/code&gt; for each node that maps variable
names to their values.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/static/images/polarify/polarify_2.mmd.svg&quot; alt=&quot;Control flow graph&quot;/&gt;&lt;/p&gt;
&lt;p&gt;At the beginning, we haven’t assigned any values to any variables, so we start with
an empty dictionary: &lt;code&gt;assignments = {}&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In the first step, we assign the value &lt;code&gt;1&lt;/code&gt; to the variable &lt;code&gt;s&lt;/code&gt;, so we update the
dictionary: &lt;code&gt;assignments = {&amp;#39;s&amp;#39;: 1}&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/static/images/polarify/polarify_3.mmd.svg&quot; alt=&quot;Control flow graph&quot;/&gt;&lt;/p&gt;
&lt;p&gt;Going further, we evaluate &lt;code&gt;if x &amp;gt; 10&lt;/code&gt;. This translates to the polars expression
&lt;code&gt;pl.when(x &amp;gt; 10).then(..).otherwise(..)&lt;/code&gt;.
We need to keep track recursively of all possible assignments to variables and
the return value of the &lt;code&gt;then&lt;/code&gt; and &lt;code&gt;else&lt;/code&gt; branches of our control flow.&lt;/p&gt;
&lt;p&gt;Since the &lt;code&gt;then&lt;/code&gt; branch directly returns &lt;code&gt;s + 10&lt;/code&gt;, we can just put a &lt;code&gt;s + 10&lt;/code&gt; in
our polars expression:
&lt;code&gt;pl.when(x &amp;gt; 10).then(assignments[&amp;#39;s&amp;#39;] + 10).otherwise(..)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now, let’s look at the &lt;code&gt;else&lt;/code&gt; branch.
We assign the value &lt;code&gt;2&lt;/code&gt; to the variable &lt;code&gt;t&lt;/code&gt;, so we create a new dictionary from
the old one with our new assignment: &lt;code&gt;assignments = {&amp;#39;s&amp;#39;: 1, &amp;#39;t&amp;#39;: 2}&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We now have another &lt;code&gt;if&lt;/code&gt; statement which gets translated into another
&lt;code&gt;pl.when(x &amp;gt; 0).then(..).otherwise(..)&lt;/code&gt; expression.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;then&lt;/code&gt; branch returns the value of &lt;code&gt;t&lt;/code&gt;, which we can get from our
&lt;code&gt;assignments&lt;/code&gt; dictionary. Thus, we can put &lt;code&gt;assignments[&amp;#39;t&amp;#39;]&lt;/code&gt; into our polars
expression: &lt;code&gt;pl.when(x &amp;gt; 0).then(assignments[&amp;#39;t&amp;#39;]).otherwise(..)&lt;/code&gt;.
The &lt;code&gt;else&lt;/code&gt; branch returns &lt;code&gt;-s&lt;/code&gt;, which we can also get from our &lt;code&gt;assignments&lt;/code&gt;
dictionary: &lt;code&gt;pl.when(x &amp;gt; 0).then(..).otherwise(-assignments[&amp;#39;s&amp;#39;])&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;All in all, we land at the following polars expression:&lt;/p&gt;
&lt;pre class=&quot;astro-code catppuccin-mocha&quot; style=&quot;background-color:#1e1e2e;color:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;python&quot;&gt;&lt;code class=&quot;code-highlight&quot;&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    pl&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;when&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;x &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt; 10&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;    .&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;then&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt; 10&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;    .&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;otherwise&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;        pl&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;when&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;x &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;            .&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;then&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;            .&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;otherwise&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;    )&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;button class=&quot;copy-btn&quot; aria-label=&quot;Copy code&quot; data-copy-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;rect x=&amp;#34;9&amp;#34; y=&amp;#34;9&amp;#34; width=&amp;#34;13&amp;#34; height=&amp;#34;13&amp;#34; rx=&amp;#34;2&amp;#34; ry=&amp;#34;2&amp;#34;/&gt;&lt;path d=&amp;#34;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&amp;#34;/&gt;&lt;/svg&gt;&quot; data-check-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;polyline points=&amp;#34;20 6 9 17 4 12&amp;#34;/&gt;&lt;/svg&gt;&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;&lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/pre&gt;
&lt;h1 id=&quot;limitations&quot;&gt;&lt;a href=&quot;#limitations&quot;&gt;Limitations&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Since polarIFy transforms Python functions into Polars expressions, it can only
handle logic that Polars itself can also do.
For instance, it can’t handle &lt;code&gt;for&lt;/code&gt; and &lt;code&gt;while&lt;/code&gt; loops, since it is not possible
to do loops for a single element with Polars expressions.
Also, functions with side effects (like &lt;code&gt;print&lt;/code&gt;, &lt;code&gt;raise&lt;/code&gt; or &lt;code&gt;pl.write_csv&lt;/code&gt;) are
not supported since these don’t make sense in a Polars expression context.&lt;/p&gt;
&lt;p&gt;Since polarIFy is a relatively new project, it might not work for all use cases
yet. As of August 2023, there are some known limitations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;match ... case&lt;/code&gt; statements are not supported&lt;/li&gt;
&lt;li&gt;the walrus operator &lt;code&gt;:=&lt;/code&gt; is not supported&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;conclusion&quot;&gt;&lt;a href=&quot;#conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;polarIFy is a powerful tool that simplifies the process of writing conditional
statements in Polars. By allowing you to write conditions in a more Pythonic
way, it makes your code cleaner and easier to understand.
We’re excited about its potential to make working with Polars even more
efficient and enjoyable.&lt;/p&gt;
&lt;p&gt;We’re always looking for feedback and contributions, so feel free to check out
the &lt;a href=&quot;https://github.com/quantco/polarify&quot;&gt;polarIFy GitHub repository&lt;/a&gt; and let us know what you think!&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;This is a cross-post from the &lt;a href=&quot;https://tech.quantco.com/blog/polarify&quot;&gt;QuantCo blog&lt;/a&gt;.
Check out the other posts there!&lt;/p&gt;</content:encoded><category>polars</category><category>python</category><category>ast</category><category>compiler</category><author>pavelzw@gmail.com (Pavel Zwerschke)</author></item><item><title>Optimize Pickling Disk Space for Deploying scikit-learn Trees to Production</title><link>https://pavel.pink/blog/slim-trees/</link><guid isPermaLink="true">https://pavel.pink/blog/slim-trees/</guid><description>We present an open source library to shrink pickled scikit-learn and lightgbm models. We will provide insights of how pickling ML models work and how to improve the disk representation. With this approach, we can reduce the deployment size of machine learning applications up to 6x.</description><pubDate>Thu, 23 Jun 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;Update 04/2023:&lt;/em&gt; We have created a package that implements the ideas presented in this article and
presented it at PyData Berlin 2023. Feel free to check &lt;code&gt;slim-trees&lt;/code&gt; out on
&lt;a href=&quot;https://github.com/quantco/slim-trees&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;At QuantCo, we use ML models such as random forests to create value from data for
our customers. To ship these models to production, we have to include them in the
application, e.g., bake them into a Docker container or fetch them from a model
registry. To save these models, we pickle them.&lt;/p&gt;
&lt;p&gt;If we want to improve the model, we sometimes increase the number of parameters.
This comes at the cost of disk space because the model is getting more complex.
In our case, we were not able to deploy a larger model because of a file size constraint.
Nevertheless, in general it makes sense to strive for smaller Docker images to
achieve quicker transfer and deployment.&lt;/p&gt;
&lt;p&gt;One way to solve this problem would be to use a different format altogether, like
ONNX. Instead, we challenged the scikit-learn pickle format to see if there are
any gains to be had. We found a 4x improvement over the native scikit-learn format.&lt;/p&gt;
&lt;a id=&quot;numbers&quot;&gt;&lt;/a&gt;
&lt;p&gt;Here are the numbers:&lt;/p&gt;








































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;dtype compression&lt;/th&gt;&lt;th&gt;compression algorithm&lt;/th&gt;&lt;th&gt;size&lt;/th&gt;&lt;th&gt;dump time&lt;/th&gt;&lt;th&gt;load time&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;no&lt;/td&gt;&lt;td&gt;no&lt;/td&gt;&lt;td&gt;496 MB&lt;/td&gt;&lt;td&gt;1.4 s&lt;/td&gt;&lt;td&gt;0.7 s&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;yes&lt;/td&gt;&lt;td&gt;no&lt;/td&gt;&lt;td&gt;128 MB&lt;/td&gt;&lt;td&gt;1.6 s&lt;/td&gt;&lt;td&gt;0.9 s&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;no&lt;/td&gt;&lt;td&gt;lzma&lt;/td&gt;&lt;td&gt;144 MB&lt;/td&gt;&lt;td&gt;217 s&lt;/td&gt;&lt;td&gt;8.4 s&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;yes&lt;/td&gt;&lt;td&gt;lzma&lt;/td&gt;&lt;td&gt;32 MB&lt;/td&gt;&lt;td&gt;53 s&lt;/td&gt;&lt;td&gt;2.8 s&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;In this article, we present how we did it.&lt;/p&gt;
&lt;h1 id=&quot;how-a-tree-is-saved&quot;&gt;&lt;a href=&quot;#how-a-tree-is-saved&quot;&gt;How a &lt;code&gt;Tree&lt;/code&gt; is saved&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Usually, when pickling an object, the methods &lt;code&gt;__reduce__&lt;/code&gt; and &lt;code&gt;__setstate__&lt;/code&gt; get
called to serialize the object. The following code illustrates some of what is
happening when calling &lt;code&gt;pickle.dump(obj)&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;astro-code catppuccin-mocha&quot; style=&quot;background-color:#1e1e2e;color:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;py&quot;&gt;&lt;code class=&quot;code-highlight&quot;&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#89B4FA;font-style:italic&quot;&gt; pickle_obj&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;obj&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    cls&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; init_args&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; state &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; obj&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89DCEB;font-style:italic&quot;&gt;__reduce__&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; unpickle_obj&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;cls&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; init_args&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; state&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#89B4FA;font-style:italic&quot;&gt; unpickle_obj&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;cls&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; init_args&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; state&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    obj &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt; cls&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;init_args&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    obj&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89DCEB;font-style:italic&quot;&gt;__setstate__&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;state&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; obj&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;myobj &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; ...&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;unpickle_func&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; myobj_data &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt; pickle_obj&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;myobj&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;save_to_file&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;quot;myobj.pkl&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; unpickle_func&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; myobj_data&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;unpickle_func&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; myobj_data &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt; load_from_file&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;quot;myobj.pkl&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;myobj_unpickled &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt; unpickle_func&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;myobj_data&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;button class=&quot;copy-btn&quot; aria-label=&quot;Copy code&quot; data-copy-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;rect x=&amp;#34;9&amp;#34; y=&amp;#34;9&amp;#34; width=&amp;#34;13&amp;#34; height=&amp;#34;13&amp;#34; rx=&amp;#34;2&amp;#34; ry=&amp;#34;2&amp;#34;/&gt;&lt;path d=&amp;#34;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&amp;#34;/&gt;&lt;/svg&gt;&quot; data-check-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;polyline points=&amp;#34;20 6 9 17 4 12&amp;#34;/&gt;&lt;/svg&gt;&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;&lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/pre&gt;
&lt;p&gt;Let’s look at the structure of &lt;code&gt;state&lt;/code&gt; when we call &lt;code&gt;tree.__reduce__()&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;astro-code catppuccin-mocha&quot; style=&quot;background-color:#1e1e2e;color:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;py&quot;&gt;&lt;code class=&quot;code-highlight&quot;&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;    &amp;#39;max_depth&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt; 19&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;    &amp;#39;node_count&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt; 469&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;    &amp;#39;nodes&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; np&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;array&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;        shape&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt;469&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,),&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;        dtype&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;np&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;dtype&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;([&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;            (&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;left_child&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; &amp;#39;&amp;lt;i8&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;            (&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;right_child&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; &amp;#39;&amp;lt;i8&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;            (&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;feature&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; &amp;#39;&amp;lt;i8&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;            (&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;threshold&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; &amp;#39;&amp;lt;f8&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;            (&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;impurity&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; &amp;#39;&amp;lt;f8&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;            (&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;n_node_samples&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; &amp;#39;&amp;lt;i8&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;            (&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;weighted_n_node_samples&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; &amp;#39;&amp;lt;f8&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)])),&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;    &amp;#39;values&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; np&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;array&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;        shape&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt;469&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;),&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; dtype&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;float64&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;button class=&quot;copy-btn&quot; aria-label=&quot;Copy code&quot; data-copy-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;rect x=&amp;#34;9&amp;#34; y=&amp;#34;9&amp;#34; width=&amp;#34;13&amp;#34; height=&amp;#34;13&amp;#34; rx=&amp;#34;2&amp;#34; ry=&amp;#34;2&amp;#34;/&gt;&lt;path d=&amp;#34;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&amp;#34;/&gt;&lt;/svg&gt;&quot; data-check-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;polyline points=&amp;#34;20 6 9 17 4 12&amp;#34;/&gt;&lt;/svg&gt;&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;&lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/pre&gt;
&lt;p&gt;Since &lt;code&gt;max_depth&lt;/code&gt; and &lt;code&gt;node_count&lt;/code&gt; are only single integers, they can be neglected
when trying to minimize the disk space. &lt;code&gt;nodes&lt;/code&gt; is a &lt;a href=&quot;https://numpy.org/doc/stable/reference/arrays.dtypes.html#data-type-objects-dtype&quot;&gt;NumPy data type object&lt;/a&gt;,
each element of the array is actually a tuple containing the indices of the children,
the used feature, etc. per node. This has a lot of potential for savings.
&lt;code&gt;value&lt;/code&gt; is a separate array because it could be a &lt;a href=&quot;https://scikit-learn.org/stable/modules/generated/sklearn.multioutput.MultiOutputRegressor.html#sklearn.multioutput.MultiOutputRegressor&quot;&gt;multidimensional output&lt;/a&gt;
too which doesn’t fit in the data type object structure of &lt;code&gt;nodes&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Returning to the &lt;code&gt;state&lt;/code&gt; of our &lt;code&gt;Tree&lt;/code&gt;, we can see that all the elements of &lt;code&gt;nodes&lt;/code&gt;
are either of type &lt;code&gt;&amp;lt;i8&lt;/code&gt; or &lt;code&gt;&amp;lt;f8&lt;/code&gt;, i.e., &lt;code&gt;int64&lt;/code&gt; or &lt;code&gt;float64&lt;/code&gt;.
This takes up a lot of disk space. To mitigate this problem, we could simply change
how these parameters of the model are stored to make the serialization more efficient.&lt;/p&gt;
&lt;p&gt;How can we implement changing all &lt;code&gt;float64&lt;/code&gt; and &lt;code&gt;int64&lt;/code&gt; numbers to more efficient
datatypes?
To do this, we can customize the behaviour of scikit-learn when pickling a &lt;code&gt;Tree&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&quot;custom-picklers&quot;&gt;&lt;a href=&quot;#custom-picklers&quot;&gt;Custom picklers&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;We will be creating a custom pickler whose behavior varies when pickling a &lt;code&gt;Tree&lt;/code&gt;
object. Thus, every instance of a &lt;code&gt;Tree&lt;/code&gt; in our model structure will get pickled
in a custom manner while the rest of the pickling behavior stays the same.&lt;/p&gt;
&lt;p&gt;To achieve this, we need to customize the dispatch table of said pickler.&lt;/p&gt;
&lt;pre class=&quot;astro-code catppuccin-mocha&quot; style=&quot;background-color:#1e1e2e;color:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;py&quot;&gt;&lt;code class=&quot;code-highlight&quot;&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#89B4FA;font-style:italic&quot;&gt; dump_dtype_reduction&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;model&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC&quot;&gt; Any&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; file&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC&quot;&gt; BinaryIO&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    p &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; pickle&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;Pickler&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;file&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    p&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;dispatch_table &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; copyreg&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;dispatch_table&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;copy&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    p&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;dispatch_table&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;Tree&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; compressed_tree_pickle&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    p&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;dump&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;model&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;button class=&quot;copy-btn&quot; aria-label=&quot;Copy code&quot; data-copy-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;rect x=&amp;#34;9&amp;#34; y=&amp;#34;9&amp;#34; width=&amp;#34;13&amp;#34; height=&amp;#34;13&amp;#34; rx=&amp;#34;2&amp;#34; ry=&amp;#34;2&amp;#34;/&gt;&lt;path d=&amp;#34;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&amp;#34;/&gt;&lt;/svg&gt;&quot; data-check-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;polyline points=&amp;#34;20 6 9 17 4 12&amp;#34;/&gt;&lt;/svg&gt;&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;&lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/pre&gt;
&lt;p&gt;The method &lt;code&gt;compressed_tree_pickle&lt;/code&gt; is supposed to replace the method &lt;code&gt;pickle_obj&lt;/code&gt;
from above.&lt;/p&gt;
&lt;p&gt;Since we want to reduce the size of a &lt;code&gt;Tree&lt;/code&gt;’s &lt;code&gt;state&lt;/code&gt;, we want to do something
like this.&lt;/p&gt;
&lt;pre class=&quot;astro-code catppuccin-mocha&quot; style=&quot;background-color:#1e1e2e;color:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;py&quot;&gt;&lt;code class=&quot;code-highlight&quot;&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#89B4FA;font-style:italic&quot;&gt; compressed_tree_pickle&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;tree&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;    assert&lt;/span&gt;&lt;span style=&quot;color:#FAB387;font-style:italic&quot;&gt; isinstance&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;tree&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; Tree&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    cls&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; init_args&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; state &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; tree&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89DCEB;font-style:italic&quot;&gt;__reduce__&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    compressed_state &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt; compress_tree_state&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;state&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; compressed_tree_unpickle&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;cls&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; init_args&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; compressed_state&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#89B4FA;font-style:italic&quot;&gt; compressed_tree_unpickle&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;cls&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; init_args&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; state&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    tree &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt; cls&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;init_args&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    decompressed_state &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt; decompress_tree_state&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;state&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    tree&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89DCEB;font-style:italic&quot;&gt;__setstate__&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;decompressed_state&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; tree&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;button class=&quot;copy-btn&quot; aria-label=&quot;Copy code&quot; data-copy-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;rect x=&amp;#34;9&amp;#34; y=&amp;#34;9&amp;#34; width=&amp;#34;13&amp;#34; height=&amp;#34;13&amp;#34; rx=&amp;#34;2&amp;#34; ry=&amp;#34;2&amp;#34;/&gt;&lt;path d=&amp;#34;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&amp;#34;/&gt;&lt;/svg&gt;&quot; data-check-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;polyline points=&amp;#34;20 6 9 17 4 12&amp;#34;/&gt;&lt;/svg&gt;&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;&lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/pre&gt;
&lt;p&gt;Now, all that’s left is to implement &lt;code&gt;compress_tree_state&lt;/code&gt; and &lt;code&gt;decompress_tree_state&lt;/code&gt;
to a more efficient format.&lt;/p&gt;
&lt;h1 id=&quot;compressing-a-tree-state&quot;&gt;&lt;a href=&quot;#compressing-a-tree-state&quot;&gt;Compressing a &lt;code&gt;Tree&lt;/code&gt; state&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;We can see that &lt;code&gt;left_child&lt;/code&gt; and &lt;code&gt;right_child&lt;/code&gt; are stored as &lt;code&gt;&amp;lt;i8&lt;/code&gt;, i.e., &lt;code&gt;int64&lt;/code&gt;
numbers.
But since there are not &lt;em&gt;that&lt;/em&gt; many leaves in a tree, the possible values of the
array containing the children of each node are relatively small. Thus, we can change
the &lt;code&gt;dtype&lt;/code&gt; of the array to &lt;code&gt;int16&lt;/code&gt; for example.
The same can be done with the &lt;code&gt;feature&lt;/code&gt; array. This attribute stores the index of
the features to be used in the node.
The &lt;code&gt;value&lt;/code&gt; array contains the actual output values of the leaves as &lt;code&gt;float64&lt;/code&gt;numbers.
With a bit of loss of precision, we could use &lt;code&gt;float32&lt;/code&gt; here.&lt;/p&gt;
&lt;p&gt;There are now four remaining attributes of &lt;code&gt;state&lt;/code&gt;: &lt;code&gt;threshold&lt;/code&gt;, &lt;code&gt;impurity&lt;/code&gt;,
&lt;code&gt;n_node_samples&lt;/code&gt;, and &lt;code&gt;weighted_node_samples&lt;/code&gt;.
The last three are all purely analytical and not used during inference.
Thus, we can just leave them out in our custom pickling solution.&lt;/p&gt;
&lt;p&gt;Now let’s look at &lt;code&gt;threshold&lt;/code&gt;, i.e., the splitting points at each node, whether
to go to the left or right child in the tree.
We could simply do the same as with the &lt;code&gt;value&lt;/code&gt; array and call it a day.
But unlike the &lt;code&gt;value&lt;/code&gt; array, we need to have in mind that error propagation can
occur. If a “wrong” turn is made in the beginning, we could land at a completely
different output node than we should.&lt;/p&gt;
&lt;p&gt;There are three ways to continue:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;accept the extra loss and continue;&lt;/li&gt;
&lt;li&gt;use &lt;code&gt;float64&lt;/code&gt; again in the &lt;code&gt;threshold&lt;/code&gt; array and don’t gain disk space in this
array;&lt;/li&gt;
&lt;li&gt;examine the structure of the &lt;code&gt;threshold&lt;/code&gt; array and try to find a way to do
lossless compression.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let’s try out the latter option.&lt;/p&gt;
&lt;h2 id=&quot;compressing-half-ints&quot;&gt;&lt;a href=&quot;#compressing-half-ints&quot;&gt;Compressing half ints&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The following only works if you have many categorical columns in your dataset.
If you don’t, you may want to go with 1. or 2. or look into other methods to do
lossless compression.&lt;/p&gt;
&lt;p&gt;When we looked at the structure of the &lt;code&gt;threshold&lt;/code&gt; array, we realized that there
are a lot of values that are of the form &lt;code&gt;x.5&lt;/code&gt;, i.e., &lt;code&gt;3.5&lt;/code&gt;, &lt;code&gt;0.5&lt;/code&gt;, &lt;code&gt;9.5&lt;/code&gt;, etc.
Let’s call them half ints. This is because our dataset has a lot of categorical
values which are converted to &lt;code&gt;int&lt;/code&gt; and then cast to &lt;code&gt;float64&lt;/code&gt; for fitting by scikit-learn.
Since every point still lies on an integer, the optimal splitting point is in the
middle of two integers.
These optimal splitting points are exactly what the sklearn trees learn.
Now what can we do with this information?&lt;/p&gt;
&lt;p&gt;We could compress these half ints by multiplying them with &lt;code&gt;2&lt;/code&gt; and casting them
to &lt;code&gt;int8&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Because of floating point precision, we need to make sure not only to catch the
exact integers but an epsilon neighborhood of the integer values.&lt;/p&gt;
&lt;pre class=&quot;astro-code catppuccin-mocha&quot; style=&quot;background-color:#1e1e2e;color:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;py&quot;&gt;&lt;code class=&quot;code-highlight&quot;&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;a2 &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; np&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;array&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;([&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt;1.9999999999999&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt; 2.0000000000001&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;])&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;np&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;minimum&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;np&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;abs&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;a2 &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;),&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; a2 &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2;font-style:italic&quot;&gt;# array([9.99200722e-14, 9.99200722e-14])&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;button class=&quot;copy-btn&quot; aria-label=&quot;Copy code&quot; data-copy-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;rect x=&amp;#34;9&amp;#34; y=&amp;#34;9&amp;#34; width=&amp;#34;13&amp;#34; height=&amp;#34;13&amp;#34; rx=&amp;#34;2&amp;#34; ry=&amp;#34;2&amp;#34;/&gt;&lt;path d=&amp;#34;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&amp;#34;/&gt;&lt;/svg&gt;&quot; data-check-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;polyline points=&amp;#34;20 6 9 17 4 12&amp;#34;/&gt;&lt;/svg&gt;&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;&lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/pre&gt;
&lt;pre class=&quot;astro-code catppuccin-mocha&quot; style=&quot;background-color:#1e1e2e;color:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;py&quot;&gt;&lt;code class=&quot;code-highlight&quot;&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#89B4FA;font-style:italic&quot;&gt; compress_half_int_float_array&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; compression_dtype&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC&quot;&gt;np&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC&quot;&gt;int8&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    info &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; np&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;iinfo&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;compression_dtype&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    a2 &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt; 2&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; a&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    is_compressible &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;np&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;minimum&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;np&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;abs&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;a2 &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;),&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; a2 &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt; 1e-12&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;                      (&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;a2 &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; info&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;min&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;a2 &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; info&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;max&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    not_compressible &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; np&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;logical_not&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;is_compressible&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    a2_compressible &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; a2&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;is_compressible&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;].&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;astype&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;compression_dtype&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    a_incompressible &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; a&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;not_compressible&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    state &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;        &amp;quot;is_compressible&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; is_compressible&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;        &amp;quot;a2_compressible&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; a2_compressible&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;        &amp;quot;a_incompressible&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; a_incompressible&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; state&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#89B4FA;font-style:italic&quot;&gt; decompress_half_int_float_array&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;state&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    is_compressible &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; state&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1;font-style:italic&quot;&gt;is_compressible&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    a &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; np&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;zeros&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FAB387;font-style:italic&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;is_compressible&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;),&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; dtype&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;quot;float64&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;    a&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;is_compressible&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; state&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1;font-style:italic&quot;&gt;a2_compressible&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; /&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt; 2&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;    a&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;np&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA;font-style:italic&quot;&gt;logical_not&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4;font-style:italic&quot;&gt;is_compressible&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)]&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; state&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1;font-style:italic&quot;&gt;a_incompressible&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; a&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;button class=&quot;copy-btn&quot; aria-label=&quot;Copy code&quot; data-copy-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;rect x=&amp;#34;9&amp;#34; y=&amp;#34;9&amp;#34; width=&amp;#34;13&amp;#34; height=&amp;#34;13&amp;#34; rx=&amp;#34;2&amp;#34; ry=&amp;#34;2&amp;#34;/&gt;&lt;path d=&amp;#34;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&amp;#34;/&gt;&lt;/svg&gt;&quot; data-check-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;polyline points=&amp;#34;20 6 9 17 4 12&amp;#34;/&gt;&lt;/svg&gt;&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;&lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/pre&gt;
&lt;p&gt;This format is very efficient if you have a lot of these half int values in your
array.
&lt;code&gt;state[&amp;quot;is_compressible&amp;quot;]&lt;/code&gt; is a &lt;code&gt;bool&lt;/code&gt; array which takes up only one bit per entry,
&lt;code&gt;state[&amp;quot;a2_compressible&amp;quot;]&lt;/code&gt; is an &lt;code&gt;int8&lt;/code&gt; array which only takes up eight bits per
entry and &lt;code&gt;state[&amp;quot;a_incompressible&amp;quot;]&lt;/code&gt; takes up the full 64 bits per entry.&lt;/p&gt;
&lt;p&gt;In our productive example, the &lt;code&gt;threshold&lt;/code&gt; array contained 4000 elements with
65-70% of them being half integers.
This leads to a theoretical compression of&lt;/p&gt;
&lt;svg style=&quot;vertical-align:-NaNem;display:block;margin:0 auto&quot; class=&quot;typst-doc&quot; viewBox=&quot;0 0 402.000 23.000&quot; width=&quot;36.54545454545455em&quot; height=&quot;2.090909090909091em&quot; data-width=&quot;402.000&quot; data-height=&quot;23.000&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; xmlns:h5=&quot;http://www.w3.org/1999/xhtml&quot;&gt;&lt;style type=&quot;text/css&quot;&gt;.typst-text {
  pointer-events: bounding-box;
}

.tsel span,
.tsel {
  left: 0;
  position: fixed;
  text-align: justify;
  white-space: nowrap;
  width: 100%;
  height: 100%;
  text-align-last: justify;
  color: transparent;
  white-space: pre;
}
.tsel span::-moz-selection,
.tsel::-moz-selection {
  color: transparent;
  background: #7db9dea0;
}
.tsel span::selection,
.tsel::selection {
  color: transparent;
  background: #7db9dea0;
}
.pseudo-link {
  fill: transparent;
  cursor: pointer;
  pointer-events: all;
}
svg {
  fill: none;
}

.outline_glyph path,
path.outline_glyph {
  fill: var(--glyph_fill);
  stroke: var(--glyph_stroke);
}

.outline_glyph path,
path.outline_glyph {
  transition: 0.2s fill stroke;
}
.hover .typst-text {
  --glyph_fill: #66bab7;
  --glyph_stroke: #66bab7;
}

.typst-jump-ripple,
.typst-debug-react-ripple {
  width: 0;
  height: 0;
  background-color: transparent;
  position: absolute;
  border-radius: 50%;
}
.typst-jump-ripple {
  border: 1px solid #66bab7;
}
.typst-debug-react-ripple {
  border: 1px solid #cb1b45;
}
@keyframes typst-jump-ripple-effect {
  to {
    width: 10vw;
    height: 10vw;
    opacity: 0.01;
    margin: -5vw;
  }
}
@keyframes typst-debug-react-ripple-effect {
  to {
    width: 3vw;
    height: 3vw;
    opacity: 0.01;
    margin: -1.5vw;
  }
}
&lt;/style&gt;&lt;defs class=&quot;glyph&quot;&gt;&lt;path id=&quot;gl3Hi1Qw&quot; class=&quot;outline_glyph&quot; d=&quot;M 698 274 L 413 274 L 413 559 C 413 575 405 583 389 583 C 373 583 365 575 365 559 L 365 274 L 80 274 C 64 274 56 266 56 250 C 56 234 64 226 80 226 L 365 226 L 365 -59 C 365 -75 373 -83 389 -83 C 405 -83 413 -75 413 -59 L 413 226 L 698 226 C 714 226 722 234 722 250 C 722 263 711 274 698 274 Z &quot;&gt;&lt;/path&gt;&lt;path id=&quot;gl3Hi1Q8&quot; class=&quot;outline_glyph&quot; d=&quot;M 192 53 C 192 82 168 106 139 106 C 110 106 86 82 86 53 C 86 24 110 0 139 0 C 168 0 192 24 192 53 Z &quot;&gt;&lt;/path&gt;&lt;path id=&quot;gl3Hi1RE&quot; class=&quot;outline_glyph&quot; d=&quot;M 249 -22 C 390 -22 460 92 460 320 C 460 473 428 575 365 625 C 330 652 291 666 250 666 C 109 666 39 551 39 320 C 39 136 88 -22 249 -22 Z M 361 524 C 368 489 371 425 371 332 C 371 240 367 172 360 128 C 347 48 310 8 249 8 C 226 8 203 17 182 34 C 155 57 139 104 132 176 C 129 201 128 253 128 332 C 128 419 131 480 136 513 C 145 568 163 603 191 618 C 213 630 232 636 249 636 C 314 636 350 583 361 524 Z &quot;&gt;&lt;/path&gt;&lt;path id=&quot;gl3Hi1RI&quot; class=&quot;outline_glyph&quot; d=&quot;M 269 666 C 228 624 168 603 89 603 L 89 564 C 141 564 184 572 217 588 L 217 82 C 217 64 213 52 204 47 C 195 42 170 39 130 39 L 95 39 L 95 0 C 120 2 174 3 257 3 C 340 3 394 2 419 0 L 419 39 L 384 39 C 343 39 318 42 310 47 C 302 52 297 64 297 82 L 297 636 C 297 660 295 666 269 666 Z &quot;&gt;&lt;/path&gt;&lt;path id=&quot;gl3Hi1RQ&quot; class=&quot;outline_glyph&quot; d=&quot;M 303 353 C 369 378 431 441 431 526 C 431 569 410 604 369 631 C 333 654 292 666 246 666 C 201 666 162 654 127 631 C 88 605 68 571 68 528 C 68 495 90 472 122 472 C 154 472 176 495 176 527 C 176 560 157 578 119 580 C 145 615 186 633 242 633 C 302 633 332 598 332 527 C 332 485 324 450 309 421 C 282 373 245 364 183 364 C 171 362 165 357 165 348 C 165 333 172 333 192 333 L 235 333 C 310 333 348 280 348 173 C 348 88 317 14 241 14 C 176 14 128 36 99 80 C 134 79 160 105 160 139 C 160 173 135 198 101 198 C 62 198 42 178 42 137 C 42 88 64 49 108 18 C 147 -9 193 -22 244 -22 C 301 -22 350 -3 393 34 C 436 71 457 117 457 173 C 457 267 383 332 303 353 Z &quot;&gt;&lt;/path&gt;&lt;path id=&quot;gl3Hi1RU&quot; class=&quot;outline_glyph&quot; d=&quot;M 353 677 C 344 677 336 672 330 663 L 28 199 L 28 163 L 289 163 L 289 81 C 289 63 285 51 278 46 C 271 41 252 39 219 39 L 194 39 L 194 0 C 223 2 269 3 331 3 C 393 3 439 2 468 0 L 468 39 L 443 39 C 410 39 391 41 384 46 C 377 51 373 63 373 81 L 373 163 L 471 163 L 471 202 L 373 202 L 373 660 C 373 670 366 677 353 677 Z M 295 553 L 295 202 L 67 202 Z &quot;&gt;&lt;/path&gt;&lt;path id=&quot;gl3Hi1RY&quot; class=&quot;outline_glyph&quot; d=&quot;M 118 315 C 123 315 129 319 134 326 C 164 371 205 393 257 393 C 292 393 319 373 337 332 C 348 305 354 264 354 209 C 354 146 346 102 331 76 C 306 35 272 14 229 14 C 162 14 109 62 91 114 C 94 113 96 114 100 114 C 130 114 155 137 155 167 C 155 198 130 219 100 219 C 65 219 50 200 50 163 C 50 63 131 -22 231 -22 C 292 -22 344 0 386 44 C 428 88 449 141 449 202 C 449 260 432 310 398 353 C 361 400 315 423 259 423 C 212 423 171 408 138 378 L 138 556 C 165 548 191 544 218 544 C 264 544 304 555 338 578 C 369 597 390 616 402 634 C 408 642 411 648 411 651 C 411 661 406 666 396 666 C 341 645 294 634 256 634 C 211 634 168 643 127 662 C 122 664 118 665 114 665 C 105 665 100 656 100 637 L 100 345 C 100 324 100 315 118 315 Z &quot;&gt;&lt;/path&gt;&lt;path id=&quot;gl3Hi1Rc&quot; class=&quot;outline_glyph&quot; d=&quot;M 383 504 C 416 504 432 521 432 555 C 432 627 378 666 304 666 C 221 666 155 627 106 548 C 63 480 42 403 42 316 C 42 189 65 100 112 47 C 152 1 198 -22 251 -22 C 312 -22 362 1 401 47 C 438 91 457 144 457 205 C 457 266 439 318 403 361 C 365 407 316 431 257 431 C 205 431 165 402 138 346 L 138 352 C 138 465 166 561 226 605 C 252 624 279 633 306 633 C 342 633 368 623 385 602 C 351 602 334 583 334 553 C 334 525 355 504 383 504 Z M 344 340 C 355 317 361 272 361 206 C 361 141 356 98 345 76 C 325 35 294 14 251 14 C 222 14 200 24 184 44 C 171 60 162 74 158 85 C 146 116 140 163 140 227 C 140 255 144 282 151 308 C 164 355 201 399 256 399 C 295 399 325 379 344 340 Z &quot;&gt;&lt;/path&gt;&lt;path id=&quot;gl3Hi1Rk&quot; class=&quot;outline_glyph&quot; d=&quot;M 250 666 C 201 666 158 650 122 618 C 86 586 68 546 68 497 C 68 456 83 419 113 386 C 120 378 142 361 179 335 C 88 288 42 227 42 153 C 42 100 64 57 107 24 C 147 -7 194 -22 249 -22 C 305 -22 354 -4 395 32 C 436 68 457 115 457 170 C 457 216 441 257 408 294 C 396 307 365 330 316 361 C 393 402 431 454 431 515 C 431 606 344 666 250 666 Z M 379 515 C 379 463 348 418 286 381 L 167 459 C 136 479 120 505 120 536 C 120 596 185 633 249 633 C 318 633 379 584 379 515 Z M 250 14 C 168 14 99 73 99 153 C 99 220 136 274 210 315 L 328 240 C 376 209 400 174 400 134 C 400 62 325 14 250 14 Z &quot;&gt;&lt;/path&gt;&lt;path id=&quot;gl3Hi1R4&quot; class=&quot;outline_glyph&quot; d=&quot;M 698 367 L 80 367 C 64 367 56 359 56 344 C 56 329 64 321 80 321 L 698 321 C 714 321 722 329 722 344 C 722 356 711 367 698 367 Z M 698 179 L 80 179 C 64 179 56 171 56 156 C 56 141 64 133 80 133 L 698 133 C 714 133 722 141 722 156 C 722 169 711 179 698 179 Z &quot;&gt;&lt;/path&gt;&lt;path id=&quot;gl3Hi1SM&quot; class=&quot;outline_glyph&quot; d=&quot;M 478 358 C 548 376 624 432 624 512 C 624 565 599 607 549 640 C 506 669 456 683 401 683 L 36 683 L 36 644 L 64 644 C 99 644 120 641 127 636 C 134 631 138 620 138 602 L 138 81 C 138 63 134 51 127 46 C 120 41 99 39 64 39 L 36 39 L 36 0 L 427 0 C 484 0 535 16 579 48 C 627 83 651 129 651 185 C 651 278 563 342 478 358 Z M 521 512 C 521 428 451 370 367 370 L 228 370 L 228 609 C 228 645 233 644 272 644 L 394 644 C 468 644 521 586 521 512 Z M 544 186 L 544 160 C 542 137 529 111 504 84 C 478 54 442 39 395 39 L 272 39 C 233 39 228 38 228 74 L 228 340 L 409 340 C 490 340 544 270 544 186 Z &quot;&gt;&lt;/path&gt;&lt;path id=&quot;gl3Hi1Uo&quot; class=&quot;outline_glyph&quot; d=&quot;M 194 601 C 194 631 169 657 139 657 C 109 657 83 631 83 601 C 83 571 108 544 138 544 C 169 544 194 570 194 601 Z M 143 3 L 247 0 L 247 39 C 214 39 194 41 188 45 C 182 49 180 60 180 78 L 180 445 L 37 433 L 37 395 C 70 395 91 392 98 387 C 105 382 108 368 108 345 L 108 79 C 108 60 105 48 98 44 C 91 40 69 39 33 39 L 33 0 Z &quot;&gt;&lt;/path&gt;&lt;path id=&quot;gl3Hi1VU&quot; class=&quot;outline_glyph&quot; d=&quot;M 332 126 L 332 186 L 300 186 L 300 128 C 300 78 282 22 238 22 C 197 22 177 56 177 124 L 177 395 L 316 395 L 316 433 L 177 433 L 177 615 L 145 615 C 144 582 141 553 134 527 C 117 461 78 427 19 424 L 19 395 L 102 395 L 102 126 C 102 67 120 29 155 10 C 182 -4 207 -11 232 -11 C 298 -11 332 55 332 126 Z &quot;&gt;&lt;/path&gt;&lt;path id=&quot;gl3Hi1QsE&quot; class=&quot;outline_glyph&quot; d=&quot;M 717 432 L 717 434 C 717 445 712 450 701 450 C 694 450 689 446 686 439 C 679 404 665 377 645 360 C 612 331 577 317 539 317 C 510 317 480 328 449 349 C 392 390 358 413 347 420 C 304 445 266 457 232 457 C 125 457 77 382 56 284 L 56 281 C 56 271 61 266 72 266 C 81 266 86 270 88 278 C 95 313 108 339 128 356 C 161 385 196 399 235 399 C 264 399 293 388 324 366 C 381 326 415 303 426 296 C 469 271 507 259 541 259 C 648 259 696 334 717 432 Z M 717 216 L 717 219 C 717 229 712 234 701 234 C 694 234 689 230 686 223 C 679 188 665 162 645 144 C 612 115 577 101 539 101 C 510 101 480 112 449 134 C 392 174 358 197 347 204 C 304 229 266 241 232 241 C 125 241 77 166 56 68 L 56 66 C 56 55 61 50 72 50 C 81 50 86 54 88 62 C 95 97 108 123 128 140 C 161 169 196 183 235 183 C 264 183 293 172 324 151 C 381 110 415 87 426 80 C 469 55 507 43 541 43 C 648 43 696 118 717 216 Z &quot;&gt;&lt;/path&gt;&lt;path id=&quot;gl3Hi1YgE&quot; class=&quot;outline_glyph&quot; d=&quot;M 192 250 C 192 279 168 303 139 303 C 110 303 86 279 86 250 C 86 221 110 197 139 197 C 168 197 192 221 192 250 Z &quot;&gt;&lt;/path&gt;&lt;/defs&gt;&lt;defs class=&quot;clip-path&quot;&gt;&lt;/defs&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;/style&gt;&lt;g class=&quot;typst-page&quot; transform=&quot;translate(0, 0)&quot; data-tid=&quot;pLzL8mgfXOmI8Z8nHvTOmCg&quot; data-page-width=&quot;402&quot; data-page-height=&quot;23&quot;&gt;&lt;g data-tid=&quot;gLzL8mgfXOmI8Z8nHvTOmCg&quot; class=&quot;typst-group&quot;&gt;&lt;g transform=&quot;translate(0.000,0.000)&quot; data-tid=&quot;p9NmhV8mjp+Qdt0YYwNszKQ&quot;&gt;&lt;g data-tid=&quot;g9NmhV8mjp+Qdt0YYwNszKQ&quot; class=&quot;typst-group&quot;&gt;&lt;g transform=&quot;translate(0.000,0.000)&quot; data-tid=&quot;pdY7qVYHc/WkQvNuj7FFivI&quot;&gt;&lt;g data-tid=&quot;gdY7qVYHc/WkQvNuj7FFivI&quot; class=&quot;typst-group&quot;&gt;&lt;g transform=&quot;translate(1.100,7.513)&quot; data-tid=&quot;pwbp8wzGfeOsHu4HiOMm6Ro&quot;&gt;&lt;g data-tid=&quot;gwbp8wzGfeOsHu4HiOMm6Ro&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RU&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;4&quot;&gt;4&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(6.600,7.513)&quot; data-tid=&quot;pNEBB2iCTdcgRNjY8GzZQho&quot;&gt;&lt;g data-tid=&quot;gNEBB2iCTdcgRNjY8GzZQho&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RE&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;0&quot;&gt;0&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(12.100,7.513)&quot; data-tid=&quot;pNEBB2iCTdcgRNjY8GzZQho&quot;&gt;&lt;g data-tid=&quot;gNEBB2iCTdcgRNjY8GzZQho&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RE&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;0-1&quot;&gt;0&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(17.600,7.513)&quot; data-tid=&quot;pNEBB2iCTdcgRNjY8GzZQho&quot;&gt;&lt;g data-tid=&quot;gNEBB2iCTdcgRNjY8GzZQho&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RE&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;0-2&quot;&gt;0&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(25.544,7.513)&quot; data-tid=&quot;paKe2osoRM6IVnum1y/PQis&quot;&gt;&lt;g data-tid=&quot;gaKe2osoRM6IVnum1y/PQis&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1YgE&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;17.38&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id&gt;⋅&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(31.047,7.513)&quot; data-tid=&quot;pNEBB2iCTdcgRNjY8GzZQho&quot;&gt;&lt;g data-tid=&quot;gNEBB2iCTdcgRNjY8GzZQho&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RE&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;0-3&quot;&gt;0&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(36.547,7.513)&quot; data-tid=&quot;pKx4gjRFV/cIK7g2K0zE0Ls&quot;&gt;&lt;g data-tid=&quot;gKx4gjRFV/cIK7g2K0zE0Ls&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1Q8&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;17.38&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;-1&quot;&gt;.&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(39.605,7.513)&quot; data-tid=&quot;pxJGQF2BzQ+4a4/wP0tpidI&quot;&gt;&lt;g data-tid=&quot;gxJGQF2BzQ+4a4/wP0tpidI&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1Rc&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;6&quot;&gt;6&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(45.105,7.513)&quot; data-tid=&quot;pwlJuD0gd0A42R1nn6oR5kg&quot;&gt;&lt;g data-tid=&quot;gwlJuD0gd0A42R1nn6oR5kg&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RY&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;5&quot;&gt;5&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(53.049,7.513)&quot; data-tid=&quot;paKe2osoRM6IVnum1y/PQis&quot;&gt;&lt;g data-tid=&quot;gaKe2osoRM6IVnum1y/PQis&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1YgE&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;17.38&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;-2&quot;&gt;⋅&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(58.552,7.513)&quot; data-tid=&quot;pLD8LidN0y2EDhKLTsSRMzg&quot;&gt;&lt;g data-tid=&quot;gLD8LidN0y2EDhKLTsSRMzg&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1Rk&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;8&quot;&gt;8&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(65.885,7.513)&quot; data-tid=&quot;pLFmDkkl2VnkR3tg2pHkKwg&quot;&gt;&lt;g data-tid=&quot;gLFmDkkl2VnkR3tg2pHkKwg&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1SM&quot;&gt;&lt;/use&gt;&lt;use x=&quot;708&quot; y=&quot;0&quot; href=&quot;#gl3Hi1Uo&quot;&gt;&lt;/use&gt;&lt;use x=&quot;986&quot; y=&quot;0&quot; href=&quot;#gl3Hi1VU&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;85.94&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;bit&quot;&gt;Bit&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(83.455,7.513)&quot; data-tid=&quot;peHf8J65SCGMjHTtShtQPow&quot;&gt;&lt;g data-tid=&quot;geHf8J65SCGMjHTtShtQPow&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1Qw&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;48.62&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;-3&quot;&gt;+&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(94.457,7.513)&quot; data-tid=&quot;pwbp8wzGfeOsHu4HiOMm6Ro&quot;&gt;&lt;g data-tid=&quot;gwbp8wzGfeOsHu4HiOMm6Ro&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RU&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;4-1&quot;&gt;4&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(99.957,7.513)&quot; data-tid=&quot;pNEBB2iCTdcgRNjY8GzZQho&quot;&gt;&lt;g data-tid=&quot;gNEBB2iCTdcgRNjY8GzZQho&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RE&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;0-4&quot;&gt;0&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(105.457,7.513)&quot; data-tid=&quot;pNEBB2iCTdcgRNjY8GzZQho&quot;&gt;&lt;g data-tid=&quot;gNEBB2iCTdcgRNjY8GzZQho&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RE&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;0-5&quot;&gt;0&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(110.957,7.513)&quot; data-tid=&quot;pNEBB2iCTdcgRNjY8GzZQho&quot;&gt;&lt;g data-tid=&quot;gNEBB2iCTdcgRNjY8GzZQho&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RE&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;0-6&quot;&gt;0&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(118.901,7.513)&quot; data-tid=&quot;paKe2osoRM6IVnum1y/PQis&quot;&gt;&lt;g data-tid=&quot;gaKe2osoRM6IVnum1y/PQis&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1YgE&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;17.38&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;-4&quot;&gt;⋅&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(124.404,7.513)&quot; data-tid=&quot;pNEBB2iCTdcgRNjY8GzZQho&quot;&gt;&lt;g data-tid=&quot;gNEBB2iCTdcgRNjY8GzZQho&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RE&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;0-7&quot;&gt;0&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(129.904,7.513)&quot; data-tid=&quot;pKx4gjRFV/cIK7g2K0zE0Ls&quot;&gt;&lt;g data-tid=&quot;gKx4gjRFV/cIK7g2K0zE0Ls&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1Q8&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;17.38&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;-5&quot;&gt;.&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(132.962,7.513)&quot; data-tid=&quot;pswt4MVJEPlsBqVisNkNgbc&quot;&gt;&lt;g data-tid=&quot;gswt4MVJEPlsBqVisNkNgbc&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RQ&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;3&quot;&gt;3&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(138.462,7.513)&quot; data-tid=&quot;pwlJuD0gd0A42R1nn6oR5kg&quot;&gt;&lt;g data-tid=&quot;gwlJuD0gd0A42R1nn6oR5kg&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RY&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;5-1&quot;&gt;5&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(146.406,7.513)&quot; data-tid=&quot;paKe2osoRM6IVnum1y/PQis&quot;&gt;&lt;g data-tid=&quot;gaKe2osoRM6IVnum1y/PQis&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1YgE&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;17.38&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;-6&quot;&gt;⋅&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(151.909,7.513)&quot; data-tid=&quot;pxJGQF2BzQ+4a4/wP0tpidI&quot;&gt;&lt;g data-tid=&quot;gxJGQF2BzQ+4a4/wP0tpidI&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1Rc&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;6-1&quot;&gt;6&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(157.409,7.513)&quot; data-tid=&quot;pwbp8wzGfeOsHu4HiOMm6Ro&quot;&gt;&lt;g data-tid=&quot;gwbp8wzGfeOsHu4HiOMm6Ro&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RU&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;4-2&quot;&gt;4&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(164.742,7.513)&quot; data-tid=&quot;pLFmDkkl2VnkR3tg2pHkKwg&quot;&gt;&lt;g data-tid=&quot;gLFmDkkl2VnkR3tg2pHkKwg&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1SM&quot;&gt;&lt;/use&gt;&lt;use x=&quot;708&quot; y=&quot;0&quot; href=&quot;#gl3Hi1Uo&quot;&gt;&lt;/use&gt;&lt;use x=&quot;986&quot; y=&quot;0&quot; href=&quot;#gl3Hi1VU&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;85.94&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;bit-1&quot;&gt;Bit&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(182.312,7.513)&quot; data-tid=&quot;peHf8J65SCGMjHTtShtQPow&quot;&gt;&lt;g data-tid=&quot;geHf8J65SCGMjHTtShtQPow&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1Qw&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;48.62&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;-7&quot;&gt;+&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(193.314,7.513)&quot; data-tid=&quot;pwbp8wzGfeOsHu4HiOMm6Ro&quot;&gt;&lt;g data-tid=&quot;gwbp8wzGfeOsHu4HiOMm6Ro&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RU&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;4-3&quot;&gt;4&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(198.814,7.513)&quot; data-tid=&quot;pNEBB2iCTdcgRNjY8GzZQho&quot;&gt;&lt;g data-tid=&quot;gNEBB2iCTdcgRNjY8GzZQho&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RE&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;0-8&quot;&gt;0&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(204.314,7.513)&quot; data-tid=&quot;pNEBB2iCTdcgRNjY8GzZQho&quot;&gt;&lt;g data-tid=&quot;gNEBB2iCTdcgRNjY8GzZQho&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RE&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;0-9&quot;&gt;0&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(209.814,7.513)&quot; data-tid=&quot;pNEBB2iCTdcgRNjY8GzZQho&quot;&gt;&lt;g data-tid=&quot;gNEBB2iCTdcgRNjY8GzZQho&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RE&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;0-10&quot;&gt;0&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(217.758,7.513)&quot; data-tid=&quot;paKe2osoRM6IVnum1y/PQis&quot;&gt;&lt;g data-tid=&quot;gaKe2osoRM6IVnum1y/PQis&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1YgE&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;17.38&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;-8&quot;&gt;⋅&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(223.261,7.513)&quot; data-tid=&quot;pDIkrPr4ePGsCHO9XNLQ38Y&quot;&gt;&lt;g data-tid=&quot;gDIkrPr4ePGsCHO9XNLQ38Y&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RI&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;1&quot;&gt;1&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(230.594,7.513)&quot; data-tid=&quot;pLFmDkkl2VnkR3tg2pHkKwg&quot;&gt;&lt;g data-tid=&quot;gLFmDkkl2VnkR3tg2pHkKwg&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1SM&quot;&gt;&lt;/use&gt;&lt;use x=&quot;708&quot; y=&quot;0&quot; href=&quot;#gl3Hi1Uo&quot;&gt;&lt;/use&gt;&lt;use x=&quot;986&quot; y=&quot;0&quot; href=&quot;#gl3Hi1VU&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;85.94&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;bit-2&quot;&gt;Bit&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(94.457,14.993)&quot; data-tid=&quot;ptJu+Lt9kkX0ocuoinwKd8o&quot;&gt;&lt;g data-tid=&quot;gtJu+Lt9kkX0ocuoinwKd8o&quot; class=&quot;typst-group&quot;&gt;&lt;g transform=&quot;translate(0.000,7.513)&quot; data-tid=&quot;pwbp8wzGfeOsHu4HiOMm6Ro&quot;&gt;&lt;g data-tid=&quot;gwbp8wzGfeOsHu4HiOMm6Ro&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RU&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;4-4&quot;&gt;4&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(5.500,7.513)&quot; data-tid=&quot;pNEBB2iCTdcgRNjY8GzZQho&quot;&gt;&lt;g data-tid=&quot;gNEBB2iCTdcgRNjY8GzZQho&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RE&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;0-11&quot;&gt;0&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(11.000,7.513)&quot; data-tid=&quot;pNEBB2iCTdcgRNjY8GzZQho&quot;&gt;&lt;g data-tid=&quot;gNEBB2iCTdcgRNjY8GzZQho&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RE&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;0-12&quot;&gt;0&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(16.500,7.513)&quot; data-tid=&quot;pNEBB2iCTdcgRNjY8GzZQho&quot;&gt;&lt;g data-tid=&quot;gNEBB2iCTdcgRNjY8GzZQho&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RE&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;0-13&quot;&gt;0&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(24.444,7.513)&quot; data-tid=&quot;paKe2osoRM6IVnum1y/PQis&quot;&gt;&lt;g data-tid=&quot;gaKe2osoRM6IVnum1y/PQis&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1YgE&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;17.38&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;-9&quot;&gt;⋅&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(29.947,7.513)&quot; data-tid=&quot;pxJGQF2BzQ+4a4/wP0tpidI&quot;&gt;&lt;g data-tid=&quot;gxJGQF2BzQ+4a4/wP0tpidI&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1Rc&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;6-2&quot;&gt;6&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(35.447,7.513)&quot; data-tid=&quot;pwbp8wzGfeOsHu4HiOMm6Ro&quot;&gt;&lt;g data-tid=&quot;gwbp8wzGfeOsHu4HiOMm6Ro&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RU&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;4-5&quot;&gt;4&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(42.780,7.513)&quot; data-tid=&quot;pLFmDkkl2VnkR3tg2pHkKwg&quot;&gt;&lt;g data-tid=&quot;gLFmDkkl2VnkR3tg2pHkKwg&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1SM&quot;&gt;&lt;/use&gt;&lt;use x=&quot;708&quot; y=&quot;0&quot; href=&quot;#gl3Hi1Uo&quot;&gt;&lt;/use&gt;&lt;use x=&quot;986&quot; y=&quot;0&quot; href=&quot;#gl3Hi1VU&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;85.94&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;bit-3&quot;&gt;Bit&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(1.100,12.210)&quot; data-tid=&quot;p0NlWTWhLRE0KuJYJp2VFqI&quot;&gt;&lt;g data-tid=&quot;g0NlWTWhLRE0KuJYJp2VFqI&quot;&gt;&lt;path class=&quot;typst-shape&quot; d=&quot;M 0 0 L 244.61922 0 &quot; stroke-width=&quot;0.528&quot; stroke-miterlimit=&quot;4&quot; fill-rule=&quot;nonzero&quot; fill=&quot;none&quot; stroke=&quot;#000&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(249.875,14.960)&quot; data-tid=&quot;pe2SMhDFTNBs1fA0EQ/wClI&quot;&gt;&lt;g data-tid=&quot;ge2SMhDFTNBs1fA0EQ/wClI&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1R4&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;48.62&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;-10&quot;&gt;=&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(261.488,0.066)&quot; data-tid=&quot;pperXNxw5NzkSGir8jmN/0M&quot;&gt;&lt;g data-tid=&quot;gperXNxw5NzkSGir8jmN/0M&quot; class=&quot;typst-group&quot;&gt;&lt;g transform=&quot;translate(1.100,7.447)&quot; data-tid=&quot;pNEBB2iCTdcgRNjY8GzZQho&quot;&gt;&lt;g data-tid=&quot;gNEBB2iCTdcgRNjY8GzZQho&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RE&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;0-14&quot;&gt;0&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(6.600,7.447)&quot; data-tid=&quot;pKx4gjRFV/cIK7g2K0zE0Ls&quot;&gt;&lt;g data-tid=&quot;gKx4gjRFV/cIK7g2K0zE0Ls&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1Q8&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;17.38&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;-11&quot;&gt;.&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(9.658,7.447)&quot; data-tid=&quot;pxJGQF2BzQ+4a4/wP0tpidI&quot;&gt;&lt;g data-tid=&quot;gxJGQF2BzQ+4a4/wP0tpidI&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1Rc&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;6-3&quot;&gt;6&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(15.158,7.447)&quot; data-tid=&quot;pwlJuD0gd0A42R1nn6oR5kg&quot;&gt;&lt;g data-tid=&quot;gwlJuD0gd0A42R1nn6oR5kg&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RY&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;5-2&quot;&gt;5&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(23.102,7.447)&quot; data-tid=&quot;paKe2osoRM6IVnum1y/PQis&quot;&gt;&lt;g data-tid=&quot;gaKe2osoRM6IVnum1y/PQis&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1YgE&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;17.38&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;-12&quot;&gt;⋅&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(28.605,7.447)&quot; data-tid=&quot;pLD8LidN0y2EDhKLTsSRMzg&quot;&gt;&lt;g data-tid=&quot;gLD8LidN0y2EDhKLTsSRMzg&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1Rk&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;8-1&quot;&gt;8&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(36.549,7.447)&quot; data-tid=&quot;peHf8J65SCGMjHTtShtQPow&quot;&gt;&lt;g data-tid=&quot;geHf8J65SCGMjHTtShtQPow&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1Qw&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;48.62&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;-13&quot;&gt;+&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(47.552,7.447)&quot; data-tid=&quot;pNEBB2iCTdcgRNjY8GzZQho&quot;&gt;&lt;g data-tid=&quot;gNEBB2iCTdcgRNjY8GzZQho&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RE&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;0-15&quot;&gt;0&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(53.052,7.447)&quot; data-tid=&quot;pKx4gjRFV/cIK7g2K0zE0Ls&quot;&gt;&lt;g data-tid=&quot;gKx4gjRFV/cIK7g2K0zE0Ls&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1Q8&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;17.38&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;-14&quot;&gt;.&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(56.110,7.447)&quot; data-tid=&quot;pswt4MVJEPlsBqVisNkNgbc&quot;&gt;&lt;g data-tid=&quot;gswt4MVJEPlsBqVisNkNgbc&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RQ&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;3-1&quot;&gt;3&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(61.610,7.447)&quot; data-tid=&quot;pwlJuD0gd0A42R1nn6oR5kg&quot;&gt;&lt;g data-tid=&quot;gwlJuD0gd0A42R1nn6oR5kg&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RY&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;5-3&quot;&gt;5&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(69.554,7.447)&quot; data-tid=&quot;paKe2osoRM6IVnum1y/PQis&quot;&gt;&lt;g data-tid=&quot;gaKe2osoRM6IVnum1y/PQis&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1YgE&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;17.38&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;-15&quot;&gt;⋅&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(75.057,7.447)&quot; data-tid=&quot;pxJGQF2BzQ+4a4/wP0tpidI&quot;&gt;&lt;g data-tid=&quot;gxJGQF2BzQ+4a4/wP0tpidI&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1Rc&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;6-4&quot;&gt;6&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(80.557,7.447)&quot; data-tid=&quot;pwbp8wzGfeOsHu4HiOMm6Ro&quot;&gt;&lt;g data-tid=&quot;gwbp8wzGfeOsHu4HiOMm6Ro&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RU&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;4-6&quot;&gt;4&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(88.501,7.447)&quot; data-tid=&quot;peHf8J65SCGMjHTtShtQPow&quot;&gt;&lt;g data-tid=&quot;geHf8J65SCGMjHTtShtQPow&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1Qw&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;48.62&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;-16&quot;&gt;+&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(99.504,7.447)&quot; data-tid=&quot;pDIkrPr4ePGsCHO9XNLQ38Y&quot;&gt;&lt;g data-tid=&quot;gDIkrPr4ePGsCHO9XNLQ38Y&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RI&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;1-1&quot;&gt;1&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(47.552,22.440)&quot; data-tid=&quot;pxJGQF2BzQ+4a4/wP0tpidI&quot;&gt;&lt;g data-tid=&quot;gxJGQF2BzQ+4a4/wP0tpidI&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1Rc&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;6-5&quot;&gt;6&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(53.052,22.440)&quot; data-tid=&quot;pwbp8wzGfeOsHu4HiOMm6Ro&quot;&gt;&lt;g data-tid=&quot;gwbp8wzGfeOsHu4HiOMm6Ro&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RU&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;4-7&quot;&gt;4&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(1.100,12.144)&quot; data-tid=&quot;poSw+CLiQEFEVivOPgPPDkg&quot;&gt;&lt;g data-tid=&quot;goSw+CLiQEFEVivOPgPPDkg&quot;&gt;&lt;path class=&quot;typst-shape&quot; d=&quot;M 0 0 L 103.90356 0 &quot; stroke-width=&quot;0.528&quot; stroke-miterlimit=&quot;4&quot; fill-rule=&quot;nonzero&quot; fill=&quot;none&quot; stroke=&quot;#000&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(370.647,14.960)&quot; data-tid=&quot;pENhJ+351gdor1JuaMQNJOY&quot;&gt;&lt;g data-tid=&quot;gENhJ+351gdor1JuaMQNJOY&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1QsE&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;48.31&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;-17&quot;&gt;≈&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(382.206,14.960)&quot; data-tid=&quot;pNEBB2iCTdcgRNjY8GzZQho&quot;&gt;&lt;g data-tid=&quot;gNEBB2iCTdcgRNjY8GzZQho&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RE&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;0-16&quot;&gt;0&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(387.706,14.960)&quot; data-tid=&quot;pKx4gjRFV/cIK7g2K0zE0Ls&quot;&gt;&lt;g data-tid=&quot;gKx4gjRFV/cIK7g2K0zE0Ls&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1Q8&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;17.38&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;-18&quot;&gt;.&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(390.764,14.960)&quot; data-tid=&quot;pwbp8wzGfeOsHu4HiOMm6Ro&quot;&gt;&lt;g data-tid=&quot;gwbp8wzGfeOsHu4HiOMm6Ro&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RU&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;4-8&quot;&gt;4&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(396.264,14.960)&quot; data-tid=&quot;pwlJuD0gd0A42R1nn6oR5kg&quot;&gt;&lt;g data-tid=&quot;gwlJuD0gd0A42R1nn6oR5kg&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RY&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;5-4&quot;&gt;5&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(0.000,0.000)&quot; data-tid=&quot;pDdHKzdBRei08VsADJf8vXM&quot;&gt;&lt;g data-tid=&quot;gDdHKzdBRei08VsADJf8vXM&quot; class=&quot;typst-content-hint&quot; data-hint=&quot;a&quot;&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(0.000,0.000)&quot; data-tid=&quot;pDdHKzdBRei08VsADJf8vXM&quot;&gt;&lt;g data-tid=&quot;gDdHKzdBRei08VsADJf8vXM&quot; class=&quot;typst-content-hint&quot; data-hint=&quot;a&quot;&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;/svg&gt;
&lt;p&gt;compared to the &lt;code&gt;float32&lt;/code&gt; compression of
&lt;svg style=&quot;vertical-align:-0.5445454545454546em&quot; class=&quot;typst-doc&quot; viewBox=&quot;0 0 91.000 19.000&quot; width=&quot;8.272727272727273em&quot; height=&quot;1.7272727272727273em&quot; data-width=&quot;91.000&quot; data-height=&quot;19.000&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; xmlns:h5=&quot;http://www.w3.org/1999/xhtml&quot;&gt;&lt;style type=&quot;text/css&quot;&gt;.typst-text {
  pointer-events: bounding-box;
}

.tsel span,
.tsel {
  left: 0;
  position: fixed;
  text-align: justify;
  white-space: nowrap;
  width: 100%;
  height: 100%;
  text-align-last: justify;
  color: transparent;
  white-space: pre;
}
.tsel span::-moz-selection,
.tsel::-moz-selection {
  color: transparent;
  background: #7db9dea0;
}
.tsel span::selection,
.tsel::selection {
  color: transparent;
  background: #7db9dea0;
}
.pseudo-link {
  fill: transparent;
  cursor: pointer;
  pointer-events: all;
}
svg {
  fill: none;
}

.outline_glyph path,
path.outline_glyph {
  fill: var(--glyph_fill);
  stroke: var(--glyph_stroke);
}

.outline_glyph path,
path.outline_glyph {
  transition: 0.2s fill stroke;
}
.hover .typst-text {
  --glyph_fill: #66bab7;
  --glyph_stroke: #66bab7;
}

.typst-jump-ripple,
.typst-debug-react-ripple {
  width: 0;
  height: 0;
  background-color: transparent;
  position: absolute;
  border-radius: 50%;
}
.typst-jump-ripple {
  border: 1px solid #66bab7;
}
.typst-debug-react-ripple {
  border: 1px solid #cb1b45;
}
@keyframes typst-jump-ripple-effect {
  to {
    width: 10vw;
    height: 10vw;
    opacity: 0.01;
    margin: -5vw;
  }
}
@keyframes typst-debug-react-ripple-effect {
  to {
    width: 3vw;
    height: 3vw;
    opacity: 0.01;
    margin: -1.5vw;
  }
}
&lt;/style&gt;&lt;defs class=&quot;glyph&quot;&gt;&lt;path id=&quot;gl3Hi1Q8&quot; class=&quot;outline_glyph&quot; d=&quot;M 192 53 C 192 82 168 106 139 106 C 110 106 86 82 86 53 C 86 24 110 0 139 0 C 168 0 192 24 192 53 Z &quot;&gt;&lt;/path&gt;&lt;path id=&quot;gl3Hi1RA&quot; class=&quot;outline_glyph&quot; d=&quot;M 444 718 C 445 720 445 723 445 726 C 445 742 437 750 421 750 C 410 750 403 745 399 734 L 57 -218 C 56 -220 56 -223 56 -226 C 56 -242 64 -250 80 -250 C 91 -250 98 -245 102 -234 Z &quot;&gt;&lt;/path&gt;&lt;path id=&quot;gl3Hi1RE&quot; class=&quot;outline_glyph&quot; d=&quot;M 249 -22 C 390 -22 460 92 460 320 C 460 473 428 575 365 625 C 330 652 291 666 250 666 C 109 666 39 551 39 320 C 39 136 88 -22 249 -22 Z M 361 524 C 368 489 371 425 371 332 C 371 240 367 172 360 128 C 347 48 310 8 249 8 C 226 8 203 17 182 34 C 155 57 139 104 132 176 C 129 201 128 253 128 332 C 128 419 131 480 136 513 C 145 568 163 603 191 618 C 213 630 232 636 249 636 C 314 636 350 583 361 524 Z &quot;&gt;&lt;/path&gt;&lt;path id=&quot;gl3Hi1RM&quot; class=&quot;outline_glyph&quot; d=&quot;M 237 666 C 186 666 143 648 106 612 C 69 576 50 534 50 483 C 50 449 75 424 106 424 C 136 424 161 450 161 480 C 161 513 137 536 105 536 C 102 536 100 536 98 535 C 117 584 161 627 224 627 C 306 627 352 556 352 470 C 352 403 318 331 250 255 L 62 43 C 49 28 50 29 50 0 L 421 0 L 450 180 L 417 180 C 409 129 402 100 396 91 C 391 86 361 84 306 84 L 139 84 L 236 179 C 304 243 390 312 419 365 C 439 400 449 435 449 470 C 449 588 357 666 237 666 Z &quot;&gt;&lt;/path&gt;&lt;path id=&quot;gl3Hi1RQ&quot; class=&quot;outline_glyph&quot; d=&quot;M 303 353 C 369 378 431 441 431 526 C 431 569 410 604 369 631 C 333 654 292 666 246 666 C 201 666 162 654 127 631 C 88 605 68 571 68 528 C 68 495 90 472 122 472 C 154 472 176 495 176 527 C 176 560 157 578 119 580 C 145 615 186 633 242 633 C 302 633 332 598 332 527 C 332 485 324 450 309 421 C 282 373 245 364 183 364 C 171 362 165 357 165 348 C 165 333 172 333 192 333 L 235 333 C 310 333 348 280 348 173 C 348 88 317 14 241 14 C 176 14 128 36 99 80 C 134 79 160 105 160 139 C 160 173 135 198 101 198 C 62 198 42 178 42 137 C 42 88 64 49 108 18 C 147 -9 193 -22 244 -22 C 301 -22 350 -3 393 34 C 436 71 457 117 457 173 C 457 267 383 332 303 353 Z &quot;&gt;&lt;/path&gt;&lt;path id=&quot;gl3Hi1RU&quot; class=&quot;outline_glyph&quot; d=&quot;M 353 677 C 344 677 336 672 330 663 L 28 199 L 28 163 L 289 163 L 289 81 C 289 63 285 51 278 46 C 271 41 252 39 219 39 L 194 39 L 194 0 C 223 2 269 3 331 3 C 393 3 439 2 468 0 L 468 39 L 443 39 C 410 39 391 41 384 46 C 377 51 373 63 373 81 L 373 163 L 471 163 L 471 202 L 373 202 L 373 660 C 373 670 366 677 353 677 Z M 295 553 L 295 202 L 67 202 Z &quot;&gt;&lt;/path&gt;&lt;path id=&quot;gl3Hi1RY&quot; class=&quot;outline_glyph&quot; d=&quot;M 118 315 C 123 315 129 319 134 326 C 164 371 205 393 257 393 C 292 393 319 373 337 332 C 348 305 354 264 354 209 C 354 146 346 102 331 76 C 306 35 272 14 229 14 C 162 14 109 62 91 114 C 94 113 96 114 100 114 C 130 114 155 137 155 167 C 155 198 130 219 100 219 C 65 219 50 200 50 163 C 50 63 131 -22 231 -22 C 292 -22 344 0 386 44 C 428 88 449 141 449 202 C 449 260 432 310 398 353 C 361 400 315 423 259 423 C 212 423 171 408 138 378 L 138 556 C 165 548 191 544 218 544 C 264 544 304 555 338 578 C 369 597 390 616 402 634 C 408 642 411 648 411 651 C 411 661 406 666 396 666 C 341 645 294 634 256 634 C 211 634 168 643 127 662 C 122 664 118 665 114 665 C 105 665 100 656 100 637 L 100 345 C 100 324 100 315 118 315 Z &quot;&gt;&lt;/path&gt;&lt;path id=&quot;gl3Hi1Rc&quot; class=&quot;outline_glyph&quot; d=&quot;M 383 504 C 416 504 432 521 432 555 C 432 627 378 666 304 666 C 221 666 155 627 106 548 C 63 480 42 403 42 316 C 42 189 65 100 112 47 C 152 1 198 -22 251 -22 C 312 -22 362 1 401 47 C 438 91 457 144 457 205 C 457 266 439 318 403 361 C 365 407 316 431 257 431 C 205 431 165 402 138 346 L 138 352 C 138 465 166 561 226 605 C 252 624 279 633 306 633 C 342 633 368 623 385 602 C 351 602 334 583 334 553 C 334 525 355 504 383 504 Z M 344 340 C 355 317 361 272 361 206 C 361 141 356 98 345 76 C 325 35 294 14 251 14 C 222 14 200 24 184 44 C 171 60 162 74 158 85 C 146 116 140 163 140 227 C 140 255 144 282 151 308 C 164 355 201 399 256 399 C 295 399 325 379 344 340 Z &quot;&gt;&lt;/path&gt;&lt;path id=&quot;gl3Hi1R4&quot; class=&quot;outline_glyph&quot; d=&quot;M 698 367 L 80 367 C 64 367 56 359 56 344 C 56 329 64 321 80 321 L 698 321 C 714 321 722 329 722 344 C 722 356 711 367 698 367 Z M 698 179 L 80 179 C 64 179 56 171 56 156 C 56 141 64 133 80 133 L 698 133 C 714 133 722 141 722 156 C 722 169 711 179 698 179 Z &quot;&gt;&lt;/path&gt;&lt;path id=&quot;gl3Hi1SM&quot; class=&quot;outline_glyph&quot; d=&quot;M 478 358 C 548 376 624 432 624 512 C 624 565 599 607 549 640 C 506 669 456 683 401 683 L 36 683 L 36 644 L 64 644 C 99 644 120 641 127 636 C 134 631 138 620 138 602 L 138 81 C 138 63 134 51 127 46 C 120 41 99 39 64 39 L 36 39 L 36 0 L 427 0 C 484 0 535 16 579 48 C 627 83 651 129 651 185 C 651 278 563 342 478 358 Z M 521 512 C 521 428 451 370 367 370 L 228 370 L 228 609 C 228 645 233 644 272 644 L 394 644 C 468 644 521 586 521 512 Z M 544 186 L 544 160 C 542 137 529 111 504 84 C 478 54 442 39 395 39 L 272 39 C 233 39 228 38 228 74 L 228 340 L 409 340 C 490 340 544 270 544 186 Z &quot;&gt;&lt;/path&gt;&lt;path id=&quot;gl3Hi1Uo&quot; class=&quot;outline_glyph&quot; d=&quot;M 194 601 C 194 631 169 657 139 657 C 109 657 83 631 83 601 C 83 571 108 544 138 544 C 169 544 194 570 194 601 Z M 143 3 L 247 0 L 247 39 C 214 39 194 41 188 45 C 182 49 180 60 180 78 L 180 445 L 37 433 L 37 395 C 70 395 91 392 98 387 C 105 382 108 368 108 345 L 108 79 C 108 60 105 48 98 44 C 91 40 69 39 33 39 L 33 0 Z &quot;&gt;&lt;/path&gt;&lt;path id=&quot;gl3Hi1VU&quot; class=&quot;outline_glyph&quot; d=&quot;M 332 126 L 332 186 L 300 186 L 300 128 C 300 78 282 22 238 22 C 197 22 177 56 177 124 L 177 395 L 316 395 L 316 433 L 177 433 L 177 615 L 145 615 C 144 582 141 553 134 527 C 117 461 78 427 19 424 L 19 395 L 102 395 L 102 126 C 102 67 120 29 155 10 C 182 -4 207 -11 232 -11 C 298 -11 332 55 332 126 Z &quot;&gt;&lt;/path&gt;&lt;/defs&gt;&lt;defs class=&quot;clip-path&quot;&gt;&lt;/defs&gt;&lt;style type=&quot;text/css&quot;&gt;&lt;/style&gt;&lt;g class=&quot;typst-page&quot; transform=&quot;translate(0, 0)&quot; data-tid=&quot;pCVe4dyzBUnU/P9cObpM1rQ&quot; data-page-width=&quot;91&quot; data-page-height=&quot;19&quot;&gt;&lt;g data-tid=&quot;gCVe4dyzBUnU/P9cObpM1rQ&quot; class=&quot;typst-group&quot;&gt;&lt;g transform=&quot;translate(0.000,0.000)&quot; data-tid=&quot;pxvKVMcrDcAIWw7yAQtpvNg&quot;&gt;&lt;g data-tid=&quot;gxvKVMcrDcAIWw7yAQtpvNg&quot; class=&quot;typst-group&quot;&gt;&lt;g transform=&quot;translate(0.000,0.000)&quot; data-tid=&quot;pv3I5/AuomQYIvFTedS2bjs&quot;&gt;&lt;g data-tid=&quot;gv3I5/AuomQYIvFTedS2bjs&quot; class=&quot;typst-group&quot;&gt;&lt;g transform=&quot;translate(0.000,13.013)&quot; data-tid=&quot;pswt4MVJEPlsBqVisNkNgbc&quot;&gt;&lt;g data-tid=&quot;gswt4MVJEPlsBqVisNkNgbc&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RQ&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;3-2&quot;&gt;3&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(5.500,13.013)&quot; data-tid=&quot;pl6hzOpmqI5osHVosdjGGwc&quot;&gt;&lt;g data-tid=&quot;gl6hzOpmqI5osHVosdjGGwc&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RM&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;2&quot;&gt;2&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(12.833,13.013)&quot; data-tid=&quot;pLFmDkkl2VnkR3tg2pHkKwg&quot;&gt;&lt;g data-tid=&quot;gLFmDkkl2VnkR3tg2pHkKwg&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1SM&quot;&gt;&lt;/use&gt;&lt;use x=&quot;708&quot; y=&quot;0&quot; href=&quot;#gl3Hi1Uo&quot;&gt;&lt;/use&gt;&lt;use x=&quot;986&quot; y=&quot;0&quot; href=&quot;#gl3Hi1VU&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;85.94&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;bit-4&quot;&gt;Bit&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(27.958,13.013)&quot; data-tid=&quot;p5XBiwHD8UAY0ET8t36wrCk&quot;&gt;&lt;g data-tid=&quot;g5XBiwHD8UAY0ET8t36wrCk&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RA&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;-19&quot;&gt;/&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(33.458,13.013)&quot; data-tid=&quot;pxJGQF2BzQ+4a4/wP0tpidI&quot;&gt;&lt;g data-tid=&quot;gxJGQF2BzQ+4a4/wP0tpidI&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1Rc&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;6-6&quot;&gt;6&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(38.958,13.013)&quot; data-tid=&quot;pwbp8wzGfeOsHu4HiOMm6Ro&quot;&gt;&lt;g data-tid=&quot;gwbp8wzGfeOsHu4HiOMm6Ro&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RU&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;4-9&quot;&gt;4&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(46.292,13.013)&quot; data-tid=&quot;pLFmDkkl2VnkR3tg2pHkKwg&quot;&gt;&lt;g data-tid=&quot;gLFmDkkl2VnkR3tg2pHkKwg&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1SM&quot;&gt;&lt;/use&gt;&lt;use x=&quot;708&quot; y=&quot;0&quot; href=&quot;#gl3Hi1Uo&quot;&gt;&lt;/use&gt;&lt;use x=&quot;986&quot; y=&quot;0&quot; href=&quot;#gl3Hi1VU&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;85.94&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;bit-5&quot;&gt;Bit&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(64.472,13.013)&quot; data-tid=&quot;pe2SMhDFTNBs1fA0EQ/wClI&quot;&gt;&lt;g data-tid=&quot;ge2SMhDFTNBs1fA0EQ/wClI&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1R4&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;48.62&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;-20&quot;&gt;=&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(76.086,13.013)&quot; data-tid=&quot;pNEBB2iCTdcgRNjY8GzZQho&quot;&gt;&lt;g data-tid=&quot;gNEBB2iCTdcgRNjY8GzZQho&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RE&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;0-17&quot;&gt;0&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(81.586,13.013)&quot; data-tid=&quot;pKx4gjRFV/cIK7g2K0zE0Ls&quot;&gt;&lt;g data-tid=&quot;gKx4gjRFV/cIK7g2K0zE0Ls&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1Q8&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;17.38&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;-21&quot;&gt;.&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(84.644,13.013)&quot; data-tid=&quot;pwlJuD0gd0A42R1nn6oR5kg&quot;&gt;&lt;g data-tid=&quot;gwlJuD0gd0A42R1nn6oR5kg&quot; class=&quot;typst-text&quot; fill=&quot;#000&quot; transform=&quot;scale(0.011,-0.011)&quot;&gt;&lt;use x=&quot;0&quot; y=&quot;0&quot; href=&quot;#gl3Hi1RY&quot;&gt;&lt;/use&gt;&lt;g transform=&quot;scale(16,-16)&quot;&gt;&lt;foreignObject x=&quot;0&quot; y=&quot;-50.38&quot; width=&quot;31.25&quot; height=&quot;62.50&quot;&gt;&lt;h5:div class=&quot;tsel&quot; style=&quot;font-size:62px&quot; id=&quot;5-5&quot;&gt;5&lt;/h5:div&gt;&lt;/foreignObject&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(0.000,0.000)&quot; data-tid=&quot;pDdHKzdBRei08VsADJf8vXM&quot;&gt;&lt;g data-tid=&quot;gDdHKzdBRei08VsADJf8vXM&quot; class=&quot;typst-content-hint&quot; data-hint=&quot;a&quot;&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;/svg&gt;.
So better theoretical compression performance while staying lossless.&lt;/p&gt;
&lt;h2 id=&quot;further-optimizations&quot;&gt;&lt;a href=&quot;#further-optimizations&quot;&gt;Further optimizations&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;All the arrays that we have talked about have the same length, namely the number
of nodes in the tree. But when thinking about it, the leaves don’t really need a
left/right child, a corresponding feature or threshold. It only needs the value.
That’s why the values in the &lt;code&gt;children_left&lt;/code&gt; and &lt;code&gt;children_right&lt;/code&gt; fields are &lt;code&gt;-1&lt;/code&gt;
there and the value of &lt;code&gt;features&lt;/code&gt; and &lt;code&gt;thresholds&lt;/code&gt; are &lt;code&gt;-2&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We can just delete these elements and save some space again by creating a &lt;code&gt;bool&lt;/code&gt;
array &lt;code&gt;is_leaf&lt;/code&gt; that is used as a mask for getting and setting the corresponding
values.&lt;/p&gt;
&lt;pre class=&quot;astro-code catppuccin-mocha&quot; style=&quot;background-color:#1e1e2e;color:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;py&quot;&gt;&lt;code class=&quot;code-highlight&quot;&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#89B4FA;font-style:italic&quot;&gt; compress_tree_state&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;state&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#CBA6F7;font-style:italic&quot;&gt; dict&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    ...&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    is_leaf &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; nodes&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1;font-style:italic&quot;&gt;left_child&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; ==&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    is_not_leaf &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; np&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;logical_not&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;is_leaf&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2;font-style:italic&quot;&gt;    # feature, threshold and children are irrelevant for leaves&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    children_left &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; nodes&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1;font-style:italic&quot;&gt;left_child&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;][&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;is_not_leaf&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;].&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;astype&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;dtype_child&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    children_right &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; nodes&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1;font-style:italic&quot;&gt;right_child&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;][&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;is_not_leaf&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;].&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;astype&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;dtype_child&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    features &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; nodes&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1;font-style:italic&quot;&gt;feature&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;][&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;is_not_leaf&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;].&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;astype&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;dtype_feature&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2;font-style:italic&quot;&gt;    # do lossless compression for thresholds by downcasting&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2;font-style:italic&quot;&gt;    # half ints (e.g. 5.5, 10.5, ...) to dtype_halfint&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    thresholds &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; nodes&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1;font-style:italic&quot;&gt;threshold&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;][&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;is_not_leaf&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;].&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;astype&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;dtype_threshold&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    thresholds &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt; compress_half_int_float_array&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;thresholds&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; dtype_halfint&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2;font-style:italic&quot;&gt;    # value is irrelevant when node is not a leaf&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    values &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; state&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1;font-style:italic&quot;&gt;values&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;][&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;is_leaf&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;].&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;astype&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;dtype_value&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    ...&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#89B4FA;font-style:italic&quot;&gt; decompress_tree_state&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;state&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#CBA6F7;font-style:italic&quot;&gt; dict&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    ...&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    n_edges &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#FAB387;font-style:italic&quot;&gt; len&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;is_leaf&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    children_left &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; np&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;empty&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;n_edges&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; dtype&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;np&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;int64&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    children_right &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; np&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;empty&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;n_edges&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; dtype&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;np&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;int64&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    features &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; np&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;empty&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;n_edges&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; dtype&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;np&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;int64&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    thresholds &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; np&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;empty&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;n_edges&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; dtype&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;np&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;float64&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2;font-style:italic&quot;&gt;    # same shape as values but with all edges instead of only the leaves&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    values &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; np&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;zeros&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;n_edges&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;state&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1;font-style:italic&quot;&gt;values&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;].&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;shape&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#FAB387;font-style:italic&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;:]),&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; dtype&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;np&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;float64&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;    children_left&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;is_not_leaf&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; state&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1;font-style:italic&quot;&gt;children_left&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;    children_left&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;is_leaf&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#9399B2;font-style:italic&quot;&gt;  # child of leaves is -1&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;    children_right&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;is_not_leaf&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; state&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1;font-style:italic&quot;&gt;children_right&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;    children_right&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;is_leaf&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#9399B2;font-style:italic&quot;&gt;  # child of leaves is -1&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;    features&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;is_not_leaf&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; state&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1;font-style:italic&quot;&gt;features&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;    features&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;is_leaf&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#9399B2;font-style:italic&quot;&gt;  # feature of leaves is -2&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;    thresholds&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;is_not_leaf&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt; decompress_half_int_float_array&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;state&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1;font-style:italic&quot;&gt;thresholds&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;])&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;    thresholds&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;is_leaf&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#FAB387&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#9399B2;font-style:italic&quot;&gt;  # threshold of leaves is -2&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;    values&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;is_leaf&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; state&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1;font-style:italic&quot;&gt;values&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    ...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;button class=&quot;copy-btn&quot; aria-label=&quot;Copy code&quot; data-copy-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;rect x=&amp;#34;9&amp;#34; y=&amp;#34;9&amp;#34; width=&amp;#34;13&amp;#34; height=&amp;#34;13&amp;#34; rx=&amp;#34;2&amp;#34; ry=&amp;#34;2&amp;#34;/&gt;&lt;path d=&amp;#34;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&amp;#34;/&gt;&lt;/svg&gt;&quot; data-check-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;polyline points=&amp;#34;20 6 9 17 4 12&amp;#34;/&gt;&lt;/svg&gt;&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;&lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/pre&gt;
&lt;h1 id=&quot;reconstructing-the-state-of-the-tree&quot;&gt;&lt;a href=&quot;#reconstructing-the-state-of-the-tree&quot;&gt;Reconstructing the state of the tree&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;To be able to reconstruct a &lt;code&gt;Tree&lt;/code&gt;, we need the exact same state format as in the
original, i.e., a dict with &lt;code&gt;max_depth&lt;/code&gt;, &lt;code&gt;node_count&lt;/code&gt;, &lt;code&gt;nodes&lt;/code&gt; and &lt;code&gt;values&lt;/code&gt;,
all in the same format as before. &lt;code&gt;nodes&lt;/code&gt; is actually a NumPy data type object as
mentioned before, so we need to specify the structure manually.&lt;/p&gt;
&lt;pre class=&quot;astro-code catppuccin-mocha&quot; style=&quot;background-color:#1e1e2e;color:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;py&quot;&gt;&lt;code class=&quot;code-highlight&quot;&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color:#89B4FA;font-style:italic&quot;&gt; decompress_tree_state&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;state&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#CBA6F7;font-style:italic&quot;&gt; dict&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    ...&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    dtype &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; np&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;dtype&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;([(&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;left_child&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; &amp;#39;&amp;lt;i8&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;),&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;right_child&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; &amp;#39;&amp;lt;i8&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;                      (&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;feature&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; &amp;#39;&amp;lt;i8&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;),&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;threshold&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; &amp;#39;&amp;lt;f8&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;                      (&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;impurity&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; &amp;#39;&amp;lt;f8&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;),&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;n_node_samples&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; &amp;#39;&amp;lt;i8&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;                      (&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;weighted_n_node_samples&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt; &amp;#39;&amp;lt;f8&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)])&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    nodes &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; np&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;zeros&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;n_edges&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; dtype&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;dtype&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;    nodes&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1;font-style:italic&quot;&gt;left_child&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; children_left&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;    nodes&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1;font-style:italic&quot;&gt;right_child&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; children_right&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;    nodes&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1;font-style:italic&quot;&gt;feature&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; features&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt;    nodes&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1;font-style:italic&quot;&gt;threshold&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; thresholds&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;max_depth&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; state&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1;font-style:italic&quot;&gt;max_depth&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;            &amp;#39;node_count&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; state&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1;font-style:italic&quot;&gt;node_count&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;],&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;            &amp;#39;nodes&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; nodes&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;            &amp;#39;values&amp;#39;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; values&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;button class=&quot;copy-btn&quot; aria-label=&quot;Copy code&quot; data-copy-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;rect x=&amp;#34;9&amp;#34; y=&amp;#34;9&amp;#34; width=&amp;#34;13&amp;#34; height=&amp;#34;13&amp;#34; rx=&amp;#34;2&amp;#34; ry=&amp;#34;2&amp;#34;/&gt;&lt;path d=&amp;#34;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&amp;#34;/&gt;&lt;/svg&gt;&quot; data-check-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;polyline points=&amp;#34;20 6 9 17 4 12&amp;#34;/&gt;&lt;/svg&gt;&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;&lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/pre&gt;
&lt;h1 id=&quot;compression-errors&quot;&gt;&lt;a href=&quot;#compression-errors&quot;&gt;Compression errors&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;In our production example, we tested the predictions on a dataset with 3 500 000
entries. The average compression error was at &lt;code&gt;5.59e-8&lt;/code&gt;, there were
8 / 3 500 000 elements with a prediction error &lt;code&gt;&amp;gt; 1e-4&lt;/code&gt; with the largest error being
&lt;code&gt;2.87e-4&lt;/code&gt;. When we cumulate all prediction errors, we get an absolute error of &lt;code&gt;0.19&lt;/code&gt;.
For our use case, these errors are completely fine.&lt;/p&gt;
&lt;h1 id=&quot;discussion&quot;&gt;&lt;a href=&quot;#discussion&quot;&gt;Discussion&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;In our production example, we could shrink down the model size from 496 MB to
128 MB, i.e., compress the model to 26% of its original size.&lt;/p&gt;
&lt;p&gt;One can also use a compression algorithm like &lt;code&gt;gzip&lt;/code&gt; or &lt;code&gt;lzma&lt;/code&gt; to compress the model
even further. We tried out &lt;code&gt;zstd&lt;/code&gt;, &lt;code&gt;gzip&lt;/code&gt;, &lt;code&gt;lzma&lt;/code&gt;, &lt;code&gt;bz2&lt;/code&gt; and &lt;code&gt;zlib&lt;/code&gt;.
We opted for &lt;code&gt;lzma&lt;/code&gt; because it is part of the Python stdlib and it yielded the best
compression results.
We managed to go down to 32 MB (without the extra &lt;code&gt;dtype&lt;/code&gt; reduction steps and only
&lt;code&gt;lzma&lt;/code&gt; compression we got to 144 MB, so we still get the model down to 22% of its
original “&lt;code&gt;lzma&lt;/code&gt; size”).&lt;/p&gt;
&lt;p&gt;These extra compression algorithms do bring additional startup time with them, though.
You can find the numbers at the &lt;a href=&quot;#numbers&quot;&gt;beginning of this blog post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This is although only the size on the disk. When you actually load the model,
these steps don’t help on reducing the size of the model in memory.
It still has its use cases, for example when providing a docker image that is as
small as possible.&lt;/p&gt;
&lt;pre class=&quot;astro-code catppuccin-mocha&quot; style=&quot;background-color:#1e1e2e;color:#cdd6f4;overflow-x:auto&quot; tabindex=&quot;0&quot; data-language=&quot;py&quot;&gt;&lt;code class=&quot;code-highlight&quot;&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2;font-style:italic&quot;&gt;# dump compressed&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;with&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; lzma&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;open&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;quot;/path/to/model.pickle.lzma&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; mode&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;quot;wb&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt; as&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; f&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;    dump_dtype_reduction&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;model&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; file&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9399B2;font-style:italic&quot;&gt;# load compressed&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt;with&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; lzma&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;open&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;quot;/path/to/model.pickle.lzma&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#EBA0AC;font-style:italic&quot;&gt; mode&lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#A6E3A1&quot;&gt;&amp;quot;rb&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#CBA6F7&quot;&gt; as&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; f&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&quot;code-line&quot;&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;    model_dtype_reduction &lt;/span&gt;&lt;span style=&quot;color:#94E2D5&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt; pickle&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#89B4FA&quot;&gt;load&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#CDD6F4&quot;&gt;file&lt;/span&gt;&lt;span style=&quot;color:#9399B2&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;button class=&quot;copy-btn&quot; aria-label=&quot;Copy code&quot; data-copy-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;rect x=&amp;#34;9&amp;#34; y=&amp;#34;9&amp;#34; width=&amp;#34;13&amp;#34; height=&amp;#34;13&amp;#34; rx=&amp;#34;2&amp;#34; ry=&amp;#34;2&amp;#34;/&gt;&lt;path d=&amp;#34;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&amp;#34;/&gt;&lt;/svg&gt;&quot; data-check-icon=&quot;&lt;svg width=&amp;#34;16&amp;#34; height=&amp;#34;16&amp;#34; viewBox=&amp;#34;0 0 24 24&amp;#34; fill=&amp;#34;none&amp;#34; stroke=&amp;#34;currentColor&amp;#34; stroke-width=&amp;#34;2&amp;#34; stroke-linecap=&amp;#34;round&amp;#34; stroke-linejoin=&amp;#34;round&amp;#34;&gt;&lt;polyline points=&amp;#34;20 6 9 17 4 12&amp;#34;/&gt;&lt;/svg&gt;&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;&gt;&lt;rect x=&quot;9&quot; y=&quot;9&quot; width=&quot;13&quot; height=&quot;13&quot; rx=&quot;2&quot; ry=&quot;2&quot;&gt;&lt;/rect&gt;&lt;path d=&quot;M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/button&gt;&lt;/pre&gt;
&lt;p&gt;Pickling has several disadvantages though like arbitrary code execution and no
version compatibility.
Uwe Korn did a blog post about the &lt;a href=&quot;https://uwekorn.com/2021/04/26/implications-of-pickling-ml-models.html&quot;&gt;implications of pickling ML models&lt;/a&gt;
and Ned Batchelder wrote one about &lt;a href=&quot;https://nedbatchelder.com/blog/202006/pickles_nine_flaws.html&quot;&gt;pickle’s nine flaws&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Another alternative could be using ONNX to compile the model. This also could
shrink down the model and improve the inference speed and the simplification of
deployment.
ONNX brings its own challenges though: you need create workflows to transform your
fitted model to ONNX which is not trivial for more complicated models.
Also, you would need to make sure that the converted ONNX model predicts
the same things as your original model.&lt;/p&gt;
&lt;p&gt;The code for this blog post can be found on &lt;a href=&quot;https://gist.github.com/pavelzw/1e5ba9ca5b102e463635f0943322a7d7&quot;&gt;GitHub Gist&lt;/a&gt;.
The whole procedure was tested on &lt;code&gt;scikit-learn=0.23.2&lt;/code&gt;,
the internal structure of &lt;code&gt;Tree&lt;/code&gt; may however change in upcoming versions.&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;This is a cross-post from the &lt;a href=&quot;https://tech.quantco.com/2023/08/25/polarify.html&quot;&gt;QuantCo blog&lt;/a&gt;.
Check out the other posts there!&lt;/p&gt;</content:encoded><category>sklearn</category><category>python</category><category>compression</category><category>pickling</category><author>pavelzw@gmail.com (Pavel Zwerschke)</author></item></channel></rss>