/*
* 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 mathjs from '../kernel/mathjs'
import Complexe from '../types/Complexe'
import CCb from './CCb'
import CCbGlob from '../kernel/CCbGlob'
import NatCal from 'src/types/NatCal'
const { matrix } = mathjs
// export default CAppelFonction
export default CAppelFonction
/**
* Objet d'un arbre binaire de calcul représentant un appel de fonction réelle utilisateur.
* @constructor
* @extends CCb
* @param {CListeObjets} listeProprietaire La liste propriétaire.
* @param {CCalculAncetre} fonctionAssociee Peut pointer sur une fonction ou une suite.
* @param {CCb} operande L'opérande dont on cherche l'image.
* @returns {CAppelFonction}
*/
function CAppelFonction (listeProprietaire, fonctionAssociee, operande) {
if (arguments.length === 0) CCb.call(this) // Ajout version WebPack
else {
CCb.call(this, listeProprietaire)
this.fonctionAssociee = fonctionAssociee
this.operande = operande
/** @since 4.9.7 */
this.z1loc = new Complexe()
}
}
CAppelFonction.prototype = new CCb()
CAppelFonction.prototype.constructor = CAppelFonction
CAppelFonction.prototype.superClass = 'CCb'
CAppelFonction.prototype.className = 'CAppelFonction'
CAppelFonction.prototype.nature = function () {
return CCbGlob.natAppelFonction
}
CAppelFonction.prototype.getClone = function (listeSource, listeCible) {
const cloneOperande = this.operande.getClone(listeSource, listeCible)
// à revoir car la fonction a déjà été créée
const ind1 = listeSource.indexOf(this.fonctionAssociee)
return new CAppelFonction(listeCible, listeCible.get(ind1, 'CCalculAncetre'), cloneOperande)
}
CAppelFonction.prototype.resultatComplexe = function (infoRandom, zRes) {
this.operande.resultatComplexe(infoRandom, this.z1loc)
this.fonctionAssociee.rendValeurFonctionComplexe(infoRandom, this.z1loc, zRes)
}
CAppelFonction.prototype.resultatFonctionComplexe = function (infoRandom, valeurParametre, zRes) {
this.operande.resultatFonctionComplexe(infoRandom, valeurParametre, this.z1loc)
this.fonctionAssociee.rendValeurFonctionComplexe(infoRandom, this.z1loc, zRes)
}
CAppelFonction.prototype.existe = function () {
return this.fonctionAssociee.existe && this.operande.existe()
}
CAppelFonction.prototype.resultat = function (infoRandom) {
return this.fonctionAssociee.rendValeurFonction(infoRandom, this.operande.resultat(infoRandom))
}
CAppelFonction.prototype.resultatFonction = function (infoRandom, valeurParametre) {
return this.fonctionAssociee.rendValeurFonction(infoRandom, this.operande.resultatFonction(infoRandom, valeurParametre))
}
// Ajout version 6.7
CAppelFonction.prototype.resultatMat = function (infoRandom) {
const op = this.operande.resultatMat(infoRandom)
if (typeof op === 'number') return this.resultat(infoRandom)
// On applique la fonction à chacun des termes de la matrice
const res = []
const size = op.size()
const n = size[0]
const p = size[1]
for (let i = 0; i < n; i++) {
const lig = []
res.push(lig)
for (let j = 0; j < p; j++) {
lig.push(this.fonctionAssociee.rendValeurFonction(infoRandom, op(i, j)))
}
}
return matrix(res)
}
CAppelFonction.prototype.initialisePourDependance = function () {
CCb.prototype.initialisePourDependance.call(this)
this.operande.initialisePourDependance()
}
CAppelFonction.prototype.depDe = function (p) {
if (this.elementTestePourDependDe === p) return this.dependDeElementTeste
return this.memDep(CCb.prototype.depDe.call(this, p) ||
this.fonctionAssociee.depDe(p) || this.operande.depDe(p))
}
CAppelFonction.prototype.dependDePourBoucle = function (p) {
return this.fonctionAssociee.dependDePourBoucle(p) || this.operande.dependDePourBoucle(p)
}
CAppelFonction.prototype.dependDeVariable = function (ind) {
return this.operande.dependDeVariable(ind)
}
CAppelFonction.prototype.deriveePossible = function (indiceVariable) {
const b = this.operande.deriveePossible(indiceVariable)
if (this.fonctionAssociee.className === 'CSuiteRec') return b
else return b || this.fonctionAssociee.deriveePossible(indiceVariable)
}
CAppelFonction.prototype.getCopie = function () {
return new CAppelFonction(this.listeProprietaire, this.fonctionAssociee, this.operande.getCopie())
}
CAppelFonction.prototype.getCore = function () {
return this.fonctionAssociee.calcul.getCore()
}
CAppelFonction.prototype.chaineCalcul = function (varFor = null) {
// ElimineParenthesesDebut(cha);
return this.fonctionAssociee.getNom() + '(' + this.operande.chaineCalculSansPar(varFor) + ')'
}
CAppelFonction.prototype.chaineLatex = function (varFor, fracSimple = false) {
const estSuiteRec = this.fonctionAssociee.estDeNatureCalcul(NatCal.NTteSuiteRec)
// Si la fonction associée est en fait une uite récurrente, on passe en indice pour l'argument
const parouvLatex = estSuiteRec ? '_{' : '\\left('
const parferLatex = estSuiteRec ? '}' : '\\right)'
return this.fonctionAssociee.getNom() + parouvLatex + this.operande.chaineLatexSansPar(varFor, fracSimple) + parferLatex
}
CAppelFonction.prototype.read = function (inps, list) {
CCb.prototype.read.call(this, inps, list)
const ind1 = inps.readInt()
this.fonctionAssociee = list.get(ind1, 'CCalculAncetre')
this.operande = inps.readObject(list)
}
CAppelFonction.prototype.write = function (oups, list) {
CCb.prototype.write.call(this, oups, list)
const ind1 = list.indexOf(this.fonctionAssociee)
oups.writeInt(ind1)
oups.writeObject(this.operande)
}
CAppelFonction.prototype.estConstant = function () {
return this.fonctionAssociee.estConstant() && this.operande.estConstant()
}
// Pour cette classe, isCalcVect renvoie fausse par défaut
CAppelFonction.prototype.isCalcOK4Vect = function (tabNames) {
return !this.operande.isCalcVect(tabNames)
}