示例#1
0
        public void ArgumentOfNegativeAndEvenDegree_Calculate_ResultMustBeNonNegativeNumber()
        {
            var number = new PowerFunction(2);


            Assert.IsTrue(number.Calculate(-2.9).Eq(8.41));
        }
示例#2
0
        public void ArgumentIsZero_Calculate_ResultMustBeZero()
        {
            var number = new PowerFunction(4);


            Assert.Zero(number.Calculate(0));
        }
示例#3
0
        public void DegreeIsZero_Calculate_ResultMustBeZero()
        {
            var number = new PowerFunction(0);


            Assert.IsTrue(number.Calculate(2.2).Eq(1));
        }
示例#4
0
        public void DegreeIsNegative_ToString_ResultMustBeNumber()
        {
            var number = new PowerFunction(-2);


            Assert.AreEqual(number.ToString(), "x^-2");
        }
示例#5
0
        public void DegreeAndMultiplierOfValid_ToString_ResultMustBeNumber()
        {
            var number = new PowerFunction(5);


            Assert.AreEqual(number.GetDerivative().ToString(), "5x^4");
        }
示例#6
0
        public void DegreeIsNumber_GetDerivative_ResultMustBeNumber()
        {
            var number = new PowerFunction(3);


            Assert.AreEqual(number.GetDerivative().ToString(), "3x^2");
        }
示例#7
0
        public void DegreeOfNegative_GetDerivative_ResultMustBeNumber()
        {
            var number = new PowerFunction(-3);


            Assert.AreEqual(number.GetDerivative().ToString(), "-3x^-4");
        }
示例#8
0
        public void DegreeIsZeroMultiplierIsZero_ToString_ResultMustBeZero()
        {
            var number = new PowerFunction(0);


            Assert.AreEqual(number.ToString(), "0");
        }
示例#9
0
        public void DegreeIsZero_ToString_ResultMustBeNumber()
        {
            var number = new PowerFunction(1);


            Assert.AreEqual(number.GetDerivative().ToString(), "1");
        }
示例#10
0
        public void DegreeNegative_Calculate_ResultMustBeNumber()
        {
            var number = new PowerFunction(-1);


            Assert.IsTrue(number.Calculate(-2.9).Eq(-0.3448));
        }
示例#11
0
        public void ArgumentOfNegativeAndOddDegree_Calculate_ResultMustBeNegativeNumber()
        {
            var number = new PowerFunction(3);


            Assert.IsTrue(number.Calculate(-2.9).Eq(-24.389));
        }
示例#12
0
        private static void RecursivePowerFunction()
        {
            PowerFunction p   = new PowerFunction();
            int           num = 7;
            int           exp = -3;

            Console.WriteLine($"{num} ^ {exp} is {p.Power(num, exp)}.");
        }
示例#13
0
        public void PowerByOneTest()
        {
            GetConverter(out var varX, out _);
            var prog1 = new PowerFunction(varX, Constant.One);
            var prog2 = varX;
            var simp  = prog1.Simplify();

            Console.WriteLine($"{prog1}->{simp}, {prog2}");
            Assert.AreEqual(simp, prog2, $"{prog1} simplification ({simp}) should be equal to {prog2}");
        }
示例#14
0
        public void PowerFunction_Calculate_ResultMustBeNumber()
        {
            var powerFunction = new PowerFunction(3);
            var name          = "powerFunction";
            var storage       = new FunctionsStorage();


            storage.AddFunction(name, powerFunction);


            Assert.AreEqual(storage.CalculateFunction(name, 2.2), 10.648, 0.0001);
        }
示例#15
0
        public void ToTaylorExpansion_1()
        {
            var power = new PowerFunction {
                Aparam = 2, Bparam = 3, PowerNumerator = 3, PowerDenominator = 1
            };
            var expansion = power.ToTaylorExpansion(7).ToList();

            expansion.Should().HaveCount(4);

            expansion.Select(s => s.PolynomialDegree).Should().ContainInOrder(0, 1, 2, 3);
            expansion.Select(s => s.LittleODegree).Should().OnlyContain(x => x == 0);
            expansion.Select(s => s.Coefficient).Should().ContainInOrder(27.0, 54.0, 36.0, 8.0);
        }
示例#16
0
        public void ToTaylorExpansion_2()
        {
            var power = new PowerFunction {
                Aparam = 2, Bparam = 3, PowerNumerator = 1, PowerDenominator = 2
            };
            var expansion = power.ToTaylorExpansion(2).ToList();

            expansion.Should().HaveCount(4);

            expansion.Select(s => s.PolynomialDegree).Should().ContainInOrder(0, 1, 2, 0);
            expansion.Select(s => s.LittleODegree).Should().ContainInOrder(0, 0, 0, 2);
            expansion.Select(s => s.Coefficient).Should().ContainInOrder(Math.Pow(3, 0.5), Math.Pow(3, 0.5) * 1.0 / 3.0, Math.Pow(3, 0.5) * -1.0 / 18.0, 1.0);
        }
示例#17
0
        public ICommand BuildCommand(string input)
        {
            var regexForName       = new Regex(@"\w+");
            var regexForArguments  = new Regex(@"(-?\d+(,\d+)?)");
            var regForFunction     = new Regex(@"\w+\((-?\d+(,\d+)?)\)$");
            var regexForParameters = new Regex(@"\((-?\d+(,\d+)?)\)$");
            var function           = regForFunction.Match(input).ToString();
            var name          = regexForName.Match(function).ToString();
            var parameters    = regexForParameters.Match(function).ToString();
            var argument      = Convert.ToDouble(regexForArguments.Match(parameters).ToString());
            var powerFunction = new PowerFunction(argument);

            return(new AddFunctionCommand(name, powerFunction));
        }
