1. Overview
The Laegna number system is defined in a compact, discrete form and then extended step by step into a richer representation that can be used for visualizations and animations. The core idea is simple:
- numbers.json is the canonical, minimal description of the system.
- Extensions add derived information (bounds, floating values, octave structure).
- The result is written to
numberdatabase/complete.json. - From there, a separate step produces
animation.jsonfor timelines and visual tools.
This page explains the process in human language, so that the transformation from
numbers.json to animation.json can be understood and reproduced without
reading the Python source in detail.
2. The base data: numbers.json and numbers.bin.json
The starting point is a pair of files generated by decoder.py:
numbers.jsonnumbers.bin.json
These files contain:
- A list of chapters (for example,
R = 0.5, 1, 2, 3, 4). - For each chapter, a list of numbers.
- For each number, basic representations:
- Decimal (unsigned and signed forms).
- Laegna (symbolic or binary form).
- Wave (symbolic or binary form).
These base files deliberately avoid floating point, percentages, and octave calculations. They define a discrete, bounded number system that can be analyzed and extended in a controlled way.
3. The extension script: ApplyExtensions
The transformation from the base files to the extended dataset is handled by a Python script that
uses an ApplyExtensions class. Its job is to:
- Read the base files.
- Apply a sequence of extension modules.
- Write the enriched result to
numberdatabase/complete.json.
3.1 Reading the base files
The script starts by reading numbers.bin.json and numbers.json and merging
their chapters into a single in-memory structure:
apply = ApplyExtensions()
apply.reads()
After this step, apply.data contains:
metainformation (version, description).chapters: a list of chapter objects, each with:R,base, and other basic properties.numbers: the list of numbers in that chapter.
3.2 Applying extensions
Extensions are small classes with a use(self, apply) method. Each one adds a specific
layer of information to the data. The script applies them in a defined order:
apply.extend(ExtChapterBounds())
apply.extend(ExtFloat())
apply.extend(ExtChapterOrder())
apply.extend(ExtOctave())
4. Extension layers
4.1 ExtChapterBounds
This extension computes the numeric bounds for each chapter and stores them in a
Bounds object inside the chapter:
bounded: total bounded range (including some extra margin).full: the main range of the chapter.half: half of the main range.
For example, for R = 0.5 the bounds are fixed:
bounded = 6
full = 2
half = 1
For other chapters, they are computed from the chapter base and R:
bounded = base^R + 4
full = base^R
half = base^R / 2
These bounds are later used to normalize positions and signed values into percentages and units.
4.2 ExtFloat
This extension adds a Float object to each number. It introduces a continuous
interpretation of the discrete number, both unsigned and signed, relative to the chapter bounds.
For each number, it computes:
- Float.Value.Units: a 0..1 value representing the position inside the chapter.
- Float.Value.Percents: the same position as a percentage string (e.g.
"50.0%"). - Float.Num: a rounded percentage (e.g.
"50%"). - Float.Signed.Units: a signed value normalized to a −2..+2 range.
- Float.Signed.Percents: the signed value as a percentage string.
Special values such as "2inf", "-inf", "+inf", "-0",
and "+0" are mapped to appropriate positions within the chapter bounds so that the system
remains symmetric and well-behaved.
4.3 ExtOctave
This extension adds an Octave object to each number. It interprets the number in terms of
octave-like scaling, using helper functions that count bits and apply them in nested ways.
For each number, it computes:
- Octave.Num: the main octave value (taken from the “lower” octave).
- Octave.Lower.Num and Octave.Lower.Signed: lower-octave interpretations of the unsigned and signed positions.
- Octave.Higher.Num and Octave.Higher.Signed: higher-octave interpretations.
The octave functions use binary length and nested multipliers to map discrete positions into octave scales, giving a structured “waveweaver” view of the number.
4.4 ExtChapterOrder
This extension simply reorders the fields inside each chapter so that the numbers list
appears at the end. It does not change any values; it only ensures a consistent and readable layout
in the final JSON.
5. Writing numberdatabase/complete.json
After all extensions have been applied, the script writes the enriched data to:
numberdatabase/complete.json
This file contains:
- The original chapter and number structure from
numbers.jsonandnumbers.bin.json. - Per-chapter bounds (
Bounds). - Per-number floating and percentage values (
Float). - Per-number octave interpretations (
Octave).
It is the “complete” representation of the Laegna number system, suitable for further processing, analysis, and visualization.
6. From complete.json to animation.json
A separate script or tool reads numberdatabase/complete.json and builds:
- A flattened list of all numbers across all chapters.
- Global identifiers:
- Id.Num: 1-based index.
- Id.Zerobased.Num: 0-based index.
- An
animationlist that orders numbers frame by frame. - An
animation_chapterslist that records chapter names and their ids.
The result is written to animation.json, which can be used by animation players,
visualizers, and timeline tools. Each frame in the animation can be traced back to its original
number entry via the zero-based id, and from there to its chapter and all extended properties
(Float, Octave, Wave, Laegna, Decimal).
7. Adding new extensions
The extension system is designed to be open-ended. New derived properties can be added by defining
a new extension class with a use(self, apply) method that walks through
apply.data["chapters"] and their numbers, and attaches new fields.
A new extension follows this pattern:
class ExtMyFeature:
def use(self, apply):
for chapter in apply.data["chapters"]:
for number in chapter["numbers"]:
# compute something based on existing fields
number["MyFeature"] = ...
Once defined, it is added to the pipeline:
apply.extend(ExtMyFeature())
Running the script again regenerates numberdatabase/complete.json with the new feature
included, while the original numbers.json and numbers.bin.json remain
unchanged.
8. Reproducing the process
To reproduce the full pipeline from the base number system to the animation-ready data:
- Generate or obtain
numbers.jsonandnumbers.bin.jsonusingdecoder.py. - Run the extension script that:
- Reads the base files into
ApplyExtensions. - Applies
ExtChapterBounds,ExtFloat,ExtChapterOrder, andExtOctave. - Writes
numberdatabase/complete.json.
- Reads the base files into
- Use
complete.jsonas input to the animation builder, which:- Flattens numbers into a global list.
- Assigns
IdandzId. - Builds
animationandanimation_chapters. - Writes
animation.json.
This sequence preserves the integrity of the original number system while adding all the structure needed for analysis, visualization, and animation.