Skip to content

Commit

Permalink
feat(math): add various T-norm functions
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Dec 10, 2020
1 parent 04f3290 commit ab4a810
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/math/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
"quadratic",
"smooth",
"solver",
"t-norm",
"trigonometry",
"typescript"
],
Expand Down
1 change: 1 addition & 0 deletions packages/math/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ export * from "./ratio";
export * from "./safe-div";
export * from "./solve";
export * from "./step";
export * from "./tnorms";
90 changes: 90 additions & 0 deletions packages/math/src/tnorms.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import type { FnN2 } from "@thi.ng/api";
import { norm } from "./fit";

// https://en.wikipedia.org/wiki/T-norm

export const tnormMin: FnN2 = (a, b) => Math.min(a, b);

export const tnormProduct: FnN2 = (a, b) => a * b;

export const tnormLukasiewicz: FnN2 = (a, b) => Math.max(0, a + b - 1);

export const tnormDrastic: FnN2 = (a, b) => (a === 1 ? b : b === 1 ? a : 0);

export const tnormNilpotent: FnN2 = (a, b) => (a + b > 1 ? Math.min(a, b) : 0);

/**
* HOF T-norm. Parametric Hamacher with `p` controlling curvature.
*
* @param p - curve param (default: 2)
*/
export const tnormHamacher = (p = 2): FnN2 => (a, b) =>
a === 0 && b === 0 ? 0 : (a * b) / (p + (1 - p) * (a + b - a * b));

/**
* S-norm (T-conorm), dual of {@link tnormMin}.
*
* @param a
* @param b
*/
export const snormMax: FnN2 = (a, b) => Math.max(a, b);

/**
* S-norm (T-conorm), dual of {@link tnormProduct}, probabilistic sum:
* `a + b - a * b`
*
* @param a
* @param b
*/
export const snormProbabilistic: FnN2 = (a, b) => a + b - a * b;

/**
* S-norm (T-conorm), dual of {@link tnormLukasiewicz}.
*
* @param a
* @param b
*/
export const snormBoundedSum: FnN2 = (a, b) => Math.min(a + b, 1);

/**
* S-norm (T-conorm), dual of {@link tnormDrastic}.
*/
export const snormDrastic: FnN2 = (a, b) => (a === 0 ? b : b === 0 ? a : 1);

/**
* S-norm (T-conorm), dual of {@link tnormNilpotent}.
*
* @param a
* @param b
*/
export const snormNilpotent: FnN2 = (a, b) => (a + b < 1 ? Math.max(a, b) : 1);

/**
* S-norm (T-conorm), dual of {@link tnormHamacher}, iff that T-norm's curve
* param is `p=2`.
*
* @param a
* @param b
*/
export const snormEinstein: FnN2 = (a, b) => (a + b) / (1 + a * b);

/**
* HOF t-norm. Constructs a new t-norm based on given t-norms for disjoint
* subintervals, completing remaining regions via {@link min}.
*
* @remarks
* Reference: https://en.wikipedia.org/wiki/Construction_of_t-norms#Ordinal_sums
*
* @param specs
*/
export const ordinalSum = (
specs: { domain: [number, number]; tnorm: FnN2 }[]
): FnN2 => (x, y) => {
for (let s of specs) {
const [a, b] = s.domain;
if (x >= a && x <= b && y >= a && y <= b) {
return a + (b - a) * s.tnorm(norm(x, a, b), norm(y, a, b));
}
}
return Math.min(x, y);
};

0 comments on commit ab4a810

Please sign in to comment.