示例#18
0
        public void ChainedMultiplicationsTest()
        {
            var converter  = GetConverter(out var varX, out _);
            var expression = "(x*x)";

            for (var i = 3; i <= 10; i++)
            {
                expression = $"({expression}*x)";
                var prog1 = converter.FromNormalNotation(expression);
                var prog2 = new PowerFunction(varX, new Constant(i));
                var simp  = prog1.Simplify();
                Console.WriteLine($"{prog1}->{simp}, {prog2}");
                Assert.AreEqual(simp, prog2, $"{prog1} simplification ({simp}) should be equal to {prog2}");
            }
        }
示例#19
0
        public void HashTestProgram()
        {
            var const1   = new Constant(0);
            var const2   = new Constant(1);
            var variable = new Variable("a");
            var sine     = new SineFunction(const2);
            var pow      = new PowerFunction(const1, variable);
            var subtr    = new SubtractionFunction(const2, pow);
            var min      = new MinFunction(subtr, const1);
            var div      = new DivisionFunction(pow, variable);
            var prog     = new IfFunction(div, min, subtr, sine);
            var hashCode = prog.GetHashCode();

            Console.WriteLine($"{prog}:{hashCode}");
            Assert.AreNotEqual(hashCode, 0, double.Epsilon, $"Hash code of {prog} should not be 0.");
        }
        private static ExComp GetIsSingleFunc(ExComp single, AlgebraComp dVar, ref EvalData pEvalData)
        {
            if (single is PowerFunction)
            {
                // Add one to the power and then divide by the power.
                PowerFunction pf = single as PowerFunction;

                if (pf.GetPower().IsEqualTo(ExNumber.GetNegOne()))
                {
                    ExComp pfBase = pf.GetBase();

                    if (pfBase is PowerFunction)
                    {
                        PowerFunction pfBasePf = pfBase as PowerFunction;
                        if (pfBasePf.GetPower().IsEqualTo(new ExNumber(0.5)) || pfBasePf.GetPower().IsEqualTo(AlgebraTerm.FromFraction(ExNumber.GetOne(), new ExNumber(2.0))))
                        {
                            // Is this arcsin or arccos?
                            ExComp compare = AddOp.StaticCombine(MulOp.Negate(PowOp.StaticCombine(dVar, new ExNumber(2.0))), ExNumber.GetOne()).ToAlgTerm().RemoveRedundancies(false);

                            ExComp useBase;
                            if (pfBasePf.GetBase() is AlgebraTerm)
                                useBase = (pfBasePf.GetBase() as AlgebraTerm).RemoveRedundancies(false);
                            else
                                useBase = pfBasePf.GetBase();

                            if (useBase.IsEqualTo(compare))
                            {
                                ASinFunction asin = new ASinFunction(dVar);
                                pEvalData.GetWorkMgr().FromFormatted(WorkMgr.STM + "\\int(\\frac{1}{sqrt{1-" + dVar.ToDispString() + "^2}})\\d" + dVar.ToDispString() +
                                    "=" + asin.FinalToDispStr() + WorkMgr.EDM, "Use the common antiderivative.");
                                return asin;
                            }
                        }

                        // See if it is just the regular (1/x^(1/2)) or something like that.
                        if (IsDerivAcceptable(pfBasePf, dVar) && !pfBasePf.GetPower().ToAlgTerm().Contains(dVar))
                        {
                            ExComp power = MulOp.Negate(pfBasePf.GetPower());
                            ExComp powChange = AddOp.StaticCombine(power, ExNumber.GetOne());
                            if (powChange is AlgebraTerm)
                                powChange = (powChange as AlgebraTerm).CompoundFractions();

                            pfBasePf.SetPower(powChange);
                            return DivOp.StaticCombine(pfBasePf, powChange);
                        }
                    }

                    if (pfBase.IsEqualTo(AddOp.StaticCombine(ExNumber.GetOne(), PowOp.StaticCombine(dVar, new ExNumber(2.0)))))
                    {
                        ATanFunction atan = new ATanFunction(dVar);
                        pEvalData.GetWorkMgr().FromFormatted(WorkMgr.STM + "\\int(\\frac{1}{" + dVar.ToDispString() + "^2+1})\\d" + dVar.ToDispString() +
                            "=" + atan.FinalToDispStr() + WorkMgr.EDM, "Use the common antiderivative.");
                        return atan;
                    }
                }

                if (pf.GetBase().IsEqualTo(Constant.GetE()) && pf.GetPower().IsEqualTo(dVar))
                {
                    pEvalData.GetWorkMgr().FromFormatted(WorkMgr.STM + "\\int(" + pf.FinalToDispStr() + ")\\d" + dVar.ToDispString() +
                        "=" + pf.FinalToDispStr() + WorkMgr.EDM, "Use the common antiderivative.");
                    return pf;
                }
                else if (!pf.GetBase().ToAlgTerm().Contains(dVar) && pf.GetPower().IsEqualTo(dVar))
                {
                    ExComp finalEx = DivOp.StaticWeakCombine(pf, LogFunction.Ln(pf.GetBase()));
                    pEvalData.GetWorkMgr().FromFormatted(WorkMgr.STM + "\\int(" + pf.FinalToDispStr() + ")\\d" + dVar.ToDispString() +
                        "=" + finalEx.ToAlgTerm().FinalToDispStr() + WorkMgr.EDM, "Use the common antiderivative law.");

                    return finalEx;
                }

                if (pf.GetBase() is TrigFunction && pf.GetPower() is ExNumber && (pf.GetPower() as ExNumber).IsRealInteger())
                {
                    int pow = (int)(pf.GetPower() as ExNumber).GetRealComp();
                    if (pow < 0)
                    {
                        // Convert to the reciprocal.
                        pf = new PowerFunction((pf.GetBase() as TrigFunction).GetReciprocalOf(), new ExNumber(-pow));
                    }
                }

                if (IsDerivAcceptable(pf, dVar) && !pf.GetPower().ToAlgTerm().Contains(dVar))
                {
                    // The special case for the power function anti-dervivative.
                    if (ExNumber.GetNegOne().IsEqualTo(pf.GetPower()))
                    {
                        pEvalData.GetWorkMgr().FromFormatted(WorkMgr.STM + "\\int(" + pf.FinalToDispStr() + ")\\d" + dVar.ToDispString() +
                            "=ln(|" + dVar + "|)" + WorkMgr.EDM, "This comes from the known derivative " + WorkMgr.STM +
                            "\\frac{d}{dx}ln(x)=\\frac{1}{x}" + WorkMgr.EDM);

                        // The absolute value function was removed here.
                        return LogFunction.Ln(dVar);
                    }

                    ExComp powChange = AddOp.StaticCombine(pf.GetPower(), ExNumber.GetOne());
                    if (powChange is AlgebraTerm)
                        powChange = (powChange as AlgebraTerm).CompoundFractions();

                    string changedPowStr = WorkMgr.ToDisp(AddOp.StaticWeakCombine(pf.GetPower(), ExNumber.GetOne()));
                    pEvalData.GetWorkMgr().FromFormatted(WorkMgr.STM + "\\int(" + WorkMgr.ToDisp(single) + ")\\d" + dVar.ToDispString() +
                        "=\\frac{" + dVar.ToDispString() + "^{" + changedPowStr + "}}{" + changedPowStr + "}" + WorkMgr.EDM,
                        "Use the power rule of antiderivatives.");

                    pf.SetPower(powChange);
                    return DivOp.StaticCombine(pf, powChange);
                }
                else if ((new ExNumber(2.0)).IsEqualTo(pf.GetPower()) && pf.GetBase() is TrigFunction && (pf.GetBase() as TrigFunction).GetInnerEx().IsEqualTo(dVar) &&
                    (pf.GetBase() is SecFunction || pf.GetBase() is CscFunction))
                {
                    ExComp ad = null;
                    if (pf.GetBase() is SecFunction)
                        ad = new TanFunction(dVar);
                    else if (pf.GetBase() is CscFunction)
                        ad = MulOp.Negate(new CotFunction(dVar));

                    if (ad != null)
                    {
                        pEvalData.GetWorkMgr().FromFormatted(WorkMgr.STM + "\\int(" + pf.FinalToDispStr() + ")\\d" + dVar.ToDispString() + "=" +
                            WorkMgr.ToDisp(ad) + WorkMgr.EDM, "Use the common antiderivative.");

                        return ad;
                    }
                }
                else if (pf.GetBase() is SinFunction && pf.GetPower() is ExNumber && (pf.GetPower() as ExNumber).IsRealInteger() &&
                    (int)((pf.GetPower() as ExNumber).GetRealComp()) > 1 && (int)((pf.GetPower() as ExNumber).GetRealComp()) % 2 == 0)
                {
                    int iPow = (int)(pf.GetPower() as ExNumber).GetRealComp();
                    SinFunction sf = pf.GetBase() as SinFunction;
                    ExComp subbed = MulOp.StaticCombine(
                        AlgebraTerm.FromFraction(ExNumber.GetOne(), new ExNumber(2.0)),
                        SubOp.StaticCombine(ExNumber.GetOne(), new CosFunction(MulOp.StaticCombine(new ExNumber(2.0), sf.GetInnerEx()))));

                    subbed = PowOp.StaticCombine(subbed, new ExNumber(iPow / 2));

                    pEvalData.GetWorkMgr().FromSides(pf, subbed,
                        "Use the trig identity " + WorkMgr.STM + "sin^{2}(x) = \\frac{1}{2}(1-cos(2x))" + WorkMgr.EDM);

                    return Integral.TakeAntiDeriv(subbed, dVar, ref pEvalData);
                }
                else if (pf.GetBase() is SinFunction && pf.GetPower() is ExNumber && (pf.GetPower() as ExNumber).IsRealInteger() &&
                    (int)((pf.GetPower() as ExNumber).GetRealComp()) > 1 && (int)((pf.GetPower() as ExNumber).GetRealComp()) % 2 != 0)
                {
                    int iPow = (int)(pf.GetPower() as ExNumber).GetRealComp();
                    SinFunction sf = pf.GetBase() as SinFunction;
                    ExComp finalEx = MulOp.StaticCombine(sf,
                        PowOp.StaticCombine(
                        SubOp.StaticCombine(
                        ExNumber.GetOne(),
                        PowOp.StaticCombine(new CosFunction(sf.GetInnerEx()), new ExNumber(2.0))),
                        new ExNumber((iPow - 1) / 2)));

                    pEvalData.GetWorkMgr().FromSides(pf, finalEx,
                        "Use the trig identity " + WorkMgr.STM + "sin^{2}(x) = \\frac{1}{2}(1-cos(2x))" + WorkMgr.EDM);

                    ExComp finalEval = Integral.TakeAntiDeriv(finalEx, dVar, ref pEvalData);
                    return finalEval;
                }
                else if (pf.GetBase() is CosFunction && pf.GetPower() is ExNumber && (pf.GetPower() as ExNumber).IsRealInteger() &&
                    (int)((pf.GetPower() as ExNumber).GetRealComp()) > 1 && (int)((pf.GetPower() as ExNumber).GetRealComp()) % 2 == 0)
                {
                    int iPow = (int)(pf.GetPower() as ExNumber).GetRealComp();
                    CosFunction cf = pf.GetBase() as CosFunction;
                    ExComp subbed = MulOp.StaticCombine(
                        AlgebraTerm.FromFraction(ExNumber.GetOne(), new ExNumber(2.0)),
                        AddOp.StaticCombine(ExNumber.GetOne(), new CosFunction(MulOp.StaticCombine(new ExNumber(2.0), cf.GetInnerEx()))));

                    subbed = PowOp.StaticCombine(subbed, new ExNumber(iPow / 2));

                    pEvalData.GetWorkMgr().FromSides(pf, subbed,
                        "Use the trig identity " + WorkMgr.STM + "cos^{2}(x) = \\frac{1}{2}(1+cos(2x))" + WorkMgr.EDM);

                    ExComp finalEval = Integral.TakeAntiDeriv(subbed, dVar, ref pEvalData);
                    return finalEval;
                }
                else if (pf.GetBase() is CosFunction && pf.GetPower() is ExNumber && (pf.GetPower() as ExNumber).IsRealInteger() &&
                    (int)((pf.GetPower() as ExNumber).GetRealComp()) > 1 && (int)((pf.GetPower() as ExNumber).GetRealComp()) % 2 != 0)
                {
                    int iPow = (int)(pf.GetPower() as ExNumber).GetRealComp();
                    CosFunction cf = pf.GetBase() as CosFunction;
                    ExComp finalEx = MulOp.StaticCombine(cf,
                        PowOp.StaticCombine(
                        SubOp.StaticCombine(
                        ExNumber.GetOne(),
                        PowOp.StaticCombine(new SinFunction(cf.GetInnerEx()), new ExNumber(2.0))),
                        new ExNumber((iPow - 1) / 2)));

                    pEvalData.GetWorkMgr().FromSides(pf, finalEx,
                        "Use the trig identity " + WorkMgr.STM + "cos^{2}(x) = \\frac{1}{2}(1+cos(2x))" + WorkMgr.EDM);

                    ExComp intEval = Integral.TakeAntiDeriv(finalEx, dVar, ref pEvalData);
                    return intEval;
                }
                else if (pf.GetBase() is CscFunction && pf.GetPower() is ExNumber && (pf.GetPower() as ExNumber).IsRealInteger() &&
                    (int)((pf.GetPower() as ExNumber).GetRealComp()) > 1 && (int)((pf.GetPower() as ExNumber).GetRealComp()) % 2 == 0)
                {
                    // In the form csc^n(x) where n is even.
                    int iPow = (int)(pf.GetPower() as ExNumber).GetRealComp();
                    CscFunction cf = pf.GetBase() as CscFunction;
                    ExComp finalEx = MulOp.StaticCombine(new PowerFunction(cf, new ExNumber(2.0)),
                        PowOp.StaticCombine(
                            AddOp.StaticCombine(
                                ExNumber.GetOne(),
                                new PowerFunction(new CotFunction(cf.GetInnerTerm()), new ExNumber(2.0))),
                            new ExNumber((iPow / 2) - 1)));

                    pEvalData.GetWorkMgr().FromSides(pf, finalEx,
                        "Use the trig identity " + WorkMgr.STM + "csc^2(x) = 1 + cot^2(x)" + WorkMgr.EDM);

                    ExComp intEval = Integral.TakeAntiDeriv(finalEx, dVar, ref pEvalData);
                    return intEval;
                }
                else if (pf.GetBase() is TanFunction && pf.GetPower() is ExNumber && (pf.GetPower() as ExNumber).IsRealInteger() &&
                    (int)((pf.GetPower() as ExNumber).GetRealComp()) > 1 && (int)((pf.GetPower() as ExNumber).GetRealComp()) % 2 == 0)
                {
                    // In the form tan^n where n is even.
                    int iPow = (int)(pf.GetPower() as ExNumber).GetRealComp();
                    if (iPow > 2)
                        return null;
                    TanFunction tf = pf.GetBase() as TanFunction;
                    ExComp finalEx = SubOp.StaticCombine(PowOp.StaticCombine(new SecFunction(tf.GetInnerTerm()), new ExNumber(2.0)), ExNumber.GetOne());

                    pEvalData.GetWorkMgr().FromSides(pf, finalEx,
                        "Use the trig identity " + WorkMgr.STM + "tan^2(x) = sec^2(x)-1" + WorkMgr.EDM);

                    ExComp intEval = Integral.TakeAntiDeriv(finalEx, dVar, ref pEvalData);
                    return intEval;
                }
                else if (pf.GetBase() is TanFunction && pf.GetPower() is ExNumber && (pf.GetPower() as ExNumber).IsRealInteger() &&
                    (int)((pf.GetPower() as ExNumber).GetRealComp()) > 1 && (int)((pf.GetPower() as ExNumber).GetRealComp()) % 2 != 0)
                {
                    // In the form tan^k where k is odd.
                    int iPow = (int)(pf.GetPower() as ExNumber).GetRealComp();
                    TanFunction tf = pf.GetBase() as TanFunction;

                    ExComp finalEx = PowOp.StaticCombine(
                        SubOp.StaticCombine(PowOp.StaticCombine(new SecFunction(tf.GetInnerTerm()), new ExNumber(2.0)), ExNumber.GetOne()),
                        new ExNumber((iPow - 1) / 2));

                    pEvalData.GetWorkMgr().FromSides(pf, finalEx,
                        "Use the trig identity " + WorkMgr.STM + "tan^2(x) = sec^2(x)-1" + WorkMgr.EDM);

                    ExComp intEval = Integral.TakeAntiDeriv(finalEx, dVar, ref pEvalData);
                    return intEval;
                }
            }
            else if (single is TrigFunction)
            {
                if (!IsDerivAcceptable(single, dVar))
                    return null;

                ExComp ad = null;
                if (single is SinFunction)
                {
                    ad = MulOp.Negate(new CosFunction(dVar));
                }
                else if (single is CosFunction)
                {
                    ad = new SinFunction(dVar);
                }
                else if (single is TanFunction)
                {
                    ad = LogFunction.Ln(new SecFunction(dVar));
                }
                else if (single is CscFunction)
                {
                    ad = LogFunction.Ln(SubOp.StaticCombine(new CscFunction(dVar), new CotFunction(dVar)));
                }
                else if (single is SecFunction)
                {
                    ad = LogFunction.Ln(SubOp.StaticCombine(new SecFunction(dVar), new TanFunction(dVar)));
                }
                else if (single is CotFunction)
                {
                    ad = LogFunction.Ln(new SinFunction(dVar));
                }

                if (ad == null)
                    return null;

                pEvalData.GetWorkMgr().FromFormatted(WorkMgr.STM + "\\int(" + (single as TrigFunction).FinalToDispStr() + ")\\d" + dVar.ToDispString() + "=" + WorkMgr.ToDisp(ad) +
                    WorkMgr.EDM,
                    "Use the common antiderivative.");

                return ad;
            }

            return null;
        }
        private static ExComp TryU(ExComp[] group, ExComp uatmpt, AlgebraComp dVar, ref IntegrationInfo pIntInfo, ref EvalData pEvalData)
        {
            string groupStr = GroupHelper.ToAlgTerm(GroupHelper.CloneGroup(group)).FinalToDispStr();
            string thisStr = "\\int(" + groupStr + ")" + dVar.ToDispString();
            string atmptStr = uatmpt.ToAlgTerm().FinalToDispStr();

            pEvalData.GetWorkMgr().FromFormatted(WorkMgr.STM + "\\int (" + groupStr + ") \\d" + dVar.ToDispString() + WorkMgr.EDM,
                "Use u-substitution.");

            AlgebraTerm term = GroupHelper.ToAlgNoRedunTerm(group);
            AlgebraComp subInVar;
            if (term.Contains(new AlgebraComp("u")))
            {
                if (term.Contains(new AlgebraComp("w")))
                    subInVar = new AlgebraComp("v");
                else
                    subInVar = new AlgebraComp("w");
            }
            else
                subInVar = new AlgebraComp("u");

            bool success = false;

            term = term.Substitute(uatmpt, subInVar, ref success);
            if (!success)
                return null;
            List<ExComp[]> updatedGroups = term.GetGroupsNoOps();
            // The group count started as one and should not have been altered by substitutions.
            if (updatedGroups.Count != 1)
                return null;

            Derivative derivative = Derivative.ConstructDeriv(uatmpt, dVar, null);

            pEvalData.GetWorkMgr().FromFormatted(WorkMgr.STM + thisStr + WorkMgr.EDM,
                "Substitute " + WorkMgr.STM + subInVar.ToDispString() + "=" + uatmpt.ToAlgTerm().FinalToDispStr() + WorkMgr.EDM);

            pEvalData.GetWorkMgr().FromFormatted("",
                "Find " + WorkMgr.STM + "d" + subInVar.ToDispString() + WorkMgr.EDM);
            WorkStep last = pEvalData.GetWorkMgr().GetLast();

            last.GoDown(ref pEvalData);
            ExComp evaluated = derivative.Evaluate(false, ref pEvalData);
            last.GoUp(ref pEvalData);

            if (evaluated is Derivative)
                return null;

            last.SetWorkHtml(WorkMgr.STM + "\\frac{d}{d" + dVar.ToDispString() + "}[" + atmptStr + "]=" + WorkMgr.ToDisp(evaluated) + WorkMgr.EDM);

            group = updatedGroups[0];

            List<ExComp[]> groups = evaluated.ToAlgTerm().GetGroupsNoOps();
            ExComp constEx = null;

            if (groups.Count == 1)
            {
                ExComp[] singularGp = groups[0];
                ExComp[] varTo, constTo;
                GroupHelper.GetConstVarTo(singularGp, out varTo, out constTo, dVar);

                constEx = constTo.Length == 0 ? ExNumber.GetOne() : (ExComp)AlgebraTerm.FromFraction(ExNumber.GetOne(), GroupHelper.ToAlgTerm(constTo));

                if (varTo.Length == 0)
                {
                    if (GroupHelper.GroupContains(group, dVar))
                        return null;

                    pEvalData.GetWorkMgr().GetWorkSteps().Add(new WorkStep(WorkMgr.STM + thisStr +
                                                                           WorkMgr.EDM, "Make the substitution " + WorkMgr.STM + subInVar.ToDispString() + "=" +
                                                                                        atmptStr + WorkMgr.EDM + " and " + WorkMgr.STM + "d" + subInVar.ToDispString() + "=" +
                                                                                        evaluated.ToAlgTerm().FinalToDispStr() + WorkMgr.EDM, true));

                    pEvalData.GetWorkMgr().FromFormatted(WorkMgr.STM + constEx.ToAlgTerm().FinalToDispStr() + "\\int (" + GroupHelper.ToAlgTerm(group.ToArray()).FinalToDispStr() + ") d" + subInVar.ToDispString() + WorkMgr.EDM);

                    ExComp innerAntiDeriv = TakeAntiDerivativeGp(group, subInVar, ref pIntInfo, ref pEvalData, "", "");
                    if (innerAntiDeriv == null)
                        return null;

                    pEvalData.GetWorkMgr().FromSides(MulOp.StaticWeakCombine(constEx, innerAntiDeriv), null, "Substitute back in " + WorkMgr.STM + subInVar.ToDispString() + "=" +
                        atmptStr + WorkMgr.EDM);

                    // Sub back in the appropriate values.
                    innerAntiDeriv = innerAntiDeriv.ToAlgTerm().Substitute(subInVar, uatmpt);

                    ExComp retEx = MulOp.StaticCombine(innerAntiDeriv, constEx);
                    pEvalData.GetWorkMgr().FromSides(retEx, null);
                    return retEx;
                }

                evaluated = GroupHelper.ToAlgTerm(varTo).RemoveRedundancies(false);
            }
            else
            {
                ExComp[] groupGcf = evaluated.ToAlgTerm().GetGroupGCF();
                ExComp[] varTo, constTo;
                GroupHelper.GetConstVarTo(groupGcf, out varTo, out constTo, dVar);

                AlgebraTerm constToAg = GroupHelper.ToAlgTerm(constTo);
                evaluated = DivOp.StaticCombine(evaluated, constToAg.CloneEx());
                constEx = AlgebraTerm.FromFraction(ExNumber.GetOne(), constToAg);
            }

            for (int j = 0; j < group.Length; ++j)
            {
                if (group[j].IsEqualTo(evaluated))
                {
                    List<ExComp> groupList = ArrayFunc.ToList(group);
                    ArrayFunc.RemoveIndex(groupList, j);

                    pEvalData.GetWorkMgr().GetWorkSteps().Add(new WorkStep(WorkMgr.STM + thisStr +
                                                                           WorkMgr.EDM, "Make the substitution " + WorkMgr.STM + subInVar.ToDispString() + "=" +
                                                                                        atmptStr + WorkMgr.EDM + " and " + WorkMgr.STM + "d" + subInVar.ToDispString() + "=" +
                                                                                        evaluated.ToAlgTerm().FinalToDispStr() + WorkMgr.EDM, false));

                    bool mulInCost = constEx != null && !ExNumber.GetOne().IsEqualTo(constEx);
                    string mulInCostStr = (mulInCost ? constEx.ToAlgTerm().FinalToDispStr() : "");

                    group = groupList.ToArray();

                    if (GroupHelper.GroupContains(group, dVar))
                        return null;

                    pEvalData.GetWorkMgr().FromFormatted(WorkMgr.STM + mulInCostStr +
                        "\\int (" + GroupHelper.ToAlgTerm(group).FinalToDispStr() + ") d" + subInVar.ToDispString() + WorkMgr.EDM);

                    ExComp innerAntiDeriv = TakeAntiDerivativeGp(group, subInVar, ref pIntInfo, ref pEvalData, "", "");
                    if (innerAntiDeriv == null)
                        return null;

                    pEvalData.GetWorkMgr().FromFormatted(WorkMgr.STM + mulInCostStr + "(" + innerAntiDeriv.ToAlgTerm().FinalToDispStr() + ")" + WorkMgr.EDM, "Substitute back in " + WorkMgr.STM + subInVar.ToDispString() + "=" +
                                    uatmpt.ToAlgTerm().FinalToDispStr() + WorkMgr.EDM);

                    // Sub back in the appropriate values.
                    innerAntiDeriv = innerAntiDeriv.ToAlgTerm().Substitute(subInVar, uatmpt);

                    ExComp retEx;

                    if (mulInCost)
                        retEx = MulOp.StaticCombine(constEx, innerAntiDeriv);
                    else
                        retEx = innerAntiDeriv;

                    pEvalData.GetWorkMgr().FromSides(retEx, null);
                    return retEx;
                }
                else if (group[j] is PowerFunction && evaluated is PowerFunction && (group[j] as PowerFunction).GetPower().IsEqualTo((evaluated as PowerFunction).GetPower()))
                {
                    PowerFunction groupPf = group[j] as PowerFunction;
                    PowerFunction evaluatedPf = evaluated as PowerFunction;

                    List<ExComp[]> baseGps = groupPf.GetBase().ToAlgTerm().GetGroupsNoOps();
                    if (baseGps.Count == 1)
                    {
                        // Search the base for like terms.
                        for (int k = 0; k < baseGps[0].Length; ++k)
                        {
                            if (baseGps[0][k].IsEqualTo(evaluatedPf.GetBase()))
                            {
                                List<ExComp> baseGpsList = ArrayFunc.ToList(baseGps[0]);
                                ArrayFunc.RemoveIndex(baseGpsList, k);

                                group[j] = new PowerFunction(GroupHelper.ToAlgTerm(baseGpsList.ToArray()), evaluatedPf.GetPower());

                                pEvalData.GetWorkMgr().GetWorkSteps().Add(new WorkStep(WorkMgr.STM + thisStr +
                                                                                       WorkMgr.EDM, "Make the substitution " + WorkMgr.STM + subInVar.ToDispString() + "=" +
                                                                                                    atmptStr + WorkMgr.EDM + " and " + WorkMgr.STM + "d" + subInVar.ToDispString() + "=" +
                                                                                                    evaluated.ToAlgTerm().FinalToDispStr() + WorkMgr.EDM, false));

                                bool mulInCost = constEx != null && !ExNumber.GetOne().IsEqualTo(constEx);
                                string mulInCostStr = (mulInCost ? constEx.ToAlgTerm().FinalToDispStr() : "");

                                pEvalData.GetWorkMgr().FromFormatted(WorkMgr.STM + mulInCostStr +
                                    "\\int (" + GroupHelper.ToAlgTerm(group).FinalToDispStr() + ") d" + subInVar.ToDispString() + WorkMgr.EDM);

                                ExComp innerAntiDeriv = TakeAntiDerivativeGp(@group, subInVar, ref pIntInfo, ref pEvalData, "", "");
                                if (innerAntiDeriv == null)
                                    return null;

                                pEvalData.GetWorkMgr().FromFormatted(WorkMgr.STM + mulInCostStr + "(" + innerAntiDeriv.ToAlgTerm().FinalToDispStr() + ")" + WorkMgr.EDM, "Substitute back in " + WorkMgr.STM + subInVar.ToDispString() + "=" +
                                    uatmpt.ToAlgTerm().FinalToDispStr() + WorkMgr.EDM);

                                // Sub back in the appropriate values.
                                innerAntiDeriv = innerAntiDeriv.ToAlgTerm().Substitute(subInVar, uatmpt);

                                ExComp retEx;

                                if (mulInCost)
                                    retEx = MulOp.StaticCombine(constEx, innerAntiDeriv);
                                else
                                    retEx = innerAntiDeriv;

                                pEvalData.GetWorkMgr().FromSides(retEx, null);
                                return retEx;
                            }
                        }
                    }
                }
            }

            return null;
        }
        /// <summary>
        /// Tries to create an Leviathan Function expression if the function Uri correseponds to a supported Leviathan Function
        /// </summary>
        /// <param name="u">Function Uri</param>
        /// <param name="args">Function Arguments</param>
        /// <param name="scalarArgs">Scalar Arguments</param>
        /// <param name="expr">Generated Expression</param>
        /// <returns>Whether an expression was successfully generated</returns>
        public bool TryCreateExpression(Uri u, List <ISparqlExpression> args, Dictionary <String, ISparqlExpression> scalarArgs, out ISparqlExpression expr)
        {
            // If any Scalar Arguments are present then can't possibly be a Leviathan Function
            if (scalarArgs.Count > 0)
            {
                expr = null;
                return(false);
            }

            String func = u.ToString();

            if (func.StartsWith(LeviathanFunctionsNamespace))
            {
                func = func.Substring(LeviathanFunctionsNamespace.Length);
                ISparqlExpression lvnFunc = null;

                switch (func)
                {
                case All:
                    if (args.Count == 1)
                    {
                        lvnFunc = new AggregateTerm(new AllAggregate(args.First()));
                    }
                    else if (args.Count == 2 && args.First() is DistinctModifier)
                    {
                        lvnFunc = new AggregateTerm(new AllAggregate(args.Last(), true));
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for Leviathan all() aggregate");
                    }
                    break;

                case Any:
                    if (args.Count == 1)
                    {
                        lvnFunc = new AggregateTerm(new AnyAggregate(args.First()));
                    }
                    else if (args.Count == 2 && args.First() is DistinctModifier)
                    {
                        lvnFunc = new AggregateTerm(new AnyAggregate(args.Last(), true));
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for Leviathan any() aggregate");
                    }
                    break;

                case Cartesian:
                    if (args.Count == 4)
                    {
                        lvnFunc = new CartesianFunction(args[0], args[1], args[2], args[3]);
                    }
                    else if (args.Count == 6)
                    {
                        lvnFunc = new CartesianFunction(args[0], args[1], args[2], args[3], args[4], args[5]);
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for Leviathan cartesian() function");
                    }
                    break;

                case Cube:
                    if (args.Count == 1)
                    {
                        lvnFunc = new CubeFunction(args.First());
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for the Leviathan cube() function");
                    }
                    break;

                case DegreesToRadians:
                    if (args.Count == 1)
                    {
                        lvnFunc = new DegreesToRadiansFunction(args.First());
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for the Leviathan degrees-to-radians() function");
                    }
                    break;

                case E:
                    if (args.Count == 1)
                    {
                        lvnFunc = new EFunction(args.First());
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for the Leviathan e() function");
                    }
                    break;

                case Factorial:
                    if (args.Count == 1)
                    {
                        lvnFunc = new FactorialFunction(args.First());
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for the Leviathan factorial() function");
                    }
                    break;

                case Ln:
                    if (args.Count == 1)
                    {
                        lvnFunc = new LeviathanNaturalLogFunction(args.First());
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for the Leviathan ln() function");
                    }
                    break;

                case Log:
                    if (args.Count == 1)
                    {
                        lvnFunc = new LogFunction(args.First());
                    }
                    else if (args.Count == 2)
                    {
                        lvnFunc = new LogFunction(args.First(), args.Last());
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for the Leviathan log() function");
                    }
                    break;

                case MD5Hash:
                    if (args.Count == 1)
                    {
                        lvnFunc = new MD5HashFunction(args.First());
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for the Leviathan md5hash() function");
                    }
                    break;

                case Median:
                    if (args.Count == 1)
                    {
                        lvnFunc = new AggregateTerm(new MedianAggregate(args.First()));
                    }
                    else if (args.Count == 2 && args.First() is DistinctModifier)
                    {
                        lvnFunc = new AggregateTerm(new MedianAggregate(args.Last(), true));
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for the Leviathan median() aggregate");
                    }
                    break;

                case Mode:
                    if (args.Count == 1)
                    {
                        lvnFunc = new AggregateTerm(new ModeAggregate(args.First()));
                    }
                    else if (args.Count == 2 && args.First() is DistinctModifier)
                    {
                        lvnFunc = new AggregateTerm(new ModeAggregate(args.Last(), true));
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for the Leviathan mode() aggregate");
                    }
                    break;

                case None:
                    if (args.Count == 1)
                    {
                        lvnFunc = new AggregateTerm(new NoneAggregate(args.First()));
                    }
                    else if (args.Count == 2 && args.First() is DistinctModifier)
                    {
                        lvnFunc = new AggregateTerm(new NoneAggregate(args.Last(), true));
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for the Leviathan none() aggregate");
                    }
                    break;

                case NumericMax:
                    if (args.Count == 1)
                    {
                        lvnFunc = new AggregateTerm(new NumericMaxAggregate(args.First()));
                    }
                    else if (args.Count == 2 && args.First() is DistinctModifier)
                    {
                        lvnFunc = new AggregateTerm(new NumericMaxAggregate(args.Last(), true));
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for the Leviathan nmax() aggregate");
                    }
                    break;

                case NumericMin:
                    if (args.Count == 1)
                    {
                        lvnFunc = new AggregateTerm(new NumericMinAggregate(args.First()));
                    }
                    else if (args.Count == 2 && args.First() is DistinctModifier)
                    {
                        lvnFunc = new AggregateTerm(new NumericMinAggregate(args.Last(), true));
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for the Leviathan nmin() aggregate");
                    }
                    break;

                case Power:
                    if (args.Count == 1)
                    {
                        lvnFunc = new SquareFunction(args.First());
                    }
                    else if (args.Count == 2)
                    {
                        lvnFunc = new PowerFunction(args.First(), args.Last());
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for the Leviathan pow() function");
                    }
                    break;

                case Pythagoras:
                    if (args.Count == 2)
                    {
                        lvnFunc = new PythagoreanDistanceFunction(args.First(), args.Last());
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for the Leviathan pythagoras() function");
                    }
                    break;

                case RadiansToDegrees:
                    if (args.Count == 1)
                    {
                        lvnFunc = new RadiansToDegreesFunction(args.First());
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for the Leviathan radians-to-degrees() function");
                    }
                    break;

                case Random:
                    if (args.Count == 0)
                    {
                        lvnFunc = new RandomFunction();
                    }
                    else if (args.Count == 1)
                    {
                        lvnFunc = new RandomFunction(args.First());
                    }
                    else if (args.Count == 2)
                    {
                        lvnFunc = new RandomFunction(args.First(), args.Last());
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for the Leviathan rnd() function");
                    }
                    break;

                case Reciprocal:
                    if (args.Count == 1)
                    {
                        lvnFunc = new ReciprocalFunction(args.First());
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for the Leviathan reciprocal() function");
                    }
                    break;

                case Root:
                    if (args.Count == 1)
                    {
                        lvnFunc = new SquareRootFunction(args.First());
                    }
                    else if (args.Count == 2)
                    {
                        lvnFunc = new RootFunction(args.First(), args.Last());
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for the Leviathan root() function");
                    }
                    break;

                case Sha256Hash:
                    if (args.Count == 1)
                    {
                        lvnFunc = new Sha256HashFunction(args.First());
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for the Leviathan sha256hash() function");
                    }
                    break;

                case Square:
                    if (args.Count == 1)
                    {
                        lvnFunc = new SquareFunction(args.First());
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for the Leviathan sq() function");
                    }
                    break;

                case SquareRoot:
                    if (args.Count == 1)
                    {
                        lvnFunc = new SquareRootFunction(args.First());
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for the Leviathan sqrt() function");
                    }
                    break;

                case Ten:
                    if (args.Count == 1)
                    {
                        lvnFunc = new TenFunction(args.First());
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for the Leviathan ten() function");
                    }
                    break;

                case TrigCos:
                case TrigCosInv:
                    if (args.Count == 1)
                    {
                        lvnFunc = new CosineFunction(args.First(), func.Equals(TrigCosInv));
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for the Leviathan " + func + "() function");
                    }
                    break;

                case TrigCosec:
                case TrigCosecInv:
                    if (args.Count == 1)
                    {
                        lvnFunc = new CosecantFunction(args.First(), func.Equals(TrigCosecInv));
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for the Leviathan " + func + "() function");
                    }
                    break;

                case TrigCotan:
                case TrigCotanInv:
                    if (args.Count == 1)
                    {
                        lvnFunc = new CotangentFunction(args.First(), func.Equals(TrigCotanInv));
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for the Leviathan " + func + "() function");
                    }
                    break;

                case TrigSec:
                case TrigSecInv:
                    if (args.Count == 1)
                    {
                        lvnFunc = new SecantFunction(args.First(), func.Equals(TrigSecInv));
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for the Leviathan " + func + "() function");
                    }
                    break;

                case TrigSin:
                case TrigSinInv:
                    if (args.Count == 1)
                    {
                        lvnFunc = new SineFunction(args.First(), func.Equals(TrigSinInv));
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for the Leviathan " + func + "() function");
                    }
                    break;

                case TrigTan:
                case TrigTanInv:
                    if (args.Count == 1)
                    {
                        lvnFunc = new TangentFunction(args.First(), func.Equals(TrigTanInv));
                    }
                    else
                    {
                        throw new RdfParseException("Incorrect number of arguments for the Leviathan " + func + "() function");
                    }
                    break;
                }

                if (lvnFunc != null)
                {
                    expr = lvnFunc;
                    return(true);
                }
            }
            expr = null;
            return(false);
        }
