public override INumber Multiple(Runtime.RuntimeData runtime, INumber val) { MultipleFormula mf = new MultipleFormula(); mf.AddItem(runtime, this); mf.AddItem(runtime, val); return(mf); }
public INumber ExecuteDiff(RuntimeData runtime, string t, INumber[] parameters) { var res = new FuncedINumber(runtime.Functions["cos"], parameters); var vaDiff = parameters[0].ExecuteDiff(runtime, t); if (vaDiff.Equals(runtime, Number.New(0))) { return(res); } MultipleFormula mf = new MultipleFormula(); mf.AddItem(runtime, vaDiff); mf.AddItem(runtime, res); return(mf); }
public INumber ExecuteDiff(RuntimeData runtime, string t, INumber[] parameters) { // log(xy) => log(x) + log(y) if (parameters[1] is MultipleFormula) { AdditionFormula af = new Expression.AdditionFormula(); foreach (var item in (parameters[1] as MultipleFormula).Items) { af.AddItem(runtime, this.ExecuteDiff(runtime, t, new INumber[] { parameters[0], item })); } return(af); } if (parameters[1] is Fraction) { AdditionFormula af = new Expression.AdditionFormula(); Fraction f = parameters[1] as Fraction; af.AddItem(runtime, this.ExecuteDiff(runtime, t, new INumber[] { parameters[0], f.Numerator })); af.AddItem(runtime, this.ExecuteDiff(runtime, t, new INumber[] { parameters[0], f.Denominator }).Multiple(runtime, Number.New(-1))); return(af); } // 普通のlogの微分 if (parameters[0] is NaturalLogarithm) { NaturalLogarithm e = parameters[0] as NaturalLogarithm; if (e.Pow.Equals(runtime, Number.New(1))) { var prm = parameters[1].ExecuteDiff(runtime, t); if (prm.Equals(runtime, Number.New(0)) || prm.Equals(runtime, Number.New(1))) { return(new Fraction( parameters[1], Number.New(1))); } else { MultipleFormula mf = new Expression.MultipleFormula(); mf.AddItem(runtime, prm); mf.AddItem(runtime, new Fraction( parameters[1], Number.New(1))); return(mf); } } } else if (!FuncCalc.Runtime.Func.Differential.IsConstValue(runtime, parameters[0])) { throw new RuntimeException("底に定数以外が含まれたlogの微分を行うことはできません。"); } INumber param1Diff = parameters[1].ExecuteDiff(runtime, t); if (param1Diff.Equals(runtime, Number.New(0))) { param1Diff = Number.New(1); } MultipleFormula den = new MultipleFormula(); den.AddItem(runtime, parameters[1]); den.AddItem(runtime, new FuncedINumber(this, new INumber[] { new NaturalLogarithm(), parameters[0] })); Fraction res = new Fraction(den, param1Diff); return(res); }
public override INumber Execute(RuntimeData runtime, params INumber[] parameters) { string varname = "x"; INumber f = parameters[0].Optimise(runtime); if (f is IConstParameter) { throw new RuntimeException("定数から方程式を評価することはできません。", parameters[0]); } if (f is Variable) { if ((f as Variable).Name == varname) { return(Number.New(0)); } else { throw new RuntimeException("この条件では方程式を解決することはできません。"); } } if (f is Member) { if ((f as Member).Text == varname) { return(Number.New(0)); } else { throw new RuntimeException("この条件では方程式を解決することはできません。"); } } if (f is MultipleFormula) { bool flag = false; MultipleFormula mf = f as MultipleFormula; for (int i = 0; i < mf.Items.Count; i++) { if (mf.Items[i] is Variable && (mf.Items[i] as Variable).Name == varname) { flag = true; } if (mf.Items[i] is Member && (mf.Items[i] as Member).Text == varname) { flag = true; } } if (flag) { return(Number.New(0)); } else { throw new RuntimeException("この条件では方程式を解決することはできません。"); } } if (!(f is AdditionFormula)) { throw new RuntimeException(string.Format("まだ '{0}' の式の解決は対応していません。", f.GetType().FullName)); } Dictionary <int, INumber> keisu = new Dictionary <int, INumber>(); // 式の係数を調べる AdditionFormula af = f as AdditionFormula; for (int i = 0; i < af.Items.Length; i++) { var item = af.Items[i]; INumber pow = null; var res = CheckMulti(runtime, varname, item, out pow); if (pow is Number) { long p = (pow as Number).Value; if (p > int.MaxValue) { throw new RuntimeException("int.MaxValueを超えるべき乗を含む式の解決はできません。"); } int ip = (int)p; if (!keisu.ContainsKey(ip)) { keisu.Add(ip, Number.New(0)); } keisu[ip] = keisu[ip].Add(runtime, res); } else { throw new RuntimeException("整数以外のべき乗の変数が指定された状態で方程式を解決することはできません。"); } } INumber result = null; // 一次方程式を解決する // 条件: x^2以上のべき乗がない // xの係数が0ではない if ((result = this.SolutionLinearEquation(runtime, varname, keisu)) != null) { return(result); } // 二次方程式を解決する // 条件: x^3以上のべき乗がない // x^2, x, 1のそれぞれの係数が実数であること // x^2の係数が0ではない if ((result = this.SolutionQuadraticEquation(runtime, varname, keisu)) != null) { return(result); } // 五次方程式を解決する // 無条件でエラーを出す。(解の公式は存在しないため計算を行うことができないため) if ((result = this.SolutionQuadraticEquation(runtime, varname, keisu)) != null) { return(result); } throw new RuntimeException("式を解決することができませんでした"); }
INumber CheckMulti(RuntimeData runtime, string varname, INumber val, out INumber pow) { if (val is IConstParameter) { pow = Number.New(0); return(val); } if (val is Variable) { if ((val as Variable).Name == varname) { pow = val.Pow; return((val as Variable).Multi); } else { pow = Number.New(0); return(val); } } if (val is Member) { if ((val as Member).Text == varname) { pow = val.Pow; return((val as Member).Multi); } else { pow = Number.New(0); return(val); } } if (val is MultipleFormula) { MultipleFormula mf = val as MultipleFormula; INumber res = Number.New(0); INumber pres = Number.New(1); bool flag = false; for (int i = 0; i < mf.Items.Count; i++) { var item = mf.Items[i]; INumber p = null; var r = this.CheckMulti(runtime, varname, item, out p); if (p is Number && (p as Number).Value == 0) { res = res.Multiple(runtime, r); } else { flag = true; pres = pres.Add(runtime, p); res = res.Multiple(runtime, r); } } if (flag) { pow = pres; return(res); } else { pow = Number.New(0); return(res); } } if (val is AdditionFormula) { throw new RuntimeException("バグ: [AF]のアイテム評価関数に[AF]が指定されました。", val); } throw new NotImplementedException("[AF]のアイテム評価関数の未実装"); }