/**
* 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 Opef from '../types/Opef'
import { ConvDegRad, ConvRadDeg, erreurCalculException, fracCont, getStr, uniteAngleRadian } from '../kernel/kernel'
import CCb, { getLeft, getRight } from './CCb'
import CCbGlob from '../kernel/CCbGlob'
import Ope from '../types/Ope'
const { det, matrix } = mathjs
export default CFonction
/**
* Classe représentant dans un arbre binaire de calcul un appel de fonction réelle
* à une variable prédéfinie.
* @constructor
* @extends CCb
* @param {CListeObjets} listeProprietaire La liste propriétaire de l'objet
* @param {Opef} opef Donne la nature de la fonction.
* @param {CCb} operande Le calcul donnant l'opérande.
* @returns {CFonction}
*/
function CFonction (listeProprietaire, opef, operande) {
CCb.call(this, listeProprietaire)
if (arguments.length !== 1) {
this.opef = opef
this.operande = operande
}
this.dejaPositionne = false // ne servira que pour un appel fonction Rand() de génération d'un nombre aléatoire.
this.valeurDejaPrise = 0 // Comme son nom l'indique pour les appels de random
this.valeurDejaPriseImaginaire = 0 // Partie imaginaire pour les fonctions complexes pour les appels de random
this.z1loc = new Complexe()
}
CFonction.prototype = new CCb()
CFonction.prototype.constructor = CFonction
CFonction.prototype.superClass = 'CCb'
CFonction.prototype.className = 'CFonction'
CFonction.prototype.nature = function () {
return CCbGlob.natFonction
}
CFonction.prototype.numeroVersion = function () {
return 2
}
CFonction.prototype.nombreVariables = function () {
return 1
}
CFonction.prototype.getClone = function (listeSource, listeCible) {
const cloneOperande = this.operande.getClone(listeSource, listeCible)
const ptcalc = new CFonction(listeCible, this.opef, cloneOperande)
// Les trois lignes suivantes ajoutées version 4.4 pour que les valeurs rand ne changent pas dans l'annuler-refaire
ptcalc.dejaPositionne = this.dejaPositionne
ptcalc.valeurDejaPrise = this.valeurDejaPrise
ptcalc.valeurDejaPriseImaginaire = this.valeurDejaPriseImaginaire
return ptcalc
}
CFonction.prototype.initialisePourDependance = function () {
CCb.prototype.initialisePourDependance.call(this)
this.operande.initialisePourDependance()
}
CFonction.prototype.depDe = function (p) {
if (this.elementTestePourDependDe === p) return this.dependDeElementTeste
return this.memDep(CCb.prototype.depDe.call(this, p) || this.operande.depDe(p))
}
CFonction.prototype.dependDePourBoucle = function (p) {
if (this.opef === Opef.Rand) {
// if (p instanceof CVariableBornee) return true;
if (p.className === 'CVariableBornee') return true
else return this.operande.dependDePourBoucle(p)
} else return this.operande.dependDePourBoucle(p)
}
CFonction.prototype.existe = function () {
return this.operande.existe()
}
CFonction.prototype.resultatBase = function (infoRandom, x) {
let a, b
switch (this.opef) {
case Opef.Abso:
return Math.abs(x)
case Opef.Enti:
return Math.floor(x)
case Opef.Raci:
case Opef.Raci2:
if (x >= 0) { return Math.sqrt(x) } else throw new Error(erreurCalculException)
case Opef.Sinu:
if (this.listeProprietaire.uniteAngle === uniteAngleRadian) return CCbGlob.sinus(x)
else return CCbGlob.sinus(x * ConvDegRad)
case Opef.Cosi:
if (this.listeProprietaire.uniteAngle === uniteAngleRadian) return CCbGlob.cosinus(x)
else return CCbGlob.cosinus(x * ConvDegRad)
case Opef.Tang:
if (this.listeProprietaire.uniteAngle === uniteAngleRadian) return CCbGlob.tangente(x)
else {
return CCbGlob.tangente(x * ConvDegRad)
}
case Opef.Logn:
if (x > 0) return Math.log(x)
else throw new Error(erreurCalculException)
case Opef.Expo:
return Math.exp(x)
case Opef.ATan:
if (this.listeProprietaire.uniteAngle === uniteAngleRadian) return Math.atan(x)
else return Math.atan(x) * ConvRadDeg
case Opef.ACos:
if (this.listeProprietaire.uniteAngle === uniteAngleRadian) return Math.acos(x)
else return Math.acos(x) * ConvRadDeg
case Opef.ASin:
if (this.listeProprietaire.uniteAngle === uniteAngleRadian) return Math.asin(x)
else return Math.asin(x) * ConvRadDeg
case Opef.Cosh:
return (Math.exp(x) + Math.exp(-x)) / 2
case Opef.Sinh:
return (Math.exp(x) - Math.exp(-x)) / 2
case Opef.Tanh: {
a = Math.exp(x)
b = Math.exp(-x)
return (a - b) / (a + b)
}
case Opef.ArgCh:
if (x >= 1) return Math.log(x + Math.sqrt(x * x - 1))
else throw new Error(erreurCalculException)
case Opef.ArgSh:
return Math.log(x + Math.sqrt(x * x + 1))
case Opef.ArgTh:
if ((x > -1) && (x < 1)) return 0.5 * Math.log((1 + x) / (1 - x))
else throw new Error(erreurCalculException)
case Opef.Rand:
if (infoRandom) {
this.valeurDejaPrise = Math.random()
this.dejaPositionne = true
return this.valeurDejaPrise
} else {
if (!this.dejaPositionne) {
this.valeurDejaPrise = Math.random()
this.dejaPositionne = true
return this.valeurDejaPrise
} else return this.valeurDejaPrise
}
case Opef.fact:
if ((x < 0) || (x !== Math.round(x))) throw new Error(erreurCalculException)
if (x <= 32) {
let p = 1
for (let i = 2; i <= x; i++) {
p = p * i
}
return p
} else {
let x1 = x
let d = 1 + 1 / (12 * x1)
x1 *= x
d += 1 / (288 * x1)
x1 *= x
d -= 139 / (51840 * x1)
x1 *= x
d -= 571 / (2488320 * x1)
x1 *= x
d -= 163879 / (209018880 * x1)
return Math.exp(0.5 * Math.log(2 * Math.PI * x) + x * (Math.log(x) - 1)) * d
}
case Opef.Transp: // Ajout version 6.7 pour la transposition d'une matrice
case Opef.Deter: // Ajout version 6.7 pour la transposition d'une matrice
// Appelé pour un réel ne fait rien, renvoie comme résultat le paramètre
return x
case Opef.Inv: // Ajouté version 6.7 pour inverse terme à terme d'une matrice
if (x === 0) throw new Error(erreurCalculException)
else return 1 / x
case Opef.Nbcol: // Ajouté version 7.0 pour renvoyer le combre de colonnes d'une matrice
case Opef.Nbrow: // Ajouté version 7.0 pour renvoyer le combre de colonnes d'une matrice
// Appliqué à un nombre renvoie 1 (nombre considéré comme matrice à une ligne et une colonne)
return 1
default : throw new Error(erreurCalculException)
}// switch Opef}
}
CFonction.prototype.resultat = function (infoRandom) {
let mg, md, x1
switch (this.opef) {
case Opef.Left :
case Opef.LeftC : // Rajouté version 4.7.2
mg = getLeft(this.operande)
if (mg === null) {
throw new Error(erreurCalculException)
} else return mg.resultat(infoRandom)
case Opef.Right :
case Opef.RightC : // Rajouté version 4.7.2
md = getRight(this.operande)
if (md === null) {
throw new Error(erreurCalculException)
}
return md.resultat(infoRandom)
case Opef.Core:
case Opef.CoreC:
return this.operande.getCore().resultat()
default :
x1 = this.operande.resultat(infoRandom)
return this.resultatBase(infoRandom, x1)
}
}
CFonction.prototype.resultatFonction = function (infoRandom, valeurParametre) {
let mg, md, x1
switch (this.opef) {
case Opef.Left :
case Opef.LeftC : // Rajouté version 4.7.2
mg = getLeft(this.operande)
if (mg === null) {
throw new Error(erreurCalculException)
}
return mg.resultatFonction(infoRandom, valeurParametre)
case Opef.Right :
case Opef.RightC : // Rajouté version 4.7.2
md = getRight(this.operande)
if (md === null) {
throw new Error(erreurCalculException)
}
return md.resultatFonction(infoRandom, valeurParametre)
case Opef.Core:
case Opef.CoreC:
return this.operande.getCore().resultatFonction(infoRandom, valeurParametre)
default :
x1 = this.operande.resultatFonction(infoRandom, valeurParametre)
return this.resultatBase(infoRandom, x1)
}
}
CFonction.prototype.resultatComplexeBase = function (infoRandom, z, zRes) {
switch (this.opef) {
case Opef.Abs:
case Opef.Abso : // Version 8.1.3 : La fonction valeur absolue réelle renvoie, quand elle est injectée
// dans une formule complexe le module
zRes.y = 0
zRes.x = z.module()
return
case Opef.Sin:
z.sinComp(this.listeProprietaire.uniteAngle, zRes)
return
case Opef.Sinu :
if (z.y !== 0) throw new Error(erreurCalculException)
else {
zRes.y = 0
if (this.listeProprietaire.uniteAngle === uniteAngleRadian) zRes.x = CCbGlob.sinus(z.x)
else zRes.x = CCbGlob.sinus(z.x * ConvDegRad)
return
}
case Opef.Cos:
z.cosComp(this.listeProprietaire.uniteAngle, zRes)
return
case Opef.Cosi :
if (z.y !== 0) throw new Error(erreurCalculException)
else {
zRes.y = 0
if (this.listeProprietaire.uniteAngle === uniteAngleRadian) zRes.x = CCbGlob.cosinus(z.x)
else zRes.x = CCbGlob.cosinus(z.x * ConvDegRad)
return
}
case Opef.Tan:
z.tanComp(this.listeProprietaire.uniteAngle, zRes)
return
case Opef.Tang :
if (z.y !== 0) throw new Error(erreurCalculException)
else {
zRes.y = 0
if (this.listeProprietaire.uniteAngle === uniteAngleRadian) zRes.x = CCbGlob.tangente(z.x)
else zRes.x = z.x * ConvDegRad // Corrigé version 6.7
return
}
case Opef.Log:
z.lnComp(this.listeProprietaire.uniteAngle, zRes)
return
case Opef.Logn :
if ((z.y !== 0) || (z.x <= 0)) throw new Error(erreurCalculException)
else {
zRes.y = 0
zRes.x = Math.log(z.x)
return
}
case Opef.Exp:
z.expComp(this.listeProprietaire.uniteAngle, zRes)
return
case Opef.Expo:
if (z.y !== 0) throw new Error(erreurCalculException)
else {
zRes.y = 0
zRes.x = Math.exp(z.x)
return
}
case Opef.Ch:
z.chComp(this.listeProprietaire.uniteAngle, zRes)
return
case Opef.Cosh:
if (z.y !== 0) throw new Error(erreurCalculException)
else {
zRes.y = 0
zRes.x = (Math.exp(z.x) + Math.exp(-z.x)) / 2
return
}
case Opef.Sh:
z.shComp(this.listeProprietaire.uniteAngle, zRes)
return
case Opef.Sinh :
if (z.y !== 0) throw new Error(erreurCalculException)
else {
zRes.y = 0
zRes.x = (Math.exp(z.x) - Math.exp(-z.x)) / 2
return
}
case Opef.Th:
z.thComp(this.listeProprietaire.uniteAngle, zRes)
return
case Opef.Tanh :
if (z.y !== 0) throw new Error(erreurCalculException)
else {
zRes.y = 0
const a = Math.exp(z.x)
const b = Math.exp(-z.x)
zRes.x = (a - b) / (a + b)
return
}
case Opef.Rnd:
zRes.y = 0
if (infoRandom) {
this.valeurDejaPrise = Math.random()
this.dejaPositionne = true
zRes.x = this.valeurDejaPrise
} else {
if (!this.dejaPositionne) {
this.valeurDejaPrise = Math.random()
this.dejaPositionne = true
zRes.x = this.valeurDejaPrise
} else zRes.x = this.valeurDejaPrise
}
break
case Opef.Conj:
zRes.x = z.x
zRes.y = -z.y
return
case Opef.Arg:
if ((z.x === 0) && (z.y === 0)) {
zRes.x = 0
zRes.y = 0
throw new Error(erreurCalculException)
} else {
zRes.x = z.argument(this.listeProprietaire.uniteAngle)
zRes.y = 0
return
}
case Opef.Re:
zRes.x = z.x
zRes.y = 0
return
case Opef.Im:
zRes.x = z.y
zRes.y = 0
return
case Opef.Rac:
case Opef.Rac2:
case Opef.Raci:
case Opef.Raci2:
zRes.x = 0
zRes.y = 0
if ((z.y !== 0) || (z.x < 0)) throw new Error(erreurCalculException)
else {
zRes.x = Math.sqrt(z.x)
return
}
case Opef.EntiC :
case Opef.Enti :
zRes.x = 0
zRes.y = 0
if (z.y !== 0) throw new Error(erreurCalculException)
else {
zRes.x = Math.floor(z.x)
return
}
case Opef.ACosC :
case Opef.ACos :
// le résultat n'existe que si l'argument est réel
if (z.y !== 0) throw new Error(erreurCalculException)
else {
zRes.y = 0
if (this.listeProprietaire.uniteAngle === uniteAngleRadian) zRes.x = Math.acos(z.x)
else zRes.x = Math.acos(z.x) * ConvRadDeg
return
}
case Opef.ASinC :
case Opef.ASin :
// le résultat n'existe que si l'argument est réel
if (z.y !== 0) throw new Error(erreurCalculException)
else {
zRes.y = 0
if (this.listeProprietaire.uniteAngle === uniteAngleRadian) zRes.x = Math.asin(z.x)
else zRes.x = Math.asin(z.x) * ConvRadDeg
return
}
case Opef.ATanC :
case Opef.ATan :
// le résultat n'existe que si l'argument est réel
if (z.y !== 0) throw new Error(erreurCalculException)
else {
zRes.y = 0
if (this.listeProprietaire.uniteAngle === uniteAngleRadian) zRes.x = Math.atan(z.x)
else zRes.x = Math.atan(z.x) * ConvRadDeg
return
}
case Opef.ArgChC :
case Opef.ArgCh :
// le résultat n'existe que si l'argument est réel
if (z.y !== 0) throw new Error(erreurCalculException)
else {
zRes.y = 0
if (z.x >= 1) zRes.x = Math.log(z.x + Math.sqrt(z.x * z.x - 1))
else throw new Error(erreurCalculException)
}
break
case Opef.ArgShC :
case Opef.ArgSh :
// le résultat n'existe que si l'argument est réel
if (z.y !== 0) throw new Error(erreurCalculException)
else {
zRes.y = 0
zRes.x = Math.log(z.x + Math.sqrt(z.x * z.x + 1))
return
}
case Opef.ArgThC :
// le résultat n'existe que si l'argument est réel
if (z.y !== 0) throw new Error(erreurCalculException)
else {
zRes.y = 0
if ((z.x > -1) && (z.x < 1)) zRes.x = 0.5 * Math.log((1 + z.x) / (1 - z.x))
else throw new Error(erreurCalculException)
}
break
case Opef.factC:
case Opef.fact:
if (z.y !== 0) throw new Error(erreurCalculException)
else {
zRes.y = 0
if ((z.x < 0) || (z.x !== Math.round(z.x))) throw new Error(erreurCalculException)
if (z.x <= 32) {
let p = 1
for (let i = 2; i <= z.x; i++) {
p = p * i
}
zRes.x = p
} else {
const x = z.x
let x1 = x
let d = 1 + 1 / (12 * x1)
x1 *= x
d += 1 / (288 * x1)
x1 *= x
d -= 139 / (51840 * x1)
x1 *= x
d -= 571 / (2488320 * x1)
x1 *= x
d -= 163879 / (209018880 * x1)
zRes.x = Math.exp(0.5 * Math.log(2 * Math.PI * x) + x * (Math.log(x) - 1)) * d
}
}
} // switch Opef}
}
CFonction.prototype.resultatComplexe = function (infoRandom, zRes) {
switch (this.opef) {
case Opef.Left :
case Opef.LeftC : // Rajouté version 4.7.2
// this.operande.membreGauche().resultatComplexe(infoRandom, zRes)
getLeft(this.operande).resultatComplexe(infoRandom, zRes)
break // Rajouté version 4.7.2
case Opef.Right :
case Opef.RightC : // Rajouté version 4.7.2
// this.operande.membreDroit().resultatComplexe(infoRandom, zRes)
getRight(this.operande).resultatComplexe(infoRandom, zRes)
break // Rajouté version 4.7.2
case Opef.Core:
case Opef.CoreC:
this.operande.getCore().resultatComplexe(infoRandom, zRes)
break
default :
this.operande.resultatComplexe(infoRandom, this.z1loc)
this.resultatComplexeBase(infoRandom, this.z1loc, zRes)
}
}
CFonction.prototype.resultatFonctionComplexe = function (infoRandom, valeurParametre, zRes) {
let mg, md
switch (this.opef) {
case Opef.Left :
case Opef.LeftC : // Rajouté version 4.7.2
// mg = this.operande.membreGauche()
mg = getLeft(this.operande)
if (mg === null) throw new Error(erreurCalculException)
mg.resultatFonctionComplexe(infoRandom, valeurParametre, zRes)
break // Rajouté version 4.7.2
case Opef.Right :
case Opef.RightC : // Rajouté version 4.7.2
// md = this.operande.membreDroit()
md = getRight(this.operande)
if (md === null) throw new Error(erreurCalculException)
md.resultatFonctionComplexe(infoRandom, valeurParametre, zRes)
break // Rajouté version 4.7.2
case Opef.Core:
case Opef.CoreC:
this.operande.getCore().resultatFonctionComplexe(infoRandom, valeurParametre, zRes)
break
default :
this.operande.resultatFonctionComplexe(infoRandom, valeurParametre, this.z1loc)
this.resultatComplexeBase(infoRandom, this.z1loc, zRes)
}
}
CFonction.prototype.resultatMatBase = function (op, infoRandom) {
if (this.opef === Opef.Frac) {
// L'opérande ne peut être qu'un nombre, une matrice colonne ou une matrice ligne
if (typeof op === 'number') {
return matrix([fracCont(op)])
} else {
const size = op.size()
const n = size[0]
const p = size[1]
if (n > 1 && p > 1) throw new Error(erreurCalculException)
if (n === 1) { // Matrice d'une ligne. ON renvoie une matrice de deux lignes
const lig1 = []
const lig2 = []
for (let j = 0; j < p; j++) {
// const nb = op(0, j)
const nb = op.get([0, j])
const frac = fracCont(nb)
lig1.push(frac[0])
lig2.push(frac[1])
}
return matrix([lig1, lig2])
} else { // Cas d'une matrice colonne
const res = []
for (let i = 0; i < n; i++) {
// const nb = op(i, 0)
const nb = op.get([i, 0])
const frac = fracCont(nb)
res.push(frac)
}
return matrix(res)
}
}
}
if (typeof op === 'number') return this.resultatBase(infoRandom, op)
if (this.opef === Opef.Transp) {
const size = op.size()
const n = size[0]
const p = size[1]
const tab = []
for (let j = 0; j < p; j++) {
const lig = []
tab.push(lig)
for (let i = 0; i < n; i++) {
lig.push(op.get([i, j]))
}
}
return matrix(tab)
}
if (this.opef === Opef.Deter) {
const size = op.size()
if (size[0] !== size[1]) throw new Error(erreurCalculException)
// return op.det()
return det(op)
}
if (this.opef === Opef.Inv) { // Inverse terme à terme d'une matrice
// On regarde si un des termes de la matrice est nul
const size = op.size()
const n = size[0]
const p = size[1]
const tab = []
for (let i = 0; i < n; i++) {
const lig = []
tab.push(lig)
for (let j = 0; j < p; j++) {
const x = op.get([i, j])
if (x === 0) throw new Error(erreurCalculException)
lig.push(1 / x)
}
}
return matrix(tab)
}
// Ajout version 7.0
if (this.opef === Opef.Nbrow) {
return op.size()[0] // Renvoie le nombre de lignes de la matrice
}
if (this.opef === Opef.Nbcol) {
return op.size()[1] // Renvoie le nombre de lignes de la matrice
}
// Fin ajout version 7.0
// On applique la fonction à chacun des termes de la matrice
const self = this
// return matrix(op.map(x => self.resultatBase(infoRandom, x)))
return op.map(function (value, index, matrix) {
return self.resultatBase(infoRandom, value)
})
}
// Ajout version 6.7
CFonction.prototype.resultatMat = function (infoRandom) {
const op = this.operande.resultatMat(infoRandom)
return this.resultatMatBase(op, infoRandom)
}
// Ajout version 7.1
CFonction.prototype.resultatMatFonction = function (infoRandom, valeurParametre) {
const op = this.operande.resultatMatFonction(infoRandom, valeurParametre)
return this.resultatMatBase(op, infoRandom)
}
CFonction.prototype.dependDeVariable = function (ind) {
switch (this.opef) {
case Opef.Left:
case Opef.LeftC:
// return this.operande.membreGauche().dependDeVariable(ind)
return getLeft(this.operande).dependDeVariable(ind)
case Opef.Right:
case Opef.RightC:
// return this.operande.membreDroit().dependDeVariable(ind)
return getRight(this.operande).dependDeVariable(ind)
default:
return this.operande.dependDeVariable(ind)
}
}
CFonction.prototype.getCopie = function () {
return new CFonction(this.listeProprietaire, this.opef, this.operande.getCopie())
}
CFonction.prototype.chaineCalcul = function (varFor = null) {
const cha = this.operande.chaineCalculSansPar(varFor)
const parouv = '('
const parfer = ')'
switch (this.opef) {
case Opef.Abso:
case Opef.Abs:
return getStr('abs') + parouv + cha + parfer
case Opef.Enti:
case Opef.EntiC:
return getStr('intgr') + parouv + cha + parfer
case Opef.Raci:
case Opef.Rac:
return getStr('sqrt') + parouv + cha + parfer
case Opef.Raci2:
case Opef.Rac2:
return getStr('rac') + parouv + cha + parfer
case Opef.Sinu:
case Opef.Sin:
return getStr('sin') + parouv + cha + parfer
case Opef.Cosi:
case Opef.Cos:
return getStr('cos') + parouv + cha + parfer
case Opef.Tang:
case Opef.Tan:
return getStr('tan') + parouv + cha + parfer
case Opef.Logn:
case Opef.Log:
return getStr('ln') + parouv + cha + parfer
case Opef.Expo:
case Opef.Exp:
return getStr('exp') + parouv + cha + parfer
case Opef.ATan:
case Opef.ATanC:
return getStr('arctan') + parouv + cha + parfer
case Opef.ACos:
case Opef.ACosC:
return getStr('arccos') + parouv + cha + parfer
case Opef.ASin:
case Opef.ASinC:
return getStr('arcsin') + parouv + cha + parfer
case Opef.Cosh:
case Opef.Ch:
return getStr('ch') + parouv + cha + parfer
case Opef.Sinh:
case Opef.Sh:
return getStr('sh') + parouv + cha + parfer
case Opef.Tanh:
case Opef.Th:
return getStr('th') + parouv + cha + parfer
case Opef.fact:
case Opef.factC:
return getStr('fact') + parouv + cha + parfer
// Deux ajouts version 4.6
case Opef.Left:
case Opef.LeftC:
return getStr('left') + parouv + cha + parfer
case Opef.Right:
case Opef.RightC:
return getStr('right') + parouv + cha + parfer
case Opef.Transp: // Ajout version 6.7 pour transposer une matrice
return getStr('transp') + parouv + cha + parfer
case Opef.Deter: // Ajout version 6.7 pour calculer le déterminant d'une matrice
return getStr('deter') + parouv + cha + parfer
case Opef.Inv: // Ajout version 6.7 pour calculer l'inverse d'une matrice
return getStr('inv') + parouv + cha + parfer
case Opef.Frac: // Ajout version 6.7 pour calculer l'inverse d'une matrice
return getStr('frac') + parouv + cha + parfer
case Opef.Nbcol: // Ajout version 7.0 pour renvoyer le nombre de colonnes d'une matrice
return getStr('nbcol') + parouv + cha + parfer
case Opef.Nbrow: // Ajout version 7.0 pour renvoyer le nombre de colonnes d'une matrice
return getStr('nbrow') + parouv + cha + parfer
// A revoir ici. Pour la version 1.5 j'ai oublie le ArgCh
case Opef.ArgCh:
case Opef.ArgChC:
return getStr('argch') + parouv + cha + parfer
case Opef.ArgSh:
case Opef.ArgShC:
return getStr('argsh') + parouv + cha + parfer
case Opef.ArgTh:
case Opef.ArgThC:
return getStr('argth') + parouv + cha + parfer
case Opef.Rand:
case Opef.Rnd:
return getStr('rand') + parouv + cha + parfer
case Opef.Conj:
return getStr('conj') + parouv + cha + parfer
case Opef.Arg:
return getStr('arg') + parouv + cha + parfer
case Opef.Re:
return getStr('re') + parouv + cha + parfer
case Opef.Im:
return getStr('im') + parouv + cha + parfer
case Opef.Core:
case Opef.CoreC:
return getStr('core') + parouv + cha + parfer
default:
return ''
} // switch Opef}}
}
// Avant la version 6.4.8, la foncton ci-dessous était CFonction.prototype.chaineLatexSans
// Modifié pour un meilleur rendu des conjugués
CFonction.prototype.chaineLatexSansPar = function (varFor, fracSimple = false) {
const parouvLatex = '\\left('
const parferLatex = '\\right)'
const cha = this.operande.chaineLatexSansPar(varFor, fracSimple)
switch (this.opef) {
case Opef.Abso:
case Opef.Abs:
return '\\left| {' + cha + '} \\right|'
case Opef.Enti:
case Opef.EntiC:
return getStr('intgr') + parouvLatex + cha + parferLatex
case Opef.Raci:
case Opef.Rac:
return '\\sqrt{' + cha + '}'
case Opef.Raci2:
case Opef.Rac2:
return '\\sqrt{' + cha + '}'
case Opef.Sinu:
case Opef.Sin:
return '\\sin' + parouvLatex + cha + parferLatex
case Opef.Cosi:
case Opef.Cos:
return '\\cos' + parouvLatex + cha + parferLatex
case Opef.Tang:
case Opef.Tan:
return '\\tan' + parouvLatex + cha + parferLatex
case Opef.Logn:
case Opef.Log:
return getStr('lnlat') + parouvLatex + cha + parferLatex
case Opef.Expo:
case Opef.Exp:
return 'e^' + '{' + cha + '}'
case Opef.ATan:
case Opef.ATanC:
return getStr('arctanlat') + parouvLatex + cha + parferLatex
case Opef.ACos:
case Opef.ACosC:
return getStr('arccoslat') + parouvLatex + cha + parferLatex
case Opef.ASin:
case Opef.ASinC:
return getStr('arcsinlat') + parouvLatex + cha + parferLatex
case Opef.Cosh:
case Opef.Ch:
return getStr('chlat') + parouvLatex + cha + parferLatex
case Opef.Sinh:
case Opef.Sh:
return getStr('shlat') + parouvLatex + cha + parferLatex
case Opef.Tanh:
case Opef.Th:
return getStr('thlat') + parouvLatex + cha + parferLatex
case Opef.fact:
case Opef.factC:
if ((this.operande.nature() & (CCbGlob.natIntegraleDansFormule | CCbGlob.natMoinsUnaire | CCbGlob.natOperation |
CCbGlob.natSommeDansFormule)) !== 0) { return parouvLatex + cha + parferLatex + '!' } else return cha + '!' // A revoir
// Deux ajouts version 4.6
case Opef.Left:
case Opef.LeftC:
// return getStr('Left') + parouvLatex + cha + parferLatex
return getLeft(this.operande).chaineLatexSansPar(varFor, fracSimple)
case Opef.Right:
case Opef.RightC:
// return getStr('Left') + parouvLatex + cha + parferLatex
return getRight(this.operande).chaineLatexSansPar(varFor, fracSimple)
case Opef.Transp: // Ajout version 6.7 pour transposer une matrice
return getStr('transp') + parouvLatex + cha + parferLatex
case Opef.Deter: // Ajout version 6.7 pour calculer le déterminant d'une matrice
return getStr('deter') + parouvLatex + cha + parferLatex
case Opef.Inv: // Ajout version 6.7 pour calculer l'inverse d'une matrice
return getStr('inv') + parouvLatex + cha + parferLatex
case Opef.Frac: // Ajout version 6.7 pour calculer l'inverse d'une matrice
return getStr('frac') + parouvLatex + cha + parferLatex
case Opef.Nbcol: // Ajout version 7.0 pour renvoyer le nombre de colonnes d'une matrice
return getStr('nbcol') + parouvLatex + cha + parferLatex
case Opef.Nbrow: // Ajout version 7.0 pour renvoyer le nombre de colonnes d'une matrice
return getStr('nbrow') + parouvLatex + cha + parferLatex
// A revoir ici. Pour la version 1.5 j'ai oublie le ArgCh
case Opef.ArgCh:
case Opef.ArgChC:
return getStr('argch') + parouvLatex + cha + parferLatex
case Opef.ArgSh:
case Opef.ArgShC:
return getStr('argsh') + parouvLatex + cha + parferLatex
case Opef.ArgTh:
case Opef.ArgThC:
return getStr('argth') + parouvLatex + cha + parferLatex
case Opef.Rand:
case Opef.Rnd:
return getStr('rand') + parouvLatex + cha + parferLatex
case Opef.Conj:
{
// Version 6.4.8 : On rajoute un petit espace devant un conjugué
// return '\\overline {' + cha + '}'
const op = this.operande
if ((op.nature() === CCbGlob.natOperation) && (op.ope === Ope.Divi)) {
return '\\,\\overline {' + parouvLatex + op.chaineLatexSansPar(varFor, fracSimple) + parferLatex + '}'
} else return '\\,\\overline {' + cha + '}'
}
case Opef.Arg:
return '\\arg' + parouvLatex + cha + parferLatex
case Opef.Re:
return getStr('re') + parouvLatex + cha + parferLatex
case Opef.Im:
return getStr('im') + parouvLatex + cha + parferLatex
case Opef.Core:
case Opef.CoreC:
return getStr('core') + parouvLatex + cha + parferLatex
default:
return ''
} // switch Opef}}
}
// Fonction ajoutée version 6.4.8 pour un meilleur rendu des conjugués
/** @inheritDoc */
CFonction.prototype.chaineLatex = function (varFor, fracSimple = false) {
const parouvLatex = '\\left('
const parferLatex = '\\right)'
const op = this.operande
const nat = (this.opef)
switch (nat) {
case Opef.Conj:
if (op.nature() === CCbGlob.natOperation) {
if (op.ope === Ope.Mult) return this.chaineLatexSansPar(varFor, fracSimple)
else {
if (op.ope === Ope.Divi) {
return '\\,\\overline {' + parouvLatex + op.chaineLatexSansPar(varFor, fracSimple) + parferLatex + '}'
} else return '\\,' + parouvLatex + '\\overline {' + op.chaineLatexSansPar(varFor, fracSimple) + '}' + parferLatex
}
} else return this.chaineLatexSansPar(varFor, fracSimple)
case Opef.Left:
case Opef.LeftC:
return getLeft(this.operande).chaineLatex(varFor, fracSimple)
case Opef.Right:
case Opef.RightC:
return getRight(this.operande).chaineLatex(varFor, fracSimple)
case Opef.Core:
case Opef.CoreC:
return this.operande.getCore().chaineLatex(varFor, fracSimple)
default:
return this.chaineLatexSansPar(varFor, fracSimple)
}
}
CFonction.prototype.read = function (inps, list) {
CCb.prototype.read.call(this, inps, list)
this.opef = inps.readByte()
// A partir de la version 3.0, décalage des indices de fonctions complexes
if ((this.nVersion === 1) && (this.opef >= 19)) this.opef += 45
this.operande = inps.readObject(list)
if (this.opef === Opef.Rand) {
this.valeurDejaPrise = inps.readDouble()
this.dejaPositionne = true
}
}
CFonction.prototype.write = function (oups, list) {
CCb.prototype.write.call(this, oups, list)
oups.writeByte(this.opef)
oups.writeObject(this.operande)
if (this.opef === Opef.Rand) {
oups.writeDouble(this.valeurDejaPrise)
}
}
CFonction.prototype.estConstant = function () {
return (this.opef !== Opef.Rand) && this.operande.estConstant()
}
CFonction.prototype.deriveePossible = function (indiceVariable) {
return this.operande.deriveePossible(indiceVariable)
}
CFonction.prototype.calculAvecValeursRemplacees = function (bfrac) {
return new CFonction(this.listeProprietaire, this.opef, this.operande.calculAvecValeursRemplacees(bfrac))
}
// Déplacé ici version 6.4.7
CFonction.prototype.calculNormalise = function (rempval, sousdivnorm, rempDecParFrac, eliminMult1 = true) {
switch (this.opef) {
case Opef.Left:
case Opef.LeftC:
// return this.operande.membreGauche().calculNormalise(rempval, sousdivnorm, rempDecParFrac, eliminMult1)
return getLeft(this.operande).calculNormalise(rempval, sousdivnorm, rempDecParFrac, eliminMult1)
case Opef.Right:
case Opef.RightC:
// return this.operande.membreDroit().calculNormalise(rempval, sousdivnorm, rempDecParFrac, eliminMult1)
return getRight(this.operande).calculNormalise(rempval, sousdivnorm, rempDecParFrac, eliminMult1)
case Opef.Core:
case Opef.CoreC:
return this.operande.getCore().calculNormalise(rempval, sousdivnorm, rempDecParFrac, eliminMult1)
default :
return new CFonction(this.listeProprietaire, this.opef, this.operande.calculNormalise(rempval, sousdivnorm, rempDecParFrac, eliminMult1))
}
}