import { CellFilterUnaryOperation } from "../../core/CellFilterUnaryOperation.js";
import { assert } from "../../../../core/assert.js";
import { bell_membership_function } from "../../../../core/math/bell_membership_function.js";

/**
 * @see "dbellmf" function from Matlab
 * @see https://codecrucks.com/what-is-fuzzy-membership-function-complete-guide/
 * @see https://researchhubs.com/post/maths/fundamentals/bell-shaped-function.html
 */
export class CellFilterMembershipGeneralizedBell extends CellFilterUnaryOperation {

    /**
     * Controls window, larger value = larger window. Function will return exactly 0.5 at this distance away from center
     * @type {number}
     */
    a = 1;

    /**
     * Slope, larger slope makes function's tails sharper, meaning that values fall off faster away from center
     * @type {number}
     */
    b = 1;

    /**
     * Controls center of the bell
     * @type {number}
     */
    c = 0;

    static from(source, a = 1, b = 1, c = 0) {
        assert.equal(source.isCellFilter, true, 'source.isCellFilter !== true');

        assert.isNumber(a, 'a');
        assert.isNumber(b, 'b');
        assert.isNumber(c, 'c');

        const r = new CellFilterMembershipGeneralizedBell();

        r.a = a;
        r.b = b;
        r.c = c;

        r.source = source;

        return r;
    }

    operation(v) {
        return bell_membership_function(v, this.a, this.b, this.c);
    }

}
