From 3bf784595ae593534f305f80ba00d7763c41e76d Mon Sep 17 00:00:00 2001 From: Kang Seonghoon Date: Mon, 23 Aug 2021 15:26:45 +0900 Subject: [PATCH] Add CompressOption.preset. this can be used to "train" the model for shared contexts. can be useful if the model is directly used for compression. it is currently unclear that this can improve actual packing; the observed improvement was "only" around 30B for samples so the eventual decoder cost may outweigh that. --- index.d.ts | 1 + index.mjs | 22 ++++++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/index.d.ts b/index.d.ts index da4dde5..9338240 100644 --- a/index.d.ts +++ b/index.d.ts @@ -94,6 +94,7 @@ export class DefaultModel implements LogisticMixModel { export interface CompressOptions extends AnsOptions { inBits: number; + preset?: number[]; calculateByteEntropy?: boolean; } diff --git a/index.mjs b/index.mjs index 267bfb3..49d150c 100644 --- a/index.mjs +++ b/index.mjs @@ -394,9 +394,18 @@ export class DefaultModel extends LogisticMixModel { //------------------------------------------------------------------------------ export const compressWithModel = (input, model, options) => { - const { inBits, outBits, precision, calculateByteEntropy } = options; + const { inBits, outBits, precision, preset = [], calculateByteEntropy } = options; const encoder = new AnsEncoder(options); + for (let offset = 0; offset < preset.length; ++offset) { + const code = preset[offset]; + for (let i = inBits - 1; i >= 0; --i) { + model.predict(); + model.update((code >> i) & 1); + } + model.flushByte(code, inBits); + } + const byteProbs = []; for (let offset = 0; offset < input.length; ++offset) { const code = input[offset]; @@ -429,9 +438,18 @@ export const compressWithModel = (input, model, options) => { }; export const decompressWithModel = ({ state, buf, inputLength }, model, options) => { - const { inBits } = options; + const { inBits, preset = [] } = options; const decoder = new AnsDecoder({ state, buf }, options); + for (let offset = 0; offset < preset.length; ++offset) { + const code = preset[offset]; + for (let i = inBits - 1; i >= 0; --i) { + model.predict(); + model.update((code >> i) & 1); + } + model.flushByte(code, inBits); + } + const reconstructed = []; for (let offset = 0; offset < inputLength; ++offset) { let current = 0;