Beispiel #1
0
        public virtual Algebraic Map(LambdaAlgebraic lambda, Algebraic arg)
        {
            if (arg == null)
            {
                var r = lambda.SymEval(this);

                if (r != null)
                {
                    return(r);
                }

                var fname = lambda.GetType().Name;

                if (fname.StartsWith("Lambda", StringComparison.Ordinal))
                {
                    fname = fname.Substring("Lambda".Length);
                    fname = fname.ToLower();

                    return(FunctionVariable.Create(fname, this));
                }

                throw new SymbolicException("Wrong type of arguments.");
            }

            return(lambda.SymEval(this, arg));
        }
Beispiel #2
0
        public virtual Algebraic divExponential(Algebraic x, FunctionVariable fv, int n)
        {
            var a = new Algebraic[2];

            a[1] = x;

            Algebraic xk = Symbol.ZERO;

            for (int i = n; i >= 0; i--)
            {
                var kf = FunctionVariable.Create("exp", fv.Var).Pow(i);

                a[0] = a[1];
                a[1] = kf;

                Poly.polydiv(a, fv);

                if (!a[0].Equals(Symbol.ZERO))
                {
                    var kfi = FunctionVariable.Create("exp", -fv.Var) ^ (n - i);

                    xk = xk + a[0] * kfi;
                }

                if (Equals(a[1], Symbol.ZERO))
                {
                    break;
                }
            }

            return(SymEval(xk));
        }
Beispiel #3
0
        internal static Algebraic finvert(FunctionVariable f, Algebraic b)
        {
            if (f.Name.Equals("sqrt"))
            {
                return(b * b - f.Var);
            }

            if (f.Name.Equals("exp"))
            {
                return(FunctionVariable.Create("log", b) - f.Var);
            }

            if (f.Name.Equals("log"))
            {
                return(FunctionVariable.Create("exp", b) - f.Var);
            }

            if (f.Name.Equals("tan"))
            {
                return(FunctionVariable.Create("atan", b) - f.Var);
            }

            if (f.Name.Equals("atan"))
            {
                return(FunctionVariable.Create("tan", b) - f.Var);
            }

            throw new SymbolicException("Could not invert " + f);
        }
Beispiel #4
0
        internal override Algebraic SymEval(Algebraic x1)
        {
            if (v.Count == 0)
            {
                return(x1);
            }

            if (!(x1 is Exponential))
            {
                return(x1.Map(this));
            }

            var e = ( Exponential )x1;

            int exp = 1;

            var exp_b = e.exp_b;

            if (exp_b is Symbol && ( Symbol )exp_b < Symbol.ZERO)
            {
                exp  *= -1;
                exp_b = -exp_b;
            }

            var x = e.expvar;

            foreach (Polynomial y in v)
            {
                if (y.Var.Equals(x))
                {
                    var rat = exp_b / y[1];

                    if (rat is Symbol && !(( Symbol )rat).IsComplex())
                    {
                        int _cfs = cfs((( Symbol )rat).ToComplex().Re);

                        if (_cfs != 0 && _cfs != 1)
                        {
                            exp  *= _cfs;
                            exp_b = exp_b / new Complex(_cfs);
                        }
                    }
                }
            }

            var p = new Polynomial(x) * exp_b;

            p = FunctionVariable.Create("exp", p).Pow(exp);

            return(p * SymEval(e[1]) + SymEval(e[0]));
        }
Beispiel #5
0
        internal override Algebraic SymEval(Algebraic f)
        {
            if (gcd.Equals(Symbol.ZERO))
            {
                return(f);
            }
            if (f is Polynomial)
            {
                Polynomial p = ( Polynomial )f;

                if (p.Var is FunctionVariable && (( FunctionVariable )p.Var).Name.Equals("exp") && Poly.Degree((( FunctionVariable )p.Var).Var, vr) == 1)
                {
                    var arg = (( FunctionVariable )p.Var).Var;

                    var new_coef = new Algebraic[2];

                    new_coef[1] = gcd.ToComplex();
                    new_coef[0] = Symbol.ZERO;

                    Algebraic new_arg = new Polynomial(vr, new_coef);

                    var subst = FunctionVariable.Create("exp", new_arg);
                    var exp   = Poly.Coefficient(arg, vr, 1) / gcd;

                    if (!(exp is Symbol) && !(( Symbol )exp).IsInteger())
                    {
                        throw new SymbolicException("Not integer exponent in exponential simplification.");
                    }

                    subst = subst ^ (( Symbol )exp).ToInt();

                    subst = subst * FunctionVariable.Create("exp", Poly.Coefficient(arg, vr, 0));

                    var len = p.Coeffs.Length;

                    var r = SymEval(p[len - 1]);

                    for (var n = len - 2; n >= 0; n--)
                    {
                        r = r * subst + SymEval(p[n]);
                    }

                    return(r);
                }
            }

            return(f.Map(this));
        }
