# core/analyzers/information.analyzer.ts

> 58 lines of code and 19 definitions.

Tree: GovLab Patterns
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/patterns#file-patterns-core-analyzers-information-analyzer-ts
Source text: https://banes-lab.com/source/patterns/core/analyzers/information.analyzer.ts.txt

Listed in [core/analyzers](https://banes-lab.com/api/source/patterns/core/analyzers.md), after [core/analyzers/field.analyzer.ts](https://banes-lab.com/source/patterns/core/analyzers/field.analyzer.ts.md) and before [core/analyzers/representation.distribution.analyzer.ts](https://banes-lab.com/source/patterns/core/analyzers/representation.distribution.analyzer.ts.md).

## Definitions

- `entropyBits` (lexical_declaration, line 6, exported)
- `ratioOf` (lexical_declaration, line 18)
- `observe` (lexical_declaration, line 43, exported)
- `push` (method_definition, line 52, exported)
- `ratio` (method_definition, line 59, exported)
- `BITS_PER_BYTE` (lexical_declaration, line 4)
- `entropy` (lexical_declaration, line 10, exported)
- `probability` (lexical_declaration, line 12, exported)
- `weighted` (lexical_declaration, line 19)
- `total` (lexical_declaration, line 20)
- `rowTotal` (lexical_declaration, line 22)
- `rowFor` (lexical_declaration, line 29)
- `existing` (lexical_declaration, line 30)
- `created` (lexical_declaration, line 34)
- `createCompressibility` (lexical_declaration, line 39, exported)
- `transitions` (lexical_declaration, line 40, exported)
- `previous` (lexical_declaration, line 41, exported)
- `started` (lexical_declaration, line 42, exported)
- `row` (lexical_declaration, line 45, exported)

## Contained in

- [core/analyzers](https://banes-lab.com/anatomy/patterns/folder-patterns-core-analyzers.md)

## Used by

- [core/aggregators/representation.distribution.aggregator.ts](https://banes-lab.com/source/patterns/core/aggregators/representation.distribution.aggregator.ts.md)

## Linked from

- [core/aggregators](https://banes-lab.com/anatomy/patterns/folder-patterns-core-aggregators.md)
- [core/analyzers](https://banes-lab.com/anatomy/patterns/folder-patterns-core-analyzers.md)

## Source

```typescript
import type { Compressibility } from "#types/information.types";
import { sumOf } from "#core/counters/base.counter";

const BITS_PER_BYTE = 8;

export const entropyBits = function entropyBits(counts: Iterable<number>, total: number): number {
    if (total === 0) {
        return 0;
    }
    let entropy = 0;
    for (const count of counts) {
        const probability = count / total;
        entropy -= probability * Math.log2(probability);
    }
    return entropy;
};

const ratioOf = function ratioOf(transitions: ReadonlyMap<string, Map<string, number>>): number {
    let weighted = 0;
    let total = 0;
    for (const row of transitions.values()) {
        const rowTotal = sumOf(row.values());
        weighted += rowTotal * entropyBits(row.values(), rowTotal);
        total += rowTotal;
    }
    return total === 0 ? 0 : Math.min(1, weighted / total / BITS_PER_BYTE);
};

const rowFor = function rowFor(transitions: Map<string, Map<string, number>>, key: string): Map<string, number> {
    const existing = transitions.get(key);
    if (existing) {
        return existing;
    }
    const created = new Map<string, number>();
    transitions.set(key, created);
    return created;
};

export const createCompressibility = function createCompressibility(): Compressibility {
    const transitions = new Map<string, Map<string, number>>();
    let previous = "";
    let started = false;
    const observe = function observe(symbol: string): void {
        if (started) {
            const row = rowFor(transitions, previous);
            row.set(symbol, (row.get(symbol) ?? 0) + 1);
        }
        previous = symbol;
        started = true;
    };
    return {
        push(...chunks: readonly string[]): void {
            for (const text of chunks) {
                for (const symbol of text) {
                    observe(symbol);
                }
            }
        },
        ratio(): number {
            return ratioOf(transitions);
        },
    };
};
```
