Example #1
0
        public override INumber Multiple(RuntimeData runtime, INumber val)
        {
            if (this.Value == 0)
            {
                return(Number.New(0));
            }

            var v = val.Eval(runtime);

            if (v is Number)
            {
                if (this.Pow.Equals(runtime, val.Pow))
                {
                    return(Number.New(this.Value * (v as Number).Value));
                }
                else
                {
                    MultipleFormula mf = new MultipleFormula();
                    mf.AddItem(runtime, this);
                    mf.AddItem(runtime, val);
                    return(mf);
                }
            }

            return(val.Multiple(runtime, this));
        }
Example #2
0
        public override INumber Multiple(RuntimeData runtime, INumber val)
        {
            var v = val.Eval(runtime);

            if (v is Variable &&
                (v as Variable).Name == this.Name)
            {
                var me = this.Clone() as Variable;
                me.multi = me.multi.Multiple(runtime, (v as Variable).multi);
                me.Pow   = me.Pow.Add(runtime, (v as Variable).Pow);
                return(me);
            }
            if (v is Number && (v as Number).Value == 1)
            {
                return(this);
            }
            if (v is Number)
            {
                var me = this.Clone() as Variable;
                me.multi = me.multi.Multiple(runtime, v);
                return(me);
            }

            return(v.Multiple(runtime, this));

            MultipleFormula af = new MultipleFormula();

            af.AddItem(runtime, this);
            af.AddItem(runtime, v);
            return(af);
        }
Example #3
0
        public override INumber Multiple(RuntimeData runtime, INumber val)
        {
            if (val is Number && (val as Number).Value == 1)
            {
                return(this.Clone());
            }

            if (val is Number || val is Fraction)
            {
                if (this.Pow is Number && (this.Pow as Number).Value == 1)
                {
                    AdditionFormula aa = new AdditionFormula();
                    foreach (var item in this.items)
                    {
                        aa.AddItem(runtime, item.Multiple(runtime, val));
                    }
                    return(aa);
                }
            }
            else
            {
                MultipleFormula mf = new MultipleFormula();
                mf.AddItem(runtime, this);
                mf.AddItem(runtime, val);
                return(mf);
            }

            throw new NotImplementedException();
        }
Example #4
0
        public override INumber Multiple(RuntimeData runtime, INumber val)
        {
            MultipleFormula mf = new MultipleFormula();

            mf.AddItem(runtime, val);
            mf.AddItem(runtime, this);
            return(mf);
        }
Example #5
0
        public override INumber Multiple(RuntimeData runtime, INumber val)
        {
            if (val is Fraction)
            {
                var f = val.Clone() as Fraction;
                f.Numerator = f.Numerator.Multiple(runtime, this);
                return(f);
            }
            if (val is Number && (val as Number).Value == 0)
            {
                return(Number.New(0));
            }

            if (val is Number || val is Variable || val is Member)
            {
                var me = this.Clone() as MultipleFormula;
                me.AddItem(runtime, val);
                return(me);
            }
            else if (val is AdditionFormula)
            {
                var res = this.Clone() as MultipleFormula;
                res.AddItem(runtime, val);
                return(res);
            }
            else if (val is MultipleFormula)
            {
                var res = new MultipleFormula();
                var v   = val as MultipleFormula;
                for (int i = 0; i < this.items.Count; i++)
                {
                    bool flag = false;
                    for (int j = 0; j < v.items.Count; j++)
                    {
                        if (this.items[i].CanJoin(runtime, v.items[j]))
                        {
                            res.AddItem(runtime, this.items[i].Multiple(runtime, v.items[j]));
                            flag = true; break;
                        }
                    }
                    if (!flag) // ConJoinに引っかからなかった
                    {
                        res.AddItem(runtime, this.items[i]);
                    }
                }
                return(res);
            }
            else
            {
                var me = this.Clone() as MultipleFormula;
                me.AddItem(runtime, val);
                return(me);
            }
        }
Example #6
0
        public override INumber Multiple(RuntimeData runtime, INumber val)
        {
            if (val is ImaginaryNumber)
            {
                Number res = Number.New(this.Value * (val as ImaginaryNumber).Value * -1);
                return(res);
            }

            MultipleFormula mf = new MultipleFormula();

            mf.AddItem(runtime, val);
            mf.AddItem(runtime, this);
            return(mf);
        }