Beispiel #6
0
        public override int Eval(Stack st)
        {
            var narg = GetNarg(st);
            var arg  = GetAlgebraic(st);

            if (arg is Symbol)
            {
                st.Push(PreEval(( Symbol )arg));
            }
            else
            {
                st.Push(FunctionVariable.Create("factorial", arg));
            }

            return(0);
        }
Beispiel #7
0
        internal override Algebraic SymEval(Algebraic x, Algebraic y)
        {
            if (y is Complex && !y.IsComplex() && x is Complex && !x.IsComplex())
            {
                return(new Complex(Math.atan2((( Complex )y).Re, (( Complex )x).Re)));
            }

            if (Symbol.ZERO != x)
            {
                return(FunctionVariable.Create("atan", y / x) + FunctionVariable.Create("sign", y) * (Symbol.ONE - FunctionVariable.Create("sign", x)) * Symbol.PI / Symbol.TWO);
            }
            else
            {
                return((FunctionVariable.Create("sign", y) * Symbol.PI) / Symbol.TWO);
            }
        }
Beispiel #8
0
        internal override Algebraic SymEval(Algebraic x, Algebraic y)
        {
            if (x.Equals(Symbol.ZERO))
            {
                if (y.Equals(Symbol.ZERO))
                {
                    return(Symbol.ONE);
                }

                return(Symbol.ZERO);
            }

            if (y is Symbol && (( Symbol )y).IsInteger())
            {
                return(x.Pow((( Symbol )y).ToInt()));
            }

            return(FunctionVariable.Create("exp", FunctionVariable.Create("log", x) * y));
        }
Beispiel #9
0
        internal override Algebraic SymEval(Algebraic x)
        {
            if (x.Equals(Symbol.ONE))
            {
                return(Symbol.ZERO);
            }

            if (x.Equals(Symbol.MINUS))
            {
                return(Symbol.PI * Symbol.IONE);
            }

            if (x is Polynomial &&
                (( Polynomial )x).Degree() == 1 &&
                (( Polynomial )x)[0].Equals(Symbol.ZERO) &&
                (( Polynomial )x).Var is FunctionVariable &&
                (( FunctionVariable )(( Polynomial )x).Var).Name.Equals("exp"))
            {
                return((( FunctionVariable )(( Polynomial )x).Var).Var + FunctionVariable.Create("log", (( Polynomial )x)[1]));
            }

            return(null);
        }