示例#23
0
        public static IElementaryFunction ConvertToElementaryFunction(string str)
        {
            IElementaryFunction function = null;

            double[] arr = null;


            if (str.Contains("sin"))
            {
                function        = new Sine();
                arr             = FindParameters(str.Substring(4, str.Count() - 4));
                function.Aparam = arr[0];
                function.Bparam = arr[1];
            }
            else if (str.Contains("cos"))
            {
                function        = new Cosine();
                arr             = FindParameters(str.Substring(4, str.Count() - 4));
                function.Aparam = arr[0];
                function.Bparam = arr[1];
            }
            else if (str.Contains("ln"))
            {
                function        = new LogarithmicFunction();
                arr             = FindParameters(str.Substring(3, str.Count() - 3));
                function.Aparam = arr[0];
                function.Bparam = arr[1];
            }
            else if (str.Contains("e^"))
            {
                function        = new ExponentialFunction();
                arr             = FindParameters(str.Substring(3, str.Count() - 3));
                function.Aparam = arr[0];
                function.Bparam = arr[1];
            }
            else if (str.Contains(")^(") || str.Contains("x^(") || str.Contains(")^"))
            {
                function = new PowerFunction();


                int powerPosition = 0;

                for (int i = 0; i < str.Count(); i++)
                {
                    if (str[i] == '^')
                    {
                        powerPosition = i;
                        StringBuilder num   = new StringBuilder();
                        StringBuilder den   = new StringBuilder();
                        bool          slash = false;
                        for (int j = i + 1; j < str.Count(); j++)
                        {
                            if (str[j] != '/' && str[j] != '(' && str[j] != ')')
                            {
                                if (slash == false)
                                {
                                    num.Append(str[j]);
                                }
                                else
                                {
                                    den.Append(str[j]);
                                }
                            }
                            else if (str[j] == '/')
                            {
                                slash = true;
                            }
                        }

                        if (slash == false)
                        {
                            ((PowerFunction)function).PowerDenominator = 1;
                        }
                        else
                        {
                            ((PowerFunction)function).PowerDenominator = int.Parse(den.ToString());
                        }

                        ((PowerFunction)function).PowerNumerator = int.Parse(num.ToString());
                    }
                }

                int beginPosition = 0;

                if (str[0] == '(')
                {
                    beginPosition = 1;
                }

                arr             = FindParameters(str.Substring(beginPosition, powerPosition - beginPosition));
                function.Aparam = arr[0];
                function.Bparam = arr[1];
            }

            return(function);
        }
 public string ToSQL(PowerFunction funcExp)
 {
     return(_FunctionToSQL(funcExp, "POW"));
 }
        public object Evaluate(PowerFunction funcExp, object data, IEnumerable <object> parameters = null)
        {
            var paramValues = _GetParameterValues(funcExp, data, parameters);

            return((object)Math.Pow(Convert.ToDouble(paramValues[0]), Convert.ToDouble(paramValues[1])));
        }