"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OtVarValueC = void 0;
const tslib_1 = require("tslib");
const util = tslib_1.__importStar(require("node:util"));
class OtVarValueC {
    constructor(masterSet, origin) {
        this.masterSet = masterSet;
        this.origin = origin;
        /** delta values */
        this.deltaValues = null;
    }
    getVarianceByIndex(index) {
        if (!this.deltaValues) {
            return 0;
        }
        else if (index < this.deltaValues.length) {
            return this.deltaValues[index];
        }
        else {
            return 0;
        }
    }
    inPlaceSetVarianceByIndex(index, value) {
        if (!this.deltaValues) {
            this.deltaValues = new Float64Array(index + 1);
        }
        else if (this.deltaValues.length <= index) {
            const v1 = new Float64Array(index + 1);
            for (let id = 0; id < this.deltaValues.length; id++) {
                v1[id] = this.deltaValues[id];
            }
            this.deltaValues = v1;
        }
        this.deltaValues[index] = value;
    }
    inPlaceAddVarianceByIndex(index, value) {
        if (!this.deltaValues) {
            this.deltaValues = new Float64Array(index + 1);
        }
        else if (this.deltaValues.length <= index) {
            const v1 = new Float64Array(index + 1);
            for (let id = 0; id < this.deltaValues.length; id++) {
                v1[id] = this.deltaValues[id];
            }
            this.deltaValues = v1;
        }
        this.deltaValues[index] = value + this.deltaValues[index];
    }
    getDelta(master) {
        const rec = this.masterSet.getOrPush(master);
        if (!rec)
            return 0;
        else
            return this.getVarianceByIndex(rec.index);
    }
    setDelta(master, value) {
        const rec = this.masterSet.getOrPush(master);
        if (rec)
            this.inPlaceSetVarianceByIndex(rec.index, value);
    }
    addDelta(master, value) {
        const rec = this.masterSet.getOrPush(master);
        if (rec)
            this.inPlaceSetVarianceByIndex(rec.index, value + this.getVarianceByIndex(rec.index));
    }
    *variance() {
        for (const [m, index] of this.masterSet) {
            const vv = this.getVarianceByIndex(index);
            if (vv)
                yield [m, vv];
        }
    }
    evaluate(instance) {
        let v = this.origin;
        for (const [master, index] of this.masterSet) {
            v += this.getVarianceByIndex(index) * master.evaluate(instance);
        }
        return v;
    }
    scaleAddNumber(thisScale, other) {
        const v1 = new OtVarValueC(this.masterSet, this.origin * thisScale + other);
        if (this.deltaValues) {
            v1.deltaValues = new Float64Array(this.deltaValues.length);
            for (let mid = 0; mid < this.deltaValues.length; mid++) {
                v1.deltaValues[mid] = thisScale * (this.deltaValues[mid] || 0);
            }
        }
        return v1;
    }
    scaleAddScaleVariable(thisScale, otherScale, other) {
        const v1 = new OtVarValueC(this.masterSet, thisScale * this.origin + otherScale * other.origin);
        if (other.masterSet === this.masterSet) {
            if (this.deltaValues || other.deltaValues) {
                v1.deltaValues = new Float64Array(Math.max(this.deltaValues ? this.deltaValues.length : 0, other.deltaValues ? other.deltaValues.length : 0));
                if (this.deltaValues) {
                    for (let mid = 0; mid < this.deltaValues.length; mid++) {
                        v1.inPlaceAddVarianceByIndex(mid, thisScale * this.deltaValues[mid]);
                    }
                }
                if (other.deltaValues) {
                    for (let mid = 0; mid < other.deltaValues.length; mid++) {
                        v1.inPlaceAddVarianceByIndex(mid, otherScale * other.deltaValues[mid]);
                    }
                }
            }
        }
        else {
            if (this.deltaValues) {
                v1.deltaValues = new Float64Array(this.deltaValues ? this.deltaValues.length : 0);
                for (let mid = 0; mid < this.deltaValues.length; mid++) {
                    v1.inPlaceAddVarianceByIndex(mid, thisScale * this.deltaValues[mid]);
                }
            }
            for (const [master, variance] of other.variance()) {
                v1.addDelta(master, otherScale * variance);
            }
        }
        return v1;
    }
    toString() {
        let s = "" + this.origin;
        for (const [master, delta] of this.variance()) {
            s += (delta >= 0 ? " + " + delta : " - " + -delta) + " " + master;
        }
        return s;
    }
    [util.inspect.custom]() {
        return "{" + this.toString() + "}";
    }
    static Create(masterSet, origin, variance) {
        const v = new OtVarValueC(masterSet, origin);
        for (const [master, delta] of variance)
            v.setDelta(master, delta);
        return v;
    }
}
exports.OtVarValueC = OtVarValueC;
//# sourceMappingURL=value.js.map