Beispiel #10
0
        internal override Algebraic SymEval(Algebraic x)
        {
            if (x is Rational)
            {
                var xr = ( Rational )x;

                if (xr.den.Var is FunctionVariable &&
                    (( FunctionVariable )xr.den.Var).Name.Equals("exp") &&
                    (( FunctionVariable )xr.den.Var).Var.IsComplex())
                {
                    var fv = ( FunctionVariable )xr.den.Var;

                    int maxdeg = Math.max(Poly.Degree(xr.nom, fv), Poly.Degree(xr.den, fv));

                    if (maxdeg % 2 == 0)
                    {
                        return(divExponential(xr.nom, fv, maxdeg / 2) / divExponential(xr.den, fv, maxdeg / 2));
                    }
                    else
                    {
                        var fv2 = new FunctionVariable("exp", (( FunctionVariable )xr.den.Var).Var / Symbol.TWO, (( FunctionVariable )xr.den.Var).Body);

                        Algebraic ex = new Polynomial(fv2, new Algebraic[] { Symbol.ZERO, Symbol.ZERO, Symbol.ONE });

                        var xr1 = xr.nom.Value(xr.den.Var, ex) / xr.den.Value(xr.den.Var, ex);

                        return(SymEval(xr1));
                    }
                }
            }

            if (x is Polynomial && (( Polynomial )x).Var is FunctionVariable)
            {
                var xp = ( Polynomial )x;

                Algebraic xf = null;

                var fvar = ( FunctionVariable )xp.Var;

                if (fvar.Name.Equals("exp"))
                {
                    var re = fvar.Var.RealPart();
                    var im = fvar.Var.ImagPart();

                    if (im != Symbol.ZERO)

                    {
                        bool _minus = minus(im);

                        if (_minus)
                        {
                            im = -im;
                        }

                        var a = FunctionVariable.Create("exp", re);
                        var b = FunctionVariable.Create("cos", im);
                        var c = FunctionVariable.Create("sin", im) * Symbol.IONE;

                        xf = a * (_minus ? b - c : b + c);
                    }
                }

                if (fvar.Name.Equals("log"))
                {
                    var arg = fvar.Var;

                    Algebraic factor = Symbol.ONE, sum = Symbol.ZERO;

                    if (arg is Polynomial &&
                        (( Polynomial )arg).Degree() == 1 &&
                        (( Polynomial )arg).Var is FunctionVariable &&
                        (( Polynomial )arg)[0].Equals(Symbol.ZERO) &&
                        (( FunctionVariable )(( Polynomial )arg).Var).Name.Equals("sqrt"))
                    {
                        sum = FunctionVariable.Create("log", (( Polynomial )arg)[1]);

                        factor = new Complex(0.5);

                        arg = (( FunctionVariable )(( Polynomial )arg).Var).Var;

                        xf = FunctionVariable.Create("log", arg);
                    }

                    try
                    {
                        var re = arg.RealPart();
                        var im = arg.ImagPart();

                        if (im != Symbol.ZERO)
                        {
                            bool min_im = minus(im);

                            if (min_im)
                            {
                                im = -im;
                            }

                            var a1 = new SqrtExpand().SymEval(arg * arg.Conj());

                            var a = FunctionVariable.Create("log", a1) / Symbol.TWO;

                            var b1 = SymEval(re / im);

                            var b = FunctionVariable.Create("atan", b1) * Symbol.IONE;

                            xf = min_im ? a + b : a - b;

                            var pi2 = Symbol.PI * Symbol.IONE / Symbol.TWO;

                            xf = min_im ? xf - pi2 : xf + pi2;
                        }
                    }
                    catch (SymbolicException)
                    {
                    }

                    if (xf != null)
                    {
                        xf = xf * factor + sum;
                    }
                }

                if (xf == null)
                {
                    return(x.Map(this));
                }

                Algebraic r = Symbol.ZERO;

                for (int i = xp.Coeffs.Length - 1; i > 0; i--)
                {
                    r = (r + SymEval(xp[i])) * xf;
                }

                if (xp.Coeffs.Length > 0)
                {
                    r = r + SymEval(xp[0]);
                }

                return(r);
            }

            return(x.Map(this));
        }
