/// <summary>Solves ax^3 + bx^2 + cx + d</summary> /// <param name="a">Coefficient of x^3</param> /// <param name="b">Coefficient of x^2</param> /// <param name="c">Coefficient of x</param> /// <param name="d">Free coefficient</param> /// <returns>Set of roots</returns> internal static IEnumerable <Entity> SolveCubic(Entity a, Entity b, Entity c, Entity d) { // en: https://en.wikipedia.org/wiki/Cubic_equation // ru: https://ru.wikipedia.org/wiki/%D0%A4%D0%BE%D1%80%D0%BC%D1%83%D0%BB%D0%B0_%D0%9A%D0%B0%D1%80%D0%B4%D0%B0%D0%BD%D0%BE if (TreeAnalyzer.IsZero(d)) { return(SolveQuadratic(a, b, c).Append(0)); } if (TreeAnalyzer.IsZero(a)) { return(SolveQuadratic(b, c, d)); } var coeff = MathS.i * MathS.Sqrt(3) / 2; var u1 = Integer.Create(1); var u2 = Rational.Create(-1, 2) + coeff; var u3 = Rational.Create(-1, 2) - coeff; var D0 = MathS.Sqr(b) - 3 * a * c; var D1 = (2 * MathS.Pow(b, 3) - 9 * a * b * c + 27 * MathS.Sqr(a) * d).InnerSimplified; var C = MathS.Pow((D1 + MathS.Sqrt(MathS.Sqr(D1) - 4 * MathS.Pow(D0, 3))) / 2, Rational.Create(1, 3)); return(new[] { u1, u2, u3 }.Select(uk => C.Evaled == 0 && D0.Evaled == 0 ? -(b + uk * C) / 3 / a : -(b + uk * C + D0 / C / uk) / 3 / a)); }
public void Test6() { var expr = (MathS.Sqr(x) + MathS.Sqr(x)) / MathS.Sqr(x) + MathS.Sqrt(x); var func = expr.Compile(x); Assert.IsTrue(func.Call(4) == 4); }
public void TestInner() { var expr = MathS.FromString("sqrt(x + sqrt(x))"); var expected = MathS.Sqrt(x + MathS.Sqrt(x)); Assert.IsTrue(expr == expected); }
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"); }
public void Test6() { // Caching with one value var expr = (MathS.Sqr(x) + MathS.Sqr(x)) / MathS.Sqr(x) + MathS.Sqrt(x); var func = expr.Compile(x); Assert.Equal(4, func.Call(4)); }
public void TestLong() { // Caching with multiple values var expr = (MathS.Sqr(x) + MathS.Sqr(x)) / MathS.Sqr(x) + MathS.Sqrt(x) + MathS.Cbrt(x) * MathS.Cbrt(x) + MathS.Sqrt(x); var func = expr.Compile(x); Assert.Equal(34, func.Call(64)); }
public void TestComplex() { var expr = MathS.FromString("ln(x) + sqrt(x) + tan(x) + sec(x) + cosec(x) + cotan(x)"); var expected = MathS.Ln(x) + MathS.Sqrt(x) + MathS.Tan(x) + MathS.Sec(x) + MathS.Cosec(x) + MathS.Cotan(x); Assert.IsTrue(expr == expected); }
public void Test2() { var x = MathS.Var("x"); var y = MathS.Var("y"); var expr = x.Pow(x) - MathS.Sqrt(x - 3) / x + MathS.Sin(x); var expected = (3 * y).Pow(3 * y) - MathS.Sqrt(3 * y - 3) / (3 * y) + MathS.Sin(3 * y); var actual = expr.Substitute(x, 3 * y); Assert.IsTrue(expected == actual); }
public void TestComplicated() { Entity subExpr = "(a * x2 + b x) / (c x2 - 3)"; Entity expr = MathS.Sqrt(subExpr * 3 / MathS.Sin(subExpr) + MathS.Sin("d")); Entity.Variable x = nameof(x); Entity dest = Real.PositiveInfinity; var limit = expr.Limit(x, dest, ApproachFrom.Left); Assert.NotNull(limit); Assert.Equal("sqrt(a / c * 3 / sin(a / c) + sin(d))", limit?.Stringize()); }
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 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 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() }; }
/// <summary> /// solves ax3 + bx2 + cx + d /// </summary> /// <param name="a"> /// Coefficient of x^3 /// </param> /// <param name="b"> /// Coefficient of x^2 /// </param> /// <param name="c"> /// Coefficient of x /// </param> /// <param name="d"> /// Free coefficient /// </param> /// <returns> /// Set of roots /// </returns> internal static Set SolveCubic(Entity a, Entity b, Entity c, Entity d) { // en: https://en.wikipedia.org/wiki/Cubic_equation // ru: https://ru.wikipedia.org/wiki/%D0%A4%D0%BE%D1%80%D0%BC%D1%83%D0%BB%D0%B0_%D0%9A%D0%B0%D1%80%D0%B4%D0%B0%D0%BD%D0%BE // TODO (to remove sympy code!) Set res; if (TreeAnalyzer.IsZero(d)) { res = SolveQuadratic(a, b, c); res.Add(0); return(res); } if (TreeAnalyzer.IsZero(a)) { return(SolveQuadratic(b, c, d)); } res = new Set(); var coeff = MathS.i * MathS.Sqrt(3) / 2; var u1 = new NumberEntity(1); var u2 = SySyn.Rational(-1, 2) + coeff; var u3 = SySyn.Rational(-1, 2) - coeff; var D0 = MathS.Sqr(b) - 3 * a * c; var D1 = (2 * MathS.Pow(b, 3) - 9 * a * b * c + 27 * MathS.Sqr(a) * d).InnerSimplify(); var C = MathS.Pow((D1 + MathS.Sqrt(MathS.Sqr(D1) - 4 * MathS.Pow(D0, 3))) / 2, Number.CreateRational(1, 3)); foreach (var uk in new List <Entity> { u1, u2, u3 }) { Entity r; if (Const.EvalIfCan(C) == 0 && Const.EvalIfCan(D0) == 0) { r = -(b + uk * C) / 3 / a; } else { r = -(b + uk * C + D0 / C / uk) / 3 / a; } res.Add(r); } return(res); }
/// <summary>Solves ax^2 + bx + c</summary> /// <param name="a">Coefficient of x^2</param> /// <param name="b">Coefficient of x</param> /// <param name="c">Free coefficient</param> /// <returns>Set of roots</returns> internal static IEnumerable <Entity> SolveQuadratic(Entity a, Entity b, Entity c) { if (TreeAnalyzer.IsZero(c)) { return(SolveLinear(a, b).Append(0)); } if (TreeAnalyzer.IsZero(a)) { return(SolveLinear(b, c)); } var D = MathS.Sqr(b) - 4 * a * c; return(new[] { ((-b - MathS.Sqrt(D)) / (2 * a)).InnerSimplified, ((-b + MathS.Sqrt(D)) / (2 * a)).InnerSimplified }); }
internal static bool PullSin(ComplexNumber arg, out Entity res) { if (TryPulling(TableSin, arg, out res)) { return(true); } if (TryPulling(TableSin, MathS.DecimalConst.pi - arg, out res)) { return(true); } if (TryPulling(TableCos, arg * 2, out res)) { res = MathS.Sqrt((1 - res) / 2); return(true); } return(false); }
internal static bool PullCos(ComplexNumber arg, out Entity res) { if (TryPulling(TableCos, arg, out res)) { return(true); } if (TryPulling(TableCos, -1 * arg, out res)) { return(true); } if (TryPulling(TableCos, arg * 2, out res)) { res = MathS.Sqrt((1 + res) / 2); return(true); } return(false); }
internal static bool PullTan(ComplexNumber arg, out Entity res) { if (TryPulling(TableTan, arg, out res)) { return(true); } if (TryPulling(TableTan, (RealNumber)MathS.DecimalConst.pi - arg, out res)) { res *= -1; return(true); } if (TryPulling(TableCos, arg * 2, out res)) { res = MathS.Sqrt((1 - res) / (1 + res)); return(true); } return(false); }
/// <summary>Solves ax^4 + bx^3 + cx^2 + dx + e</summary> /// <param name="a">Coefficient of x^4</param> /// <param name="b">Coefficient of x^3</param> /// <param name="c">Coefficient of x^2</param> /// <param name="d">Coefficient of x</param> /// <param name="e">Free coefficient</param> /// <returns>Set of roots</returns> internal static IEnumerable <Entity> SolveQuartic(Entity a, Entity b, Entity c, Entity d, Entity e) { // en: https://en.wikipedia.org/wiki/Quartic_function // ru: https://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%A4%D0%B5%D1%80%D1%80%D0%B0%D1%80%D0%B8 if (TreeAnalyzer.IsZero(e)) { return(SolveCubic(a, b, c, d).Append(0)); } if (TreeAnalyzer.IsZero(a)) { return(SolveCubic(b, c, d, e)); } var alpha = (-3 * MathS.Sqr(b) / (8 * MathS.Sqr(a)) + c / a) .InnerSimplified; var beta = (MathS.Pow(b, 3) / (8 * MathS.Pow(a, 3)) - (b * c) / (2 * MathS.Sqr(a)) + d / a) .InnerSimplified; var gamma = (-3 * MathS.Pow(b, 4) / (256 * MathS.Pow(a, 4)) + MathS.Sqr(b) * c / (16 * MathS.Pow(a, 3)) - (b * d) / (4 * MathS.Sqr(a)) + e / a) .InnerSimplified; if (beta.Evaled == 0) { return(sqrtsOf1.SelectMany(_ => sqrtsOf1, (s, t) => - b / 4 * a + s * MathS.Sqrt((-alpha + t * MathS.Sqrt(MathS.Sqr(alpha) - 4 * gamma)) / 2))); } var oneThird = Rational.Create(1, 3); var P = (-MathS.Sqr(alpha) / 12 - gamma) .InnerSimplified; var Q = (-MathS.Pow(alpha, 3) / 108 + alpha * gamma / 3 - MathS.Sqr(beta) / 8) .InnerSimplified; var R = -Q / 2 + MathS.Sqrt(MathS.Sqr(Q) / 4 + MathS.Pow(P, 3) / 27); var U = MathS.Pow(R, oneThird) .InnerSimplified; var y = (Rational.Create(-5, 6) * alpha + U + (U.Evaled == 0 ? -MathS.Pow(Q, oneThird) : -P / (3 * U))) .InnerSimplified; var W = MathS.Sqrt(alpha + 2 * y) .InnerSimplified; // Now we need to permutate all four combinations return(sqrtsOf1.SelectMany(_ => sqrtsOf1, (s, t) => - b / (4 * a) + (s * W + t * MathS.Sqrt(-(3 * alpha + 2 * y + s * 2 * beta / W))) / 2)); }
/// <summary> /// 旋转单位向量From到另外一个单位向量To /// </summary> /// <param name="from">单位向量</param> /// <param name="to">单位向量</param> /// <returns>单位四元数</returns> public static Quaternion FromTo(Vector3 from, Vector3 to) { Quaternion uq = Quaternion.identity; float squar = 2 * (1 + Vector3.Dot(from, to)); if (MathS.Abs(squar) <= Threshold) { Vector3 perp = from.Perpendicular().normalized; uq = new Quaternion(perp.x, perp.y, perp.z, 0); } else { float root = MathS.Sqrt(squar); Vector3 imag = from.Cross(to) / root; float real = root * 0.5f; uq = new Quaternion(imag.x, imag.y, imag.z, real); } return(uq); }
internal static bool PullSin(ComplexNumber arg, out Entity res) { if (TryPulling(TableSin, arg, out res)) { return(true); } if (TryPulling(TableSin, (RealNumber)MathS.DecimalConst.pi - arg, out res)) { return(true); } if (TryPulling(TableCos, arg * 2, out res)) { res = MathS.Sqrt((1 - res) / 2); if (EDecimalWrapper.IsLess((Number.Sin(arg) as RealNumber).Value, 0)) { res *= -1; } return(true); } return(false); }
internal static bool PullCos(ComplexNumber arg, out Entity res) { if (TryPulling(TableCos, arg, out res)) { return(true); } if (TryPulling(TableCos, -1 * arg, out res)) { return(true); } if (TryPulling(TableCos, arg * 2, out res)) { res = MathS.Sqrt((1 + res) / 2); if ((Number.Cos(arg) as RealNumber).Value < 0) { res *= -1; } return(true); } return(false); }
/// <summary> /// solves ax2 + bx + c /// </summary> /// <param name="a"> /// Coefficient of x^2 /// </param> /// <param name="b"> /// Coefficient of x /// </param> /// <param name="c"> /// Free coefficient /// </param> /// <returns> /// Set of roots /// </returns> internal static Set SolveQuadratic(Entity a, Entity b, Entity c) { Set res; if (TreeAnalyzer.IsZero(c)) { res = SolveLinear(a, b); res.Add(0); return(res); } if (TreeAnalyzer.IsZero(a)) { return(SolveLinear(b, c)); } res = new Set(); var D = MathS.Sqr(b) - 4 * a * c; res.Add(((-b - MathS.Sqrt(D)) / (2 * a)).InnerSimplify()); res.Add(((-b + MathS.Sqrt(D)) / (2 * a)).InnerSimplify()); return(res); }
/// <summary> /// solves ax4 + bx3 + cx2 + dx + e /// </summary> /// <param name="a"> /// Coefficient of x^4 /// </param> /// <param name="b"> /// Coefficient of x^3 /// </param> /// <param name="c"> /// Coefficient of x^2 /// </param> /// <param name="d"> /// Coefficient of x /// </param> /// <param name="e"> /// Free coefficient /// </param> /// <returns> /// Set of roots /// </returns> internal static Set SolveQuartic(Entity a, Entity b, Entity c, Entity d, Entity e) { // en: https://en.wikipedia.org/wiki/Quartic_function // ru: https://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%A4%D0%B5%D1%80%D1%80%D0%B0%D1%80%D0%B8 Set res; if (TreeAnalyzer.IsZero(e)) { res = SolveCubic(a, b, c, d); res.Add(0); return(res); } if (TreeAnalyzer.IsZero(a)) { return(SolveCubic(b, c, d, e)); } res = new Set(); var alpha = (-3 * MathS.Sqr(b) / (8 * MathS.Sqr(a)) + c / a) .InnerSimplify(); var beta = (MathS.Pow(b, 3) / (8 * MathS.Pow(a, 3)) - (b * c) / (2 * MathS.Sqr(a)) + d / a) .InnerSimplify(); var gamma = (-3 * MathS.Pow(b, 4) / (256 * MathS.Pow(a, 4)) + MathS.Sqr(b) * c / (16 * MathS.Pow(a, 3)) - (b * d) / (4 * MathS.Sqr(a)) + e / a) .InnerSimplify(); if (Const.EvalIfCan(beta) == 0) { res.FastAddingMode = true; for (int s = -1; s <= 1; s += 2) { for (int t = -1; t <= 1; t += 2) { var x = -b / 4 * a + s * MathS.Sqrt((-alpha + t * MathS.Sqrt(MathS.Sqr(alpha) - 4 * gamma)) / 2); res.Add(x); } } res.FastAddingMode = false; return(res); } var oneThird = Number.CreateRational(1, 3); var P = (-MathS.Sqr(alpha) / 12 - gamma) .InnerSimplify(); var Q = (-MathS.Pow(alpha, 3) / 108 + alpha * gamma / 3 - MathS.Sqr(beta) / 8) .InnerSimplify(); var R = -Q / 2 + MathS.Sqrt(MathS.Sqr(Q) / 4 + MathS.Pow(P, 3) / 27); var U = MathS.Pow(R, oneThird) .InnerSimplify(); var y = (Number.CreateRational(-5, 6) * alpha + U + (Const.EvalIfCan(U) == 0 ? -MathS.Pow(Q, oneThird) : -P / (3 * U))) .InnerSimplify(); var W = MathS.Sqrt(alpha + 2 * y) .InnerSimplify(); // Now we need to permutate all four combinations res.FastAddingMode = true; /* we are sure that there's no such root yet */ for (int s = -1; s <= 1; s += 2) { for (int t = -1; t <= 1; t += 2) { var x = -b / (4 * a) + (s * W + t * MathS.Sqrt(-(3 * alpha + 2 * y + s * 2 * beta / W))) / 2; res.Add(x); } } res.FastAddingMode = false; return(res); }
public void TestArc3() { var func = MathS.Arccos(2 * x); AssertEqEntity(func.Derive(x).Simplify(), (-2) / MathS.Sqrt(1 + (-4) * MathS.Sqr(x))); }
public void TestArc2() { var func = MathS.Arcsin(2 * x); AssertEqEntity(func.Derive(x).Simplify(), 2 / MathS.Sqrt(1 + (-4) * MathS.Sqr(x))); }
public void TestArc1() { var func = MathS.Arcsin(x); AssertEqEntity(func.Derive(x).Simplify(), 1 / MathS.Sqrt(1 - MathS.Sqr(x))); }
[Fact] public void TestFormula19() => Assert.Equal(x * MathS.Sqrt(3), FromString("x sqrt(3)"));
public void Test1() { var func = (x + MathS.Sqrt(x)).Compile(x); Assert.IsTrue(func.Substitute(4) == 6); }
[TestMethod] public void SquareRoot() => Test(@"\sqrt{x}", MathS.Sqrt(x));
[TestMethod] public void SetDuplicates() => Test(@"\left\{\left[x-i,2-x\times i\right],2,\begin{pmatrix}a & i\\\pi & e\end{pmatrix},4,\left[x-i,3-x\times i\right],i\right\}", new Set(MathS.Sets.Interval(x - MathS.i, 2 - x * MathS.i), 2, MathS.Matrices.Matrix(2, 2, "a", "i", "pi", "e"), 2 + 2, MathS.Sets.Interval(x - MathS.i, 2 - x * MathS.i), MathS.Sqrt(16), MathS.Sets.Interval(x - MathS.i, 3 - x * MathS.i), MathS.Matrices.Matrix(2, 2, "a", "i", "pi", "e"), MathS.i));