Example #7
0
        public override INumber Integrate(RuntimeData runtime, string t)
        {
            INumber res = null;

            if (this.func is IIntegrateWithParameters)
            {
                res = (this.func as IIntegrateWithParameters).Integrate(runtime, t, this.param);

                // この段階ではpowのことは感がられていないので、pow部をここで処理する
                if (!(this.Pow is Number && (this.Pow as Number).Value == 1))
                {
                    throw new NotImplementedException("べき乗が1ではない関数の積分はまだ未対応です");

                    // 以下、微分のコードのコピペ
                    MultipleFormula mf = new MultipleFormula();
                    mf.AddItem(runtime, res);
                    INumber pow = this.Clone();
                    pow.Pow = pow.Pow.Subtract(runtime, Number.New(1));
                    mf.AddItem(runtime, pow);

                    res = mf;
                }

                if (runtime.Setting.DoOptimize)
                {
                    res = res.Optimise(runtime);
                }
            }
            else
            {
                res = new FuncedINumber(
                    runtime.Functions["intg"], new INumber[] { new Variable(new FuncCalc.Token(t, Analyzer.TokenType.Member)), this });

                // たぶんpowの部分が怪しいのでチェックすること
                Debugger.Break();
            }

            //最終処理部
            {
                // resが結果だけど、べき乗部分の処理をしていないかもしれないので要チェック
                Debugger.Break();
                if (!(this.Pow is Number && (this.Pow as Number).Value == 1))
                {
                    runtime.Setting.Logger.AddWarning("関数式の積分の部分は1以外のべき乗の計算を考慮していないので、結果がおかしくなっている可能性があります。");
                }

                return(res);
            }
        }
Example #8
0
        public override INumber ExecuteDiff(RuntimeData runtime, string t)
        {
            INumber res = null;

            if (this.func is IDiffWithParameters)
            {
                res = (this.func as IDiffWithParameters).ExecuteDiff(runtime, t, this.param);

                // この段階ではpowのことは感がられていないので、pow部をここで処理する
                if (!(this.Pow is Number && (this.Pow as Number).Value == 1))
                {
                    MultipleFormula mf = new MultipleFormula();
                    mf.AddItem(runtime, res);
                    INumber pow = this.Clone();
                    pow.Pow = pow.Pow.Subtract(runtime, Number.New(1));
                    mf.AddItem(runtime, pow);

                    res = mf;
                }

                if (runtime.Setting.DoOptimize)
                {
                    res = res.Optimise(runtime);
                }
            }
            else
            {
                res = new FuncedINumber(
                    runtime.Functions["diff"], new INumber[] { new Variable(new FuncCalc.Token(t, Analyzer.TokenType.Member)), this });

                // たぶんpowの部分が怪しいのでチェックすること
                Debugger.Break();
            }

            //最終処理部
            {
                var mf = Runtime.Func.Differential.DiffPow(runtime, t, this);
                if (mf != null)
                {
                    mf.AddItem(runtime, res);
                    return(mf);
                }
                else
                {
                    return(res);
                }
            }
        }
Example #9
0
        public override INumber ExecuteDiff(RuntimeData runtime, string t)
        {
            MultipleFormula mf = Runtime.Func.Differential.DiffPow(runtime, t, this);

            var res = this.Eval(runtime).ExecuteDiff(runtime, t);

            if (mf != null)
            {
                mf.AddItem(runtime, res);
                return(mf);
            }
            else
            {
                return(res);
            }
        }
Example #10
0
        public override INumber Multiple(RuntimeData runtime, INumber val)
        {
            if (val is IConstParameter)
            {
                var me = this.Clone() as FloatNumber;
                me.value *= (val as IConstParameter).ConstValue;
                return(me);
            }
            if (val is InfinityValue)
            {
                return(val.Multiple(runtime, this));
            }

            MultipleFormula mf = new MultipleFormula();

            mf.AddItem(runtime, val);
            mf.AddItem(runtime, this);

            return(mf);
        }
Example #11
0
 public override INumber Multiple(RuntimeData runtime, INumber val)
 {
     if (val.ValueType == ValueType.Plus)
     {
         return(this == InfinityValue.value ? InfinityValue.value : InfinityValue.minusvalue);
     }
     else if (val.ValueType == ValueType.Minus)
     {
         return(this == InfinityValue.value ? InfinityValue.minusvalue : InfinityValue.value);
     }
     else   // val.ValueType == ValueType.Unknown
     {
         if (val is MultipleFormula)
         {
             var             res = this;
             MultipleFormula mf  = new Expression.MultipleFormula();
             for (int i = 0; i < (val as MultipleFormula).Items.Count; i++)
             {
                 var item = (val as MultipleFormula).Items[i];
                 if (item.ValueType == ValueType.Minus)
                 {
                     res = (res == InfinityValue.value) ? InfinityValue.minusvalue : InfinityValue.value;
                 }
                 if (item.ValueType == ValueType.Unknown)
                 {
                     mf.AddItem(runtime, item);
                 }
             }
             mf.AddItem(runtime, res);
             return(mf);
         }
         else
         {
             MultipleFormula mf = new MultipleFormula();
             mf.AddItem(runtime, this);
             mf.AddItem(runtime, val);
             return(mf);
         }
     }
 }