Beispiel #11
0
        internal virtual Algebraic fzexakt(Symbol x)
        {
            if (x < Symbol.ZERO)
            {
                var r = fzexakt(( Symbol )(-x));

                if (r != null)
                {
                    return(r.Conj());
                }

                return(r);
            }

            if (x.IsInteger())
            {
                if (x.ToInt() % 2 == 0)
                {
                    return(Symbol.ONE);
                }
                else
                {
                    return(Symbol.MINUS);
                }
            }

            var qs = x + new Complex(0.5);

            if ((( Symbol )qs).IsInteger())
            {
                if ((( Symbol )qs).ToInt() % 2 == 0)
                {
                    return(Symbol.IMINUS);
                }
                else
                {
                    return(Symbol.IONE);
                }
            }

            qs = x * new Complex(4);

            if ((( Symbol )qs).IsInteger())
            {
                var sq2 = FunctionVariable.Create("sqrt", new Complex(0.5));

                switch ((( Symbol )qs).ToInt() % 8)
                {
                case 1: return((Symbol.ONE + Symbol.IONE) / Symbol.SQRT2);

                case 3: return((Symbol.MINUS + Symbol.IONE) / Symbol.SQRT2);

                case 5: return((Symbol.MINUS + Symbol.IMINUS) / Symbol.SQRT2);

                case 7: return((Symbol.ONE + Symbol.IMINUS) / Symbol.SQRT2);
                }
            }

            qs = x * new Complex(6);

            if ((( Symbol )qs).IsInteger())
            {
                switch ((( Symbol )qs).ToInt() % 12)
                {
                case 1: return((Symbol.SQRT3 + Symbol.IONE) / Symbol.TWO);

                case 2: return((Symbol.ONE + Symbol.SQRT3) * Symbol.IONE / Symbol.TWO);

                case 4: return((Symbol.SQRT3 * Symbol.IONE + Symbol.MINUS) / Symbol.TWO);

                case 5: return((Symbol.IONE - Symbol.SQRT3) / Symbol.TWO);

                case 7: return((Symbol.IMINUS - Symbol.SQRT3) / Symbol.TWO);

                case 8: return((Symbol.SQRT3 * Symbol.IMINUS - Symbol.ONE) / Symbol.TWO);

                case 10: return((Symbol.SQRT3 * Symbol.IMINUS + Symbol.ONE) / Symbol.TWO);

                case 11: return((Symbol.IMINUS + Symbol.SQRT3) / Symbol.TWO);
                }
            }

            return(null);
        }
Beispiel #12
0
        internal override Algebraic SymEval(Algebraic f)
        {
            if (f is Rational)
            {
                var r = ( Rational )f;

                var nom = SymEval(r.nom);
                var den = SymEval(r.den);

                if (den is Symbol)
                {
                    return(SymEval(nom / den));
                }

                if (den is Exponential && (( Polynomial )den)[0].Equals(Symbol.ZERO) && (( Polynomial )den)[1] is Symbol)
                {
                    if (nom is Symbol || nom is Polynomial)
                    {
                        var denx = ( Exponential )den;

                        var den_inv = new Exponential(Symbol.ONE / denx[1], Symbol.ZERO, denx.expvar, -denx.exp_b);

                        return(nom * den_inv);
                    }
                }

                f = nom / den;

                return(f);
            }

            if (f is Exponential)
            {
                return(f.Map(this));
            }

            if (!(f is Polynomial))
            {
                return(f.Map(this));
            }

            var fp = ( Polynomial )f;

            if (!(fp.Var is FunctionVariable) || !(( FunctionVariable )fp.Var).Name.Equals("exp"))
            {
                return(f.Map(this));
            }

            var arg = (( FunctionVariable )fp.Var).Var.Reduce();

            if (arg is Symbol)
            {
                return(fp.value(FunctionVariable.Create("exp", arg)).Map(this));
            }

            if (!(arg is Polynomial) || (( Polynomial )arg).Degree() != 1)
            {
                return(f.Map(this));
            }

            Algebraic z = Symbol.ZERO;

            var a = (( Polynomial )arg)[1];

            for (int i = 1; i < fp.Coeffs.Length; i++)
            {
                var b = (( Polynomial )arg)[0];

                Symbol I = new Complex(( double )i);

                Algebraic ebi = Symbol.ONE;

                while (b is Polynomial && (( Polynomial )b).Degree() == 1)
                {
                    var p = ( Polynomial )b;

                    var f1 = FunctionVariable.Create("exp", new Polynomial(p.Var) * p[1] * I);

                    f1 = Exponential.poly2exp(f1);

                    ebi = ebi * f1;

                    b = (( Polynomial )b)[0];
                }

                ebi = ebi * FunctionVariable.Create("exp", b * I);

                var cf = SymEval(fp[i] * ebi);

                var f2 = FunctionVariable.Create("exp", new Polynomial((( Polynomial )arg).Var) * a * I);

                f2 = Exponential.poly2exp(f2);

                z = z + cf * f2;
            }

            if (fp.Coeffs.Length > 0)
            {
                z = z + SymEval(fp[0]);
            }

            return(Exponential.poly2exp(z));
        }