/*
* MathGraph32 Javascript : Software for animating online dynamic mathematics figures
* https://www.mathgraph32.org/
* @Author Yves Biton (yves.biton@sesamath.net)
* @License: GNU AGPLv3 https://www.gnu.org/licenses/agpl-3.0.html
*/
import Complexe from '../types/Complexe'
import CCb from './CCb'
import CCbGlob from '../kernel/CCbGlob'
export default CAppelFonctionNVar
/**
* Objet d'un arbre binaire de calcul représentant un appel de fonction réelle utilisateur
* à n variables.
* @constructor
* @extends CCb
* @param {CListeObjets} listeProprietaire La liste propriétaire.
* @param {number} nbVar Le nombre de variables de la fonction.
* @param {CFoncNVar} fonctionAssociee La fonction appliquée à l'opérande.
* @param {CCb[]} operandes Tableau de CCb représentant les opérandes.
* @returns {void}
*/
function CAppelFonctionNVar (listeProprietaire, nbVar, fonctionAssociee, operandes) {
if (arguments.length === 0) return
CCb.call(this, listeProprietaire)
this.nbVar = nbVar
this.fonctionAssociee = fonctionAssociee
/**
* Attention, ici c'est un tableau de CCb alors que dans CAppelFonction c'est une propriété operande qui est un CCb unique
* @type {CCb[]}
*/
this.operandes = operandes
}
CAppelFonctionNVar.prototype = new CCb()
CAppelFonctionNVar.prototype.constructor = CAppelFonctionNVar
CAppelFonctionNVar.prototype.superClass = 'CCb'
CAppelFonctionNVar.prototype.className = 'CAppelFonctionNVar'
CAppelFonctionNVar.prototype.nature = function () {
return CCbGlob.natAppelFonctionNVar
}
CAppelFonctionNVar.prototype.getClone = function (listeSource, listeCible) {
const operandeClone = new Array(this.nbVar)
for (let i = 0; i < this.nbVar; i++) { operandeClone[i] = this.operandes[i].getClone(listeSource, listeCible) }
// à revoir car la fonction a déjà été créée
const ind1 = listeSource.indexOf(this.fonctionAssociee)
return new CAppelFonctionNVar(listeCible, this.nbVar, listeCible.get(ind1, 'CFoncNVar'), operandeClone)
}
CAppelFonctionNVar.prototype.resultat = function (infoRandom) {
const d = new Array(this.nbVar)
for (let i = 0; i < this.nbVar; i++) d[i] = this.operandes[i].resultat(infoRandom)
return this.fonctionAssociee.rendValeurFonction(infoRandom, d)
}
CAppelFonctionNVar.prototype.resultatFonction = function (infoRandom, valeurParametre) {
const d = new Array(this.nbVar)
for (let i = 0; i < this.nbVar; i++) d[i] = this.operandes[i].resultatFonction(infoRandom, valeurParametre)
return this.fonctionAssociee.rendValeurFonction(infoRandom, d)
}
CAppelFonctionNVar.prototype.resultatComplexe = function (infoRandom, zRes) {
const z1 = new Array(this.nbVar)
for (let i = 0; i < this.nbVar; i++) z1[i] = new Complexe()
for (let i = 0; i < this.nbVar; i++) this.operandes[i].resultatComplexe(infoRandom, z1[i])
this.fonctionAssociee.rendValeurFonctionComplexe(infoRandom, z1, zRes)
}
CAppelFonctionNVar.prototype.resultatFonctionComplexe = function (infoRandom, valeurParametre, zRes) {
const z1 = new Array(this.nbVar)
for (let i = 0; i < this.nbVar; i++) z1[i] = new Complexe()
for (let i = 0; i < this.nbVar; i++) this.operandes[i].resultatFonctionComplexe(infoRandom, valeurParametre, z1[i])
this.fonctionAssociee.rendValeurFonctionComplexe(infoRandom, z1, zRes)
}
CAppelFonctionNVar.prototype.existe = function () {
let res = this.fonctionAssociee.existe
if (!res) return false
for (let i = 0; i < this.nbVar; i++) res = res || this.operandes[i].existe()
return res
}
CAppelFonctionNVar.prototype.initialisePourDependance = function () {
CCb.prototype.initialisePourDependance.call(this)
for (let i = 0; i < this.nbVar; i++) this.operandes[i].initialisePourDependance()
}
CAppelFonctionNVar.prototype.depDe = function (p) {
let res = CCb.prototype.depDe.call(this, p)
for (let i = 0; i < this.nbVar; i++) res = res || this.operandes[i].depDe(p)
return this.memDep(this.fonctionAssociee.depDe(p) || res)
}
CAppelFonctionNVar.prototype.dependDePourBoucle = function (p) {
let res = false
for (let i = 0; i < this.nbVar; i++) res = res || this.operandes[i].dependDePourBoucle(p)
return this.fonctionAssociee.dependDePourBoucle(p) || res
}
CAppelFonctionNVar.prototype.dependDeVariable = function (ind) {
let res = false
for (let i = 0; i < this.nbVar; i++) {
res = res || (this.fonctionAssociee.calcul.dependDeVariable(i) && this.operandes[i].dependDeVariable(ind))
}
return res
}
CAppelFonctionNVar.prototype.getCopie = function () {
const operandeCopie = new Array(this.nbVar)
for (let i = 0; i < this.nbVar; i++) operandeCopie[i] = this.operandes[i].getCopie()
return new CAppelFonctionNVar(this.listeProprietaire, this.nbVar, this.fonctionAssociee, operandeCopie)
}
CAppelFonctionNVar.prototype.getCore = function () {
return this.fonctionAssociee.calcul.getCore()
}
CAppelFonctionNVar.prototype.chaineCalcul = function (varFor = null) {
// Depuis la version 8.1.2 on peut demander que le séparateur décimal pour les affichages soit
// la virgule. On ne peut dans ce cas pas utiliser la virgule pour séparer les arguements.
// On utilise le point-virgule à la palce
const sep = this.listeProprietaire.decimalDot ? ',' : ';'
let ch = this.fonctionAssociee.getNom() + '('
for (let i = 0; i < this.nbVar - 1; i++) ch = ch + this.operandes[i].chaineCalculSansPar(varFor) + sep
return ch + this.operandes[this.nbVar - 1].chaineCalculSansPar(varFor) + ')'
}
CAppelFonctionNVar.prototype.chaineLatex = function (varFor, fracSimple = false) {
// Depuis la version 8.1.2 on peut demander que le séparateur décimal pour les affichages soit
// la virgule. On ne peut dans ce cas pas utiliser la virgule pour séparer les arguements.
// On utilise le point-virgule à la palce
const sep = this.listeProprietaire.decimalDot ? ',' : ';'
let ch = this.fonctionAssociee.getNom() + '('
for (let i = 0; i < this.nbVar - 1; i++) ch = ch + this.operandes[i].chaineLatexSansPar(varFor, fracSimple) + sep
return ch + this.operandes[this.nbVar - 1].chaineLatexSansPar(varFor, fracSimple) + ')'
}
CAppelFonctionNVar.prototype.read = function (inps, list) {
CCb.prototype.read.call(this, inps, list)
this.nbVar = inps.readInt()
const ind1 = inps.readInt()
this.fonctionAssociee = list.get(ind1, 'CFoncNVar')
this.operandes = new Array(this.nbVar)
for (let i = 0; i < this.nbVar; i++) this.operandes[i] = inps.readObject(list)
}
CAppelFonctionNVar.prototype.write = function (oups, list) {
CCb.prototype.write.call(this, oups, list)
oups.writeInt(this.nbVar)
const ind1 = list.indexOf(this.fonctionAssociee)
oups.writeInt(ind1)
for (let i = 0; i < this.nbVar; i++) oups.writeObject(this.operandes[i])
}
CAppelFonctionNVar.prototype.estConstant = function () {
let res = this.fonctionAssociee.estConstant()
for (let i = 0; i < this.nbVar; i++) res = res && this.operandes[i].estConstant()
return res
}
CAppelFonctionNVar.prototype.deriveePossible = function (indiceVariable) {
let b = true
for (let i = 0; (i < this.operandes.length) && b; i++) {
if (this.operandes[i].dependDeVariable(indiceVariable)) { b = this.fonctionAssociee.deriveePossible(i) && this.operandes[i].deriveePossible(indiceVariable) }
}
return b
}
CAppelFonctionNVar.prototype.calculAvecValeursRemplacees = function (bfrac) {
const nbvar = this.fonctionAssociee.nombreVariables()
const tabcal = new Array(this.fonctionAssociee.nombreVariables())
for (let i = 0; i < nbvar; i++) {
tabcal[i] = this.operandes[i].calculAvecValeursRemplacees(bfrac)
}
return new CAppelFonctionNVar(this.listeProprietaire, nbvar, this.fonctionAssociee, tabcal)
}
// Pour cette classe, isCalcVect renvoie fausse par défaut
CAppelFonctionNVar.prototype.isCalcOK4Vect = function (tabNames) {
if (this.fonctionAssociee.nomCalcul === 'prosca') {
const nbvar = this.fonctionAssociee.nombreVariables()
for (let i = 0; i < nbvar; i++) {
if (!this.operandes[i].isCalcVect(tabNames)) return false
}
return true
} else return true
}
// Déplacé ici version 6.4.7
CAppelFonctionNVar.prototype.calculNormalise = function (rempval, sousdivnorm, rempDecParFrac, eliminMult1 = true) {
const op = new Array(this.nbVar)
for (let i = 0; i < this.nbVar; i++) { op[i] = this.operandes[i].calculNormalise(rempval, sousdivnorm, rempDecParFrac, eliminMult1) }
return new CAppelFonctionNVar(this.listeProprietaire, this.nbVar, this.fonctionAssociee, op)
}