public void TestPatt2() { var y = MathS.Var("y"); var expr = (MathS.Sqr(MathS.Sin(x + 2 * y)) + MathS.Sqr(MathS.Cos(x + 2 * y))) / (2 * MathS.Sin(x - y) * MathS.Cos(x - y) + 1); Assert.IsTrue(expr.Simplify() == 1 / (MathS.Sin(2 * (x - y)) + 1)); }
public void Setup() { exprEasy = x + MathS.Sqr(x) - 3; exprMedium = MathS.Sin(x + MathS.Cos(x)) + MathS.Sqrt(x + MathS.Sqr(x)); exprHard = MathS.Sin(x + MathS.Arcsin(x)) / (MathS.Sqr(x) + MathS.Cos(x)) * MathS.Arccos(x / 1200 + 0.00032 / MathS.Cotan(x + 43)); exprSolvable = MathS.FromString("3arccos(2x + a)3 + 6arccos(2x + a)2 - a3 + 3"); }
/// <summary> /// 根据旋转轴和旋转角生成单位四元数 /// </summary> /// <param name="angle"></param> /// <param name="axisNormal"></param> /// <returns>单位四元数</returns> public static Quaternion AngleAxis(float angle, Vector3 axisNormal) { float radian = MathS.DegToRad * angle * 0.5f; float real = MathS.Cos(radian); Vector3 imag = MathS.Sin(radian) * axisNormal; return(new Quaternion(imag.x, imag.y, imag.z, real)); }
public void TestCosCustom() { var func = MathS.Cos(MathS.Pow(x, 3)); var expected = -3 * MathS.Sin(MathS.Pow(x, 3)) * MathS.Sqr(x); var actual = func.Derive(x).Simplify(); AssertEqEntity(expected.ToString(), actual.ToString()); }
public void TestCosCustom() { var func = MathS.Cos(MathS.Pow(x, 3)); var expected = -3 * MathS.Sin(MathS.Pow(x, 3)) * MathS.Sqr(x); var actual = func.Differentiate(x).Simplify(); Assert.Equal(expected, actual); }
public CacheCompiledFunc() { notCompiled = MathS.Sin(MathS.Sqr(x)) + MathS.Cos(MathS.Sqr(x)) + MathS.Sqr(x) + MathS.Sin(MathS.Sqr(x)); complexFunc = notCompiled.Compile(x); Expression <Func <Complex, Complex> > linqExpr = x => Complex.Sin(Complex.Pow(x, 2)) + Complex.Cos(Complex.Pow(x, 2)) + Complex.Pow(x, 2) + Complex.Sin(Complex.Pow(x, 2)); linqComp = linqExpr.Compile(); }
private void EveryFrame(object sender, EventArgs e) { var B = MathS.Var("B"); var expr2 = B * MathS.Sin(t + B) * MathS.Pow(MathS.e, MathS.i * B * MathS.Cos(t)); var niceFunc2 = expr2.Compile(B); plotter.Clear(); plotter.PlotIterativeComplex(niceFunc2, 0, t); plotter.Render(); t += 0.0005m; }
public SubsTest() { IterCount = 10000; tests = new List <Func <object> > { () => (x * MathS.Sin(x)).Substitute(x, 3).Eval(), () => (MathS.Cos(x) * MathS.Sin(x)).Substitute(x, 3).Eval(), () => (MathS.Sqr(MathS.Sin(x + 2 * x)) + MathS.Sqr(MathS.Cos(x + 2 * x))).Substitute(x, 3).Eval(), () => (x * MathS.Cos(x) / MathS.Sin(MathS.Sqrt(x / MathS.Ln(x))) * x * MathS.Cos(x) / MathS.Sin(MathS.Sqrt(x / MathS.Ln(x))) * x * MathS.Cos(x) / MathS.Sin(MathS.Sqrt(x / MathS.Ln(x))) * x * MathS.Cos(x) / MathS.Sin(MathS.Sqrt(x / MathS.Ln(x)))).Substitute(x, 3).Eval() }; }
public SimplificationTest() { IterCount = 1500; tests = new List <Func <object> > { () => (x * MathS.Sin(x)).Simplify(), () => (MathS.Cos(x) * MathS.Sin(x)).Simplify(), () => (MathS.Sqr(MathS.Sin(x + 2 * y)) + MathS.Sqr(MathS.Cos(x + 2 * y))).Simplify(), () => (x * MathS.Cos(x) / MathS.Sin(MathS.Sqrt(x / MathS.Ln(x))) * x * MathS.Cos(x) / MathS.Sin(MathS.Sqrt(x / MathS.Ln(x))) * x * MathS.Cos(x) / MathS.Sin(MathS.Sqrt(x / MathS.Ln(x))) * x * MathS.Cos(x) / MathS.Sin(MathS.Sqrt(x / MathS.Ln(x)))).Simplify() }; }
public DerivationTest() { IterCount = 10000; tests = new List <Func <object> > { () => x.Derive(x), () => (MathS.Cos(x) * MathS.Sin(x)).Derive(x), () => (MathS.Sqr(MathS.Sin(x + 2 * y)) + MathS.Sqr(MathS.Cos(x + 2 * y))).Derive(x), () => (x * MathS.Cos(x) / MathS.Sin(MathS.Sqrt(x / MathS.Ln(x))) * x * MathS.Cos(x) / MathS.Sin(MathS.Sqrt(x / MathS.Ln(x))) * x * MathS.Cos(x) / MathS.Sin(MathS.Sqrt(x / MathS.Ln(x))) * x * MathS.Cos(x) / MathS.Sin(MathS.Sqrt(x / MathS.Ln(x)))).Derive(x) }; }
public void TestSin() { var func = MathS.Sin(x); AssertEqEntity(func.Derive(x).Simplify(), MathS.Cos(x)); }
public void Test2() { var func = (MathS.Sin(x) + MathS.Cos(x)).Compile(x); Assert.IsTrue(func.Substitute(0) == 1); }
[TestMethod] public void Trig() => TestSimplify(@"\sin\left(\cos\left(\tan\left(\cot\left(x\right)\right)\right)\right)", MathS.Sin(MathS.Cos(MathS.Tan(MathS.Cotan(x)))));
public void Test4() { MathS.FromString((MathS.Sin(x) / MathS.Cos(x)).Derive(x).ToString()); }
/// <summary> /// Returns a set of possible roots of a function, e. g. /// sin(x) = a => /// x = arcsin(a) + 2 pi n /// x = pi - arcsin(a) + 2 pi n /// </summary> /// <param name="func"></param> /// <param name="value"></param> /// <param name="x"></param> /// <returns></returns> public static Set InvertFunctionEntity(FunctionEntity func, Entity value, Entity x) { Entity a = func.Children[0]; Entity b = func.Children.Count == 2 ? func.Children[1] : null; int arg = func.Children.Count == 2 && func.Children[1].FindSubtree(x) != null ? 1 : 0; var n = Utils.FindNextIndex(func + value, "n"); var res = new Set(); var pi = MathS.pi; Set GetNotNullEntites(Set set) { return(set.FiniteWhere(el => el.entType != Entity.EntType.NUMBER || el.GetValue().IsDefinite())); } switch (func.Name) { // Consider case when sin(sin(x)) where double-mention of n occures case "sinf": { // sin(x) = value => x = arcsin(value) + 2pi * n res.AddRange(GetNotNullEntites(FindInvertExpression(a, MathS.Arcsin(value) + 2 * pi * n, x))); // sin(x) = value => x = pi - arcsin(value) + 2pi * n res.AddRange(GetNotNullEntites(FindInvertExpression(a, pi - MathS.Arcsin(value) + 2 * pi * n, x))); return(res); } case "cosf": { // cos(x) = value => x = arccos(value) + 2pi * n res.AddRange(GetNotNullEntites(FindInvertExpression(a, MathS.Arccos(value) + 2 * pi * n, x))); // cos(x) = value => x = -arccos(value) + 2pi * n res.AddRange(GetNotNullEntites(FindInvertExpression(a, -MathS.Arccos(value) - 2 * pi * n, x))); return(res); } case "tanf": { var inverted = FindInvertExpression(a, MathS.Arctan(value) + pi * n, x); // tan(x) = value => x = arctan(value) + pi * n res.AddRange(GetNotNullEntites(inverted)); return(res); } case "cotanf": { var inverted = FindInvertExpression(a, MathS.Arccotan(value) + pi * n, x); // cotan(x) = value => x = arccotan(value) res.AddRange(GetNotNullEntites(inverted)); return(res); } case "arcsinf": // arcsin(x) = value => x = sin(value) if (EntityInBounds(value, ArcsinFrom, ArcsinTo)) { return(GetNotNullEntites(FindInvertExpression(a, MathS.Sin(value), x))); } else { return(Empty); } case "arccosf": // arccos(x) = value => x = cos(value) if (EntityInBounds(value, ArccosFrom, ArccosTo)) { return(GetNotNullEntites(FindInvertExpression(a, MathS.Cos(value), x))); } else { return(Empty); } case "arctanf": // arctan(x) = value => x = tan(value) return(GetNotNullEntites(FindInvertExpression(a, MathS.Tan(value), x))); case "arccotanf": // arccotan(x) = value => x = cotan(value) return(GetNotNullEntites(FindInvertExpression(a, MathS.Cotan(value), x))); case "logf": if (arg != 0) { // log(x, a) = value => x = a ^ value return(GetNotNullEntites(FindInvertExpression(b, MathS.Pow(a, value), x))); } else { // log(a, x) = value => a = x ^ value => x = a ^ (1 / value) return(GetNotNullEntites(FindInvertExpression(a, MathS.Pow(b, 1 / value), x))); } default: throw new SysException("Unknown function"); } }
TreeAnalyzer.TryGetPolyLinear(arg, x, out var a, out _) => - MathS.Ln(MathS.Cos(arg)) / a,
// sin(x) -> sin(1 * x) // sin(x) + sin(a * x) // if x * a // x * a => a * x // if ! a * x // x => 1 * x // if ! a * x + b // a * x => a * x + 0 private static Entity ReplaceTrigonometry(Entity expr, VariableEntity variable, VariableEntity replacement) { // SolveLinear should also solve tan and cotan equations, but currently Polynomial solver cannot handle big powers // uncomment lines above when it will be fixed (TODO) var sin = expr.FindSubtree(MathS.Sin(variable)); var cos = expr.FindSubtree(MathS.Cos(variable)); //var tan = expr.FindSubtree(MathS.Tan (variable)); //var cot = expr.FindSubtree(MathS.Cotan(variable)); var sinReplacement = replacement / (2 * MathS.i) - MathS.Pow(replacement, -1) / (2 * MathS.i); var cosReplacement = replacement / 2 + MathS.Pow(replacement, -1) / 2; // var tanReplacement = (1 - MathS.Sqr(replacement)) * MathS.i * MathS.Pow(MathS.Sqr(replacement) + 1, -1); // var cotReplacement = (MathS.Sqr(replacement) + 1) * MathS.i * MathS.Pow(MathS.Sqr(replacement) - 1, -1); TreeAnalyzer.FindAndReplace(ref expr, sin, sinReplacement); TreeAnalyzer.FindAndReplace(ref expr, cos, cosReplacement); // TreeAnalyzer.FindAndReplace(ref expr, tan, tanReplacement); // TreeAnalyzer.FindAndReplace(ref expr, cot, cotReplacement); // workaround for missing Patterns.Variable(x), replace all expressions, false-matching pattern to variables // which will be returned back after all actual replacements var falseReplacements = new List <KeyValuePair <VariableEntity, Entity> >(); string falseReplacementName = "trig"; void ReplaceSinSubExpression(ref Entity expr, Entity toReplace, Entity a, Entity b, VariableEntity replacement) { // sin(ax + b) = (t^a * e^(i*b) - t^(-a) * e^(-i*b)) / (2i) var resultReplacement = (MathS.Pow(replacement, a) * (MathS.Pow(MathS.e, b * MathS.i) / (2 * MathS.i)) - MathS.Pow(replacement, -a) * (MathS.Pow(MathS.e, -b * MathS.i)) / (2 * MathS.i)); TreeAnalyzer.FindAndReplace(ref expr, toReplace, resultReplacement); } void ReplaceCosSubExpression(ref Entity expr, Entity toReplace, Entity a, Entity b, VariableEntity replacement) { // cos(ax + b) = (t^a * e^(i*b) + t^(-a) * e^(-i*b)) / 2 var resultReplacement = (MathS.Pow(replacement, a) * (MathS.Pow(MathS.e, b * MathS.i) / 2) + MathS.Pow(replacement, -a) * (MathS.Pow(MathS.e, -b * MathS.i)) / 2); TreeAnalyzer.FindAndReplace(ref expr, toReplace, resultReplacement); } // checks if pattern-matching succeeded. If not, replace subexpression with some variable bool CheckIfReplacementIsSuitable(ref Entity expr, Entity found, Entity variable, Entity variableToCheckFor) { if (variable != variableToCheckFor) { var repl = Utils.FindNextIndex(expr, falseReplacementName); falseReplacements.Add(new KeyValuePair <VariableEntity, Entity>(repl, found)); TreeAnalyzer.FindAndReplace(ref expr, found, repl); return(false); } return(true); } void MatchSinUntil(Pattern p, Func <Entity, (Entity, Entity, Entity)> variableGetter) { Entity found; while ((found = expr.FindPatternSubtree(p)) != null) { (Entity x, Entity a, Entity b) = variableGetter(found.Children[0]); if (CheckIfReplacementIsSuitable(ref expr, found, x, variable)) { ReplaceSinSubExpression(ref expr, found, a, b, replacement); } } } void MatchCosUntil(Pattern p, Func <Entity, (Entity, Entity, Entity)> variableGetter) { Entity found; while ((found = expr.FindPatternSubtree(p)) != null) { (Entity x, Entity a, Entity b) = variableGetter(found.Children[0]); if (CheckIfReplacementIsSuitable(ref expr, found, x, variable)) { ReplaceCosSubExpression(ref expr, found, a, b, replacement); } } } // arg => (x, a, b) // TODO: refactor this. Move to a list var variablePattern = new Pattern(1000, Entity.PatType.VARIABLE, tree => tree.entType == Entity.EntType.VARIABLE && tree.Name == variable.Name); var pattern1 = Sinf.PHang(Patterns.const1 * variablePattern + Patterns.any1); MatchSinUntil(pattern1, arg => (arg.Children[0].Children[1], arg.Children[0].Children[0], arg.Children[1])); var pattern2 = Sinf.PHang(variablePattern * Patterns.const1 + Patterns.any1); MatchSinUntil(pattern2, arg => (arg.Children[0].Children[0], arg.Children[0].Children[1], arg.Children[1])); var pattern3 = Sinf.PHang(Patterns.any1 + Patterns.const1 * variablePattern); MatchSinUntil(pattern3, arg => (arg.Children[1].Children[1], arg.Children[1].Children[0], arg.Children[0])); var pattern4 = Sinf.PHang(Patterns.any1 + variablePattern * Patterns.const1); MatchSinUntil(pattern4, arg => (arg.Children[1].Children[0], arg.Children[1].Children[1], arg.Children[0])); var pattern5 = Sinf.PHang(Patterns.const1 * variablePattern); MatchSinUntil(pattern5, arg => (arg.Children[1], arg.Children[0], 0)); var pattern6 = Sinf.PHang(variablePattern * Patterns.const1); MatchSinUntil(pattern6, arg => (arg.Children[0], arg.Children[1], 0)); var pattern7 = Sinf.PHang(Patterns.any1 + variablePattern); MatchSinUntil(pattern7, arg => (arg.Children[1], 1, arg.Children[0])); var pattern8 = Sinf.PHang(variablePattern + Patterns.any1); MatchSinUntil(pattern8, arg => (arg.Children[0], 1, arg.Children[1])); var pattern9 = Cosf.PHang(Patterns.const1 * variablePattern + Patterns.any1); MatchCosUntil(pattern9, arg => (arg.Children[0].Children[1], arg.Children[0].Children[0], arg.Children[1])); var pattern10 = Cosf.PHang(variablePattern * Patterns.const1 + Patterns.any1); MatchCosUntil(pattern10, arg => (arg.Children[0].Children[0], arg.Children[0].Children[1], arg.Children[1])); var pattern11 = Cosf.PHang(Patterns.any1 + Patterns.const1 * variablePattern); MatchCosUntil(pattern11, arg => (arg.Children[1].Children[1], arg.Children[1].Children[0], arg.Children[0])); var pattern12 = Cosf.PHang(Patterns.any1 + variablePattern * Patterns.const1); MatchCosUntil(pattern12, arg => (arg.Children[1].Children[0], arg.Children[1].Children[1], arg.Children[0])); var pattern13 = Cosf.PHang(Patterns.const1 * variablePattern); MatchCosUntil(pattern13, arg => (arg.Children[1], arg.Children[0], 0)); var pattern14 = Cosf.PHang(variablePattern * Patterns.const1); MatchCosUntil(pattern14, arg => (arg.Children[0], arg.Children[1], 0)); var pattern15 = Cosf.PHang(Patterns.any1 + variablePattern); MatchCosUntil(pattern15, arg => (arg.Children[1], 1, arg.Children[0])); var pattern16 = Cosf.PHang(variablePattern + Patterns.any1); MatchCosUntil(pattern16, arg => (arg.Children[0], 1, arg.Children[1])); // re-substitute all false replacement to return expression to normal foreach (var repl in falseReplacements) { TreeAnalyzer.FindAndReplace(ref expr, repl.Key, repl.Value); } return(expr); }
public void TestTan() { var func = MathS.Tan(2 * x); Assert.Equal(2 / MathS.Pow(MathS.Cos(2 * x), 2), func.Differentiate(x).Simplify()); }
public void Test4() { Assert.IsTrue(MathS.FromString("sin(x)").Derive(MathS.Var("x")).Simplify() == MathS.Cos(MathS.Var("x"))); }
public void TestSin() { var func = MathS.Sin(x); Assert.Equal(MathS.Cos(x), func.Differentiate(x).Simplify()); }
public void TestTan() { var func = MathS.Tan(2 * x); Assert.IsTrue(func.Derive(x).Simplify() == 2 / MathS.Pow(MathS.Cos(2 * x), 2)); }
public void TestSin() { var func = MathS.Sin(x); Assert.IsTrue(func.Derive(x).Simplify() == MathS.Cos(x)); }
public void TestTan() { var func = MathS.Tan(2 * x); AssertEqEntity(func.Derive(x).Simplify(), 2 / MathS.Pow(MathS.Cos(2 * x), 2)); }
public void Test4() => MathS.FromString((MathS.Sin(x) / MathS.Cos(x)).Differentiate(x).Stringize() ?? "");
public void Test2() { var func = (MathS.Sin(x) + MathS.Cos(x)).Compile(x); Assert.Equal(1, func.Substitute(0)); }