Example #12
0
        public override INumber Power(RuntimeData runtime, INumber val)
        {
            if (val is Number)
            {
                var pow = val as Number;
                if (pow.Value == 0)
                {
                    return(Number.New(1));
                }
                if (pow.Value < 0)   // 乗数がマイナスだったら
                {
                    var res = this.Clone();
                    res = res.Power(runtime, Number.New(pow.Value * -1));
                    return(new Fraction(res, Number.New(1)));
                }
                if (pow.Value % 2 == 0)   // 乗数が偶数だったら
                {
                    if (pow.Value % 4 == 0)
                    {
                        return(Number.New(this.Value).Power(runtime, pow));
                    }
                    else
                    {
                        return(Number.New(this.Value).Power(runtime, pow).Multiple(runtime, Number.New(-1)));
                    }
                }
                else
                {
                    MultipleFormula mf = new MultipleFormula();
                    mf.AddItem(runtime, Number.New(this.Value).Power(runtime, Number.New(pow.Value - 1)));
                    mf.AddItem(runtime, this);
                    return(mf);
                }
            }

            throw new NotImplementedException("虚数に数値以外のべき乗含むのはまだ実装していません。");
        }
Example #13
0
        public override INumber Optimise(RuntimeData runtime)
        {
            var me = this.Clone() as Fraction;

            // [分母][分子]が分数の場合は有理化する
            if (me.Denominator is Fraction && me.Numerator is Fraction)
            {
                me = new Fraction(
                    (me.Denominator as Fraction).Numerator.Multiple(runtime, (me.Numerator as Fraction).Denominator),
                    (me.Denominator as Fraction).Denominator.Multiple(runtime, (me.Denominator as Fraction).Numerator)
                    );
            }
            else if (me.Denominator is Fraction)
            {
                me = new Fraction(
                    (me.Denominator as Fraction).Numerator,
                    (me.Denominator as Fraction).Denominator.Multiple(runtime, me.Numerator)
                    );
            }
            else if (me.Numerator is Fraction)
            {
                me = new Fraction(
                    me.Denominator.Multiple(runtime, (me.Numerator as Fraction).Denominator),
                    (me.Numerator as Fraction).Numerator
                    );
            }

            // 分母が0だったら無限を返す
            if (me.Denominator.Eval(runtime).Equals(runtime, Number.New(0)))
            {
                if (me.Numerator.ValueType == ValueType.Plus)
                {
                    return(InfinityValue.PlusValue);
                }
                else if (me.Numerator.ValueType == ValueType.Minus)
                {
                    return(InfinityValue.MinusValue);
                }
                else
                {
                    MultipleFormula mf = new MultipleFormula();
                    mf.AddItem(runtime, this.Numerator);
                    mf.AddItem(runtime, InfinityValue.PlusValue);
                    return(mf);

                    ;
                }
            }

            if (me.Numerator is Number && me.Denominator is Number)
            {
                // 最大公約数を求めて分母分子を割る
                var func = runtime.Functions.Where(
                    f => f.Key == "gcd" && f.Value.Parameter[0] == ExpressionType.Number && f.Value.Parameter[1] == ExpressionType.Number);
                var res = func.First().Value.Execute(runtime, me.Denominator, me.Numerator);
                me.Denominator = me.Denominator.Divide(runtime, res);
                me.Numerator   = me.Numerator.Divide(runtime, res);
            }
            else if (me.Denominator is MultipleFormula && this.Numerator is Variable)
            {
                bool dv_res; INumber dr_res;
                dr_res = (me.Denominator as MultipleFormula).TryDivide(runtime, me.Numerator, out dv_res);
                if (dv_res)
                {
                    me.Numerator   = Number.New(1);
                    me.Denominator = dr_res;
                }
                else
                {
                }
            }
            else if (me.Denominator is MultipleFormula && me.Numerator is MultipleFormula)
            {
                for (int i = 0; i < (me.Numerator as MultipleFormula).Count; i++)
                {
                    var  dt = (me.Numerator as MultipleFormula).Items[i];
                    bool dv_res;
                    var  r = (me.Denominator as MultipleFormula).TryDivide(runtime, dt, out dv_res);
                    if (dv_res)
                    {
                        me.Denominator = r;
                        (me.Numerator as MultipleFormula).Items.RemoveAt(i);
                        i--;
                    }
                    else
                    {
                    }
                }
            }

            // 分母分子を最適化する

            me.Denominator = me.Denominator.Optimise(runtime);
            me.Numerator   = me.Numerator.Optimise(runtime);


            // メンバーを含む式で約分できるか確かめる
            if (me.Numerator is MultipleFormula && me.Numerator.Pow.Equals(runtime, Number.New(1)) &&
                me.Denominator is MultipleFormula && me.Denominator.Pow.Equals(runtime, Number.New(1)))
            {
                var  den  = me.Denominator as MultipleFormula;
                bool flag = false;
                for (int i = 0; i < (me.Numerator as MultipleFormula).Count; i++)
                {
                    bool res;
                    var  fm = den.TryDivide(runtime, (me.Numerator as MultipleFormula).Items[i], out res);
                    if (res)
                    {
                        flag           = true;
                        me.Denominator = den;
                        if (fm is MultipleFormula)
                        {
                            den = fm as MultipleFormula;
                        }
                        else
                        {
                            break;
                        }

                        (me.Numerator as MultipleFormula).Items.RemoveAt(i);
                        i--;
                    }
                }
            }


            // 分母が1だったら分子部分だけを返す
            if (me.Denominator.Equals(runtime, Number.New(1)))
            {
                return(me.Numerator);
            }



            return(me);
        }
