Commit 82fee6ca authored by Mathias Chouet's avatar Mathias Chouet 🍝
Browse files

work on #162 - add module SPP

parent a94ab629
import { CalculatorType } from "../src/compute-node";
import { Grille, Session } from "../src/index";
import { Grille, Session, SPP, YAXN, YAXNParams } from "../src/index";
import { MacrorugoCompound } from "../src/macrorugo/macrorugo_compound";
import { Nub } from "../src/nub";
import { CloisonAval } from "../src/pab/cloison_aval";
......@@ -111,6 +111,17 @@ function setRandomTrigoUnit(sn: Trigo) {
sn.unit = un;
}
function addRandomYAXNs(n: SPP, nYMax: number = 3) {
const nY = Math.floor(Math.random() * nYMax) + 1;
for (let i = 0; i < nY; i++) {
n.addChild(
new YAXN(
new YAXNParams(Math.random() * 10, Math.random() * 10, Math.random() * 10)
)
);
}
}
function setPab(pab: Pab, nClMax = 30, nStMax = 3) {
const nCl = Math.floor(Math.random() * nClMax) + 1;
for (let i = 0; i < nCl; i++) {
......@@ -164,6 +175,9 @@ function CreateTestNub(iCalType: number): Nub {
setRandomOperation(n as Trigo);
setRandomTrigoUnit(n as Trigo);
}
if (iCalType === CalculatorType.SPP) {
addRandomYAXNs(n as SPP);
}
for (const p of n.parameterIterator) {
if (p.visible) {
randomizeParameter(p);
......
import { Session } from "../src/session";
import { SPP, SPPOperation } from "../src/spp";
import { SPPParams } from "../src/spp_params";
import { CreateStructure } from "../src/structure/factory_structure";
import { ParallelStructure } from "../src/structure/parallel_structure";
import { ParallelStructureParams } from "../src/structure/parallel_structure_params";
import { LoiDebit } from "../src/structure/structure_props";
import { YAXN } from "../src/yaxn";
import { YAXNParams } from "../src/yaxn_params";
describe("Class SPP: ", () => {
describe("Calc Y (sum): ", () => {
it("Y = sum([ 3*2^4, 7*1^0 ]) should be 55", () => {
const nub = new SPP(new SPPParams(1));
nub.addChild(new YAXN(new YAXNParams(3, 2, 4)));
nub.addChild(new YAXN(new YAXNParams(7, 1, 0)));
nub.operation = SPPOperation.SUM;
nub.CalcSerie();
expect(nub.result.vCalc).toBe(55);
});
});
describe("Calc Y (product): ", () => {
it("Y = product([ 3*2^4, 7*1^0 ]) should be 336", () => {
const nub = new SPP(new SPPParams(1));
nub.addChild(new YAXN(new YAXNParams(3, 2, 4)));
nub.addChild(new YAXN(new YAXNParams(7, 1, 0)));
nub.operation = SPPOperation.PRODUCT;
nub.CalcSerie();
expect(nub.result.vCalc).toBe(336);
});
});
describe("Calc some X (sum): ", () => {
it("sum([ 3*X^4, 7*1^0 ]) = 55 - X should be 2", () => {
const nub = new SPP(new SPPParams(55));
nub.addChild(new YAXN(new YAXNParams(3, 666, 4)));
nub.addChild(new YAXN(new YAXNParams(7, 1, 0)));
nub.operation = SPPOperation.SUM;
const c = nub.getChildren()[0] as YAXN;
nub.calculatedParam = c.prms.X;
nub.CalcSerie();
expect(nub.result.vCalc).toBe(2);
});
});
describe("Calc some Y (product): ", () => {
it("product([ 3*X^4, 7*1^0 ]) = 336 - X should be 2", () => {
const nub = new SPP(new SPPParams(336));
nub.addChild(new YAXN(new YAXNParams(3, 666, 4)));
nub.addChild(new YAXN(new YAXNParams(7, 1, 0)));
nub.operation = SPPOperation.PRODUCT;
const c = nub.getChildren()[0] as YAXN;
nub.calculatedParam = c.prms.X;
nub.CalcSerie();
expect(nub.result.vCalc).toBe(2);
});
});
describe("Link: ", () => {
it("all parameters must be linkable to Y and children X in both ways", () => {
const spp = new SPP(new SPPParams(1));
spp.addChild(new YAXN(new YAXNParams(3, 666, 4)));
spp.addChild(new YAXN(new YAXNParams(7, 1, 0)));
spp.addChild(new YAXN(new YAXNParams(5, 4, 3)));
const lo = new ParallelStructure(new ParallelStructureParams(1.2, 102, 101));
lo.addChild(CreateStructure(LoiDebit.GateCem88d, lo));
Session.getInstance().clear();
Session.getInstance().registerNubs([ spp, lo ]);
// SPP.Y should be linkable to all ParallelStructures params
const lpY = Session.getInstance().getLinkableValues(spp.prms.Y);
expect(lpY.length).toBe(7);
// all 3 YAXN.X should be linkable to all ParallelStructures params
for (const c of spp.getChildren()) {
const lp = Session.getInstance().getLinkableValues((c as YAXN).prms.X);
expect(lp.length).toBe(13); // 7, plus siblings params
}
// each ParallelStructures param should be linkable to SPP.Y and all 3 YAXN.X
for (const p of lo.parameterIterator) {
const lpLO = Session.getInstance().getLinkableValues(p);
expect(lpLO.length).toBe(4);
}
});
});
});
......@@ -156,11 +156,11 @@ describe("Class Trigo: ", () => {
Session.getInstance().clear();
Session.getInstance().registerNubs([ trig, lo ]);
// each YAXB param should be linkable to all ParallelStructures params
// each Trigo param should be linkable to all ParallelStructures params
expect(Session.getInstance().getLinkableValues(trig.prms.Y).length).toBe(7);
expect(Session.getInstance().getLinkableValues(trig.prms.X).length).toBe(7);
// each ParallelStructures param should be linkable to all YAXB params
// each ParallelStructures param should be linkable to all Trigo params
for (const p of lo.parameterIterator) {
expect(Session.getInstance().getLinkableValues(p).length).toBe(2);
}
......
......@@ -32,7 +32,9 @@ export enum CalculatorType {
Bief,
Solveur, // Nub qui résout des chaînes de Nubs par dichotomie
YAXB, // Y = A.X + B
Trigo
Trigo, // Fonctions trigonométriques
SPP, // Somme et produit de puissances
YAXN // Y = A.X^N
}
/**
......
......@@ -63,3 +63,7 @@ export * from "./yaxb";
export * from "./yaxb_params";
export * from "./trigo";
export * from "./trigo_params";
export * from "./spp";
export * from "./spp_params";
export * from "./yaxn";
export * from "./yaxn_params";
......@@ -22,10 +22,14 @@ import { CourbeRemous } from "./remous/remous";
import { SectionParametree } from "./section/section_parametree";
import { Solveur } from "./solveur/solveur";
import { SolveurParams } from "./solveur/solveur_params";
import { Trigo, TrigoOperation } from "./trigo";
import { SPP } from "./spp";
import { SPPParams } from "./spp_params";
import { Trigo } from "./trigo";
import { TrigoParams } from "./trigo_params";
import { YAXB } from "./yaxb";
import { YAXBParams } from "./yaxb_params";
import { YAXN } from "./yaxn";
import { YAXNParams } from "./yaxn_params";
// Classes relatives aux sections
import { BiefParams, BiefRegime } from "./remous/bief_params";
......@@ -600,7 +604,6 @@ export class Session {
break;
case CalculatorType.Trigo:
const trigoOp: TrigoOperation = params.getPropValue("trigoOperation");
nub = new Trigo(
new TrigoParams(
0.985, // Y
......@@ -610,6 +613,26 @@ export class Session {
);
break;
case CalculatorType.SPP:
nub = new SPP(
new SPPParams(
1 // Y
),
dbg
);
break;
case CalculatorType.YAXN:
nub = new YAXN(
new YAXNParams(
1, // A
1, // X
1 // B
),
dbg
);
break;
default:
throw new Error(
`Session.createNub() : type de module '${CalculatorType[calcType]}' non pris en charge`
......
import { CalculatorType } from "./compute-node";
import { Nub } from "./nub";
import { ParamCalculability } from "./param/param-definition";
import { SPPParams } from "./spp_params";
import { Result } from "./util/result";
import { Message, MessageCode } from "./util/message";
import { YAXN } from "./yaxn";
export enum SPPOperation {
SUM, // Somme
PRODUCT // Produit
}
/**
* Somme et produit de puissances
* Y = Σ ou π (a1.x1^p1, … an.xn^pn)
*/
export class SPP extends Nub {
constructor(prms: SPPParams, dbg: boolean = false) {
super(prms, dbg);
this._calcType = CalculatorType.Trigo;
this._defaultCalculatedParam = prms.Y;
this.resetDefaultCalculatedParam();
this.properties.setPropValue("sppOperation", SPPOperation.SUM);
}
/** paramètres castés au bon type */
get prms(): SPPParams {
return this._prms as SPPParams;
}
public get operation(): SPPOperation {
return this.properties.getPropValue("sppOperation");
}
public set operation(o: SPPOperation) {
this.properties.setPropValue("sppOperation", o);
}
/**
* @param sVarCalc Nom du paramètre à calculer : "Y", ou
* { uid: "abcdef", symbol: "X" } avec "abcdef" l'UID du module YAXN et "X" son paramètre
* @param rInit Valeur initiale
*/
public Calc(sVarCalc: string | any, rInit?: number): Result {
// if Calc() is called outside of CalcSerie(), _result might not be initialized
if (! this.result) {
this.initNewResultElement();
}
switch (sVarCalc) {
case "Y":
this.currentResult = super.Calc(sVarCalc, rInit);
if (this.result.ok) {
this.getParameter(sVarCalc).v = this.result.resultElement.vCalc;
}
break;
default:
if (typeof sVarCalc === "string") {
throw new Error("SPP.Calc() : unknow parameter to calculate " + sVarCalc);
}
let vPartielle;
// 1. calcul de la somme / du produit des modules YAXN, sauf celui qui est en calcul;
// 2. soustraction / division de Y par le résultat de 1.
if (this.operation === SPPOperation.SUM) {
vPartielle = 0;
for (const c of this._children) {
if (c.uid !== sVarCalc.uid) {
vPartielle += c.Equation("Y").vCalc;
}
}
vPartielle = this.prms.Y.v - vPartielle;
} else if (this.operation === SPPOperation.PRODUCT) {
vPartielle = 1;
for (const c of this._children) {
if (c.uid !== sVarCalc.uid) {
vPartielle *= c.Equation("Y").vCalc;
}
}
if (vPartielle === 0) {
const m = new Message(MessageCode.ERROR_DIVISION_BY_ZERO);
m.extraVar.symbol = "vPartielle";
return new Result(m);
}
vPartielle = this.prms.Y.v / vPartielle;
}
// 3. injection de vPartielle dans le Y du module YAXN en calcul
const yaxnEnCalcul = this.getChildren()[this.getIndexForChild(sVarCalc.uid)] as YAXN;
yaxnEnCalcul.prms.Y.v = vPartielle;
const r: Result = yaxnEnCalcul.Calc(sVarCalc.symbol, rInit); // sVarCalc.symbol should always be "X"
// "copy" result
this.result.symbol = r.symbol;
this.result.vCalc = r.vCalc;
this.result.log.addLog(r.log);
this.result.globalLog.addLog(r.globalLog);
}
return this.result;
}
public Equation(sVarCalc: string): Result {
let v: number;
switch (sVarCalc) {
case "Y":
if (this.operation === SPPOperation.SUM) {
v = 0;
for (const c of this._children) {
v += c.Equation("Y").vCalc;
}
} else if (this.operation === SPPOperation.PRODUCT) {
v = 1;
for (const c of this._children) {
v *= c.Equation("Y").vCalc;
}
}
break;
default:
throw new Error("YAXN.Equation() : invalid variable name " + sVarCalc);
}
return new Result(v, this);
}
/** paramétrage de la calculabilité des paramètres */
protected setParametersCalculability() {
this.prms.Y.calculability = ParamCalculability.EQUATION;
}
}
import { ParamDefinition, ParamFamily } from "./param/param-definition";
import { ParamDomainValue } from "./param/param-domain";
import { ParamsEquation } from "./param/params-equation";
/**
* Y = Σ ou π (a1.x1^p1, … an.xn^pn)
*/
export class SPPParams extends ParamsEquation {
/** Y */
private _Y: ParamDefinition;
constructor(rY: number) {
super();
this._Y = new ParamDefinition(this, "Y", ParamDomainValue.ANY, undefined, rY, ParamFamily.ANY);
this.addParamDefinition(this._Y);
}
get Y() {
return this._Y;
}
}
......@@ -156,6 +156,7 @@ export class Trigo extends Nub implements Observer {
this.prms.Y.domain.interval.setInterval(new Interval(1, Infinity));
break;
}
break;
}
}
}
......
......@@ -53,7 +53,7 @@ export class YAXB extends Nub {
break;
default:
throw new Error("AXB.Equation() : invalid variable name " + sVarCalc);
throw new Error("YAXB.Equation() : invalid variable name " + sVarCalc);
}
return new Result(v, this);
......
import { CalculatorType } from "./compute-node";
import { Nub } from "./nub";
import { ParamCalculability } from "./param/param-definition";
import { Message, MessageCode } from "./util/message";
import { Result } from "./util/result";
import { YAXNParams } from "./yaxn_params";
/**
* Y = A.X^N
*/
export class YAXN extends Nub {
constructor(prms: YAXNParams, dbg: boolean = false) {
super(prms, dbg);
this._calcType = CalculatorType.YAXN;
this._defaultCalculatedParam = prms.Y;
this.resetDefaultCalculatedParam();
}
/** paramètres castés au bon type */
get prms(): YAXNParams {
return this._prms as YAXNParams;
}
public Equation(sVarCalc: string): Result {
let v: number;
switch (sVarCalc) {
case "Y":
v = this.prms.A.v * Math.pow(this.prms.X.v, this.prms.N.v);
break;
case "X":
// X = (Y/A)^(1/N)
if (this.prms.A.v === 0) {
const m = new Message(MessageCode.ERROR_DIVISION_BY_ZERO);
m.extraVar.symbol = "A";
return new Result(m);
}
if (this.prms.N.v === 0) {
const m = new Message(MessageCode.ERROR_DIVISION_BY_ZERO);
m.extraVar.symbol = "N";
return new Result(m);
}
v = Math.pow((this.prms.Y.v / this.prms.A.v), (1 / this.prms.N.v));
break;
default:
throw new Error("YAXN.Equation() : invalid variable name " + sVarCalc);
}
return new Result(v, this);
}
/** paramétrage de la calculabilité des paramètres */
protected setParametersCalculability() {
this.prms.Y.calculability = ParamCalculability.EQUATION;
this.prms.X.calculability = ParamCalculability.EQUATION;
}
}
import { ParamDefinition, ParamFamily } from "./param/param-definition";
import { ParamDomainValue } from "./param/param-domain";
import { ParamsEquation } from "./param/params-equation";
/**
* Y = A.X^N
*/
export class YAXNParams extends ParamsEquation {
/** Y */
private _Y: ParamDefinition;
/** A */
private _A: ParamDefinition;
/** X */
private _X: ParamDefinition;
/** N */
private _N: ParamDefinition;
constructor(rA: number, rX: number, rN: number) {
super();
this._Y = new ParamDefinition(this, "Y", ParamDomainValue.ANY, undefined, undefined, undefined, false);
this._A = new ParamDefinition(this, "A", ParamDomainValue.ANY, undefined, rA);
this._X = new ParamDefinition(this, "X", ParamDomainValue.ANY, undefined, rX, ParamFamily.ANY);
this._N = new ParamDefinition(this, "N", ParamDomainValue.ANY, undefined, rN);
this.addParamDefinition(this._Y);
this.addParamDefinition(this._A);
this.addParamDefinition(this._X);
this.addParamDefinition(this._N);
}
get Y() {
return this._Y;
}
get A() {
return this._A;
}
get X() {
return this._X;
}
get N() {
return this._N;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment