Exemplo n.º 1
0
        public static void TestSymbolism()
        {
            // Create some constants.
            ComputerAlgebra.Expression A = 2;
            ComputerAlgebra.Constant   B = ComputerAlgebra.Constant.New(3);

            // Create some variables.
            ComputerAlgebra.Expression x = "x";
            Variable y = Variable.New("y");

            // Create basic expression with operator overloads.
            ComputerAlgebra.Expression f = A * x + B * y + 4;

            // This expression uses the implicit conversion from string to
            // Expression, which parses the string.
            ComputerAlgebra.Expression g = "5*x + C*y + 8";

            // Create a system of equations from the above expressions.
            var system = new List <Equal>()
            {
                Equal.New(f, 0),
                Equal.New(g, 0),
            };

            // We can now solve the system of equations for x and y. Since the
            // equations have a variable 'C', the solutions will not be
            // constants.
            List <Arrow> solutions = system.Solve(x, y);

            Debug.WriteLine("The solutions are:");
            foreach (Arrow i in solutions)
            {
                Debug.WriteLine(i.ToString());
            }
        }
Exemplo n.º 2
0
        // Expand N(x)/D(x) using partial fractions.
        private static Expression ExpandPartialFractions(Expression N, Expression D, Expression x)
        {
            List <Expression> terms    = new List <Expression>();
            List <Variable>   unknowns = new List <Variable>();
            List <Expression> basis    = new List <Expression>();

            foreach (Expression i in Product.TermsOf(D))
            {
                // Get the multiplicity of this basis term.
                Expression e = i;
                int        n = Power.IntegralExponentOf(e);
                if (n != 1)
                {
                    e = ((Power)i).Left;
                }

                // Convert to a polynomial.
                Polynomial Pi = Polynomial.New(e, x);

                // Add new terms for each multiplicity n.
                for (int j = 1; j <= n; ++j)
                {
                    // Expression for the unknown numerator of this term.
                    Expression unknown = 0;
                    for (int k = 0; k < Pi.Degree; ++k)
                    {
                        Variable Ai = Variable.New("_A" + unknowns.Count.ToString());
                        unknown += Ai * (x ^ k);
                        unknowns.Add(Ai);
                    }

                    terms.Add(Product.New(unknown, Power.New(e, -j)));
                }
                basis.Add(i);
            }

            // Equate the original expression with the decomposed expressions.
            D = Sum.New(terms.Select(j => (Expression)(D * j))).Expand();
            Polynomial l = Polynomial.New(N, x);
            Polynomial r = Polynomial.New(D, x);

            // Equate terms of equal degree and solve for the unknowns.
            int          degree = Math.Max(l.Degree, r.Degree);
            List <Equal> eqs    = new List <Equal>(degree + 1);

            for (int i = 0; i <= degree; ++i)
            {
                eqs.Add(Equal.New(l[i], r[i]));
            }
            List <Arrow> A = eqs.Solve(unknowns);

            // Substitute the now knowns.
            return(Sum.New(terms.Select(i => i.Evaluate(A))));
        }
Exemplo n.º 3
0
        /// <summary>
        /// Solve a linear system of differential equations with initial conditions using the laplace transform.
        /// </summary>
        /// <param name="f"></param>
        /// <param name="y"></param>
        /// <param name="y0"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        public static List <Arrow> DSolve(this IEnumerable <Equal> f, IEnumerable <Expression> y, IEnumerable <Arrow> y0, Expression t)
        {
            // Find F(s) = L[f(t)] and substitute the initial conditions.
            List <Equal> F = f.Select(i => Equal.New(
                                          L(i.Left, t).Evaluate(y0),
                                          L(i.Right, t).Evaluate(y0))).ToList();

            // Solve F for Y(s) = L[y(t)].
            List <Arrow> Y = F.Solve(y.Select(i => L(i, t)));

            // Take L^-1[Y].
            Y = Y.Select(i => Arrow.New(IL(i.Left, t), IL(i.Right, t))).ToList();
            if (Y.DependsOn(s))
            {
                throw new Exception("Could not find L^-1[Y(s)].");
            }

            return(Y);
        }
Exemplo n.º 4
0
        static void Main(string[] args)
        {
            // Create some constants.
            Expression A = 2;
            Constant   B = Constant.New(3);

            // Create some variables.
            Expression x = "x";
            Variable   y = Variable.New("y");

            // Create a basic expressions.
            Expression f = A * x + B * y + 4;

            // This expression uses the implicit conversion from string to
            // Expression, which parses the string.
            Expression g = "5*x + C*y + 8";

            // Create a system of equations from the above expressions.
            var system = new List <Equal>()
            {
                Equal.New(f, 0),
                Equal.New(g, 0),
            };

            // We can now solve the system of equations for x and y. Since the
            // equations have a variable 'C', the solutions will not be
            // constants.
            List <Arrow> solutions = system.Solve(x, y);

            Console.WriteLine("The solutions are:");
            foreach (Arrow i in solutions)
            {
                Console.WriteLine(i.ToString());
            }

            // A fundamental building block of ComputerAlgebra is the 'Arrow'
            // expression. Arrow expressions define the value of one expression
            // to be the value given by another expression. For example, 'x->2'
            // defines the expression 'x' to have the value '2'.

            // The 'Solve' function used above returns a list of Arrow
            // expressions defining the solutions of the system.

            // Arrow expressions are used by the 'Evaluate' function to
            // substitute values for expressions into other expressions. To
            // demonstrate the usage of Evaluate, let's validate the solution
            // by using Evaluate to substitute the solutions into the original
            // system of equations, and then substitute a value for C.
            Expression f_xy = f.Evaluate(solutions).Evaluate(Arrow.New("C", 2));
            Expression g_xy = g.Evaluate(solutions).Evaluate(Arrow.New("C", 2));

            if ((f_xy == 0) && (g_xy == 0))
            {
                Console.WriteLine("Success!");
            }
            else
            {
                Console.WriteLine("Failure! f = {0}, g = {1}", f_xy, g_xy);
            }

            // Suppose we need to evaluate the solutions efficiently many times.
            // We can compile the solutions to delegates where 'C' is a
            // parameter to the delegate, allowing it to be specified later.
            var x_C = x.Evaluate(solutions).Compile <Func <double, double> >("C");
            var y_C = y.Evaluate(solutions).Compile <Func <double, double> >("C");

            for (int i = 0; i < 20; ++i)
            {
                double C = i / 2.0;
                Console.WriteLine("C = {0}: (x, y) = ({1}, {2})", C, x_C(C), y_C(C));
            }
        }
Exemplo n.º 5
0
        static void Main(string[] args)
        {
            // Create some constants.
            Expression A = 2;
            Constant B = Constant.New(3);

            // Create some variables.
            Expression x = "x";
            Variable y = Variable.New("y");

            // Create a basic expressions.
            Expression f = A*x + B*y + 4;

            // This expression uses the implicit conversion from string to
            // Expression, which parses the string.
            Expression g = "5*x + C*y + 8";

            // Create a system of equations from the above expressions.
            var system = new List<Equal>()
            {
                Equal.New(f, 0),
                Equal.New(g, 0),
            };

            // We can now solve the system of equations for x and y. Since the
            // equations have a variable 'C', the solutions will not be
            // constants.
            List<Arrow> solutions = system.Solve(x, y);
            Console.WriteLine("The solutions are:");
            foreach (Arrow i in solutions)
                Console.WriteLine(i.ToString());

            // A fundamental building block of ComputerAlgebra is the 'Arrow'
            // expression. Arrow expressions define the value of one expression
            // to be the value given by another expression. For example, 'x->2'
            // defines the expression 'x' to have the value '2'.

            // The 'Solve' function used above returns a list of Arrow
            // expressions defining the solutions of the system.

            // Arrow expressions are used by the 'Evaluate' function to
            // substitute values for expressions into other expressions. To
            // demonstrate the usage of Evaluate, let's validate the solution
            // by using Evaluate to substitute the solutions into the original
            // system of equations, and then substitute a value for C.
            Expression f_xy = f.Evaluate(solutions).Evaluate(Arrow.New("C", 2));
            Expression g_xy = g.Evaluate(solutions).Evaluate(Arrow.New("C", 2));
            if ((f_xy == 0) && (g_xy == 0))
                Console.WriteLine("Success!");
            else
                Console.WriteLine("Failure! f = {0}, g = {1}", f_xy, g_xy);

            // Suppose we need to evaluate the solutions efficiently many times.
            // We can compile the solutions to delegates where 'C' is a
            // parameter to the delegate, allowing it to be specified later.
            var x_C = x.Evaluate(solutions).Compile<Func<double, double>>("C");
            var y_C = y.Evaluate(solutions).Compile<Func<double, double>>("C");

            for (int i = 0; i < 20; ++i)
            {
                double C = i / 2.0;
                Console.WriteLine("C = {0}: (x, y) = ({1}, {2})", C, x_C(C), y_C(C));
            }
        }
Exemplo n.º 6
0
        // Expand N(x)/D(x) using partial fractions.
        private static Expression ExpandPartialFractions(Expression N, Expression D, Expression x)
        {
            List<Expression> terms = new List<Expression>();
            List<Variable> unknowns = new List<Variable>();
            List<Expression> basis = new List<Expression>();
            foreach (Expression i in Product.TermsOf(D))
            {
                // Get the multiplicity of this basis term.
                Expression e = i;
                int n = Power.IntegralExponentOf(e);
                if (n != 1)
                    e = ((Power)i).Left;

                // Convert to a polynomial.
                Polynomial Pi = Polynomial.New(e, x);

                // Add new terms for each multiplicity n.
                for (int j = 1; j <= n; ++j)
                {
                    // Expression for the unknown numerator of this term.
                    Expression unknown = 0;
                    for (int k = 0; k < Pi.Degree; ++k)
                    {
                        Variable Ai = Variable.New("_A" + unknowns.Count.ToString());
                        unknown += Ai * (x ^ k);
                        unknowns.Add(Ai);
                    }

                    terms.Add(Product.New(unknown, Power.New(e, -j)));
                }
                basis.Add(i);
            }

            // Equate the original expression with the decomposed expressions.
            D = Sum.New(terms.Select(j => (Expression)(D * j))).Expand();
            Polynomial l = Polynomial.New(N, x);
            Polynomial r = Polynomial.New(D, x);

            // Equate terms of equal degree and solve for the unknowns.
            int degree = Math.Max(l.Degree, r.Degree);
            List<Equal> eqs = new List<Equal>(degree + 1);
            for (int i = 0; i <= degree; ++i)
                eqs.Add(Equal.New(l[i], r[i]));
            List<Arrow> A = eqs.Solve(unknowns);

            // Substitute the now knowns.
            return Sum.New(terms.Select(i => i.Evaluate(A)));
        }