Example #14
0
        public INumber TryDivide(RuntimeData runtime, INumber val, out bool result)
        {
            // IConstParameterで割ろうとした場合はBase.Divideでも対応できるのでここでは割愛する

            // メンバー(変数)で割ろうとした場合
            Variable v = val as Variable;

            if (v != null || (v = val.Eval(runtime) as Variable) is Variable)
            {
                var me = this.Clone() as MultipleFormula;

                for (int i = 0; i < me.items.Count; i++)
                {
                    var item = me.items[i];
                    if (item is MultipleFormula)
                    {
                        throw new FuncCalcException("MultipleFormulaの中にMultipleFormulaが含まれています。", this);
                    }

                    if (item is Variable)
                    {
                        var res = item.Divide(runtime, v);
                        if (res is Number && (res as Number).Value == 1)
                        {
                            me.items.RemoveAt(i);
                            result = true;
                            return(me);
                        }
                        me.items[i] = res;
                        result      = true;
                        return(me);
                    }
                }
            }
            if (val is MultipleFormula)
            {
                MultipleFormula den  = new Expression.MultipleFormula();
                INumber         num  = this.Clone() as MultipleFormula;
                MultipleFormula f    = val as MultipleFormula;
                bool            flag = false;

                for (int i = 0; i < f.items.Count; i++)
                {
                    var  ex = f.items[i];
                    bool dv_res; INumber res;
                    res = (num as MultipleFormula).TryDivide(runtime, ex, out dv_res);
                    if (dv_res)
                    {
                        flag = true;
                        if (res is MultipleFormula)
                        {
                            num = res as MultipleFormula;
                        }
                        else
                        {
                            num = res;
                            for (int j = i + 1; j < f.items.Count; j++)
                            {
                                den.AddItem(runtime, f.items[j]);
                            }
                            break;
                        }
                    }
                    else
                    {
                        den.AddItem(runtime, ex);
                    }
                }
                if (!flag)
                {
                    result = false; return(null);
                }
                else
                {
                    result = true;

                    // numの条件判定はdenより先に行う
                    if (num is MultipleFormula)
                    {
                        INumber d = den;
                        if (den.items.Count == 0)
                        {
                            return(num);
                        }
                        if (den.items.Count == 1)
                        {
                            d = den.items[0];
                        }

                        if ((num as MultipleFormula).items.Count == 0)
                        {
                            return(new Fraction(d, Number.New(1)));
                        }
                        if ((num as MultipleFormula).items.Count == 1)
                        {
                            return(new Fraction(d, (num as MultipleFormula).items[0]));
                        }
                    }

                    // 最低限の形で返す
                    if (den.items.Count == 0)
                    {
                        return(num);
                    }
                    if (den.items.Count == 1)
                    {
                        var res = new Fraction(den.items[0], num);
                        if (runtime.Setting.DoOptimize)
                        {
                            return(res.Optimise(runtime));
                        }
                        else
                        {
                            return(res);
                        }
                    }

                    return(new Fraction(den, num));
                }
            }

            result = false;
            return(null);
        }