diff --git a/symja_android_library/matheclipse-api/src/test/java/org/matheclipse/api/TestPods.java b/symja_android_library/matheclipse-api/src/test/java/org/matheclipse/api/TestPods.java index 7149097bf..feface592 100644 --- a/symja_android_library/matheclipse-api/src/test/java/org/matheclipse/api/TestPods.java +++ b/symja_android_library/matheclipse-api/src/test/java/org/matheclipse/api/TestPods.java @@ -2093,7 +2093,7 @@ public void testTransliterate() { + " \"error\" : \"false\",\n" // + " \"numsubpods\" : 1,\n" // + " \"subpods\" : [ {\n" // - + " \"markdown\" : \"## Chop\\n\\n```\\nChop(numerical-expr)\\n```\\n\\n> replaces numerical values in the `numerical-expr` which are close to zero with symbolic value `0`. \\n\\n```\\nChop(numerical-expr, delta)\\n```\\n\\n> uses a tolerance of `delta`. The default tolerance is `10^-10`.\\n \\n### Examples\\n\\n```\\n>> Chop(0.00000000001)\\n0\\n```\\n\\n\\n### Implementation status\\n\\n* ✅ - full supported\\n\\n### Github\\n\\n* [Implementation of Chop](https://github.com/axkr/symja_android_library/blob/master/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/Arithmetic.java#L706) \\n[Github master](https://github.com/axkr/symja_android_library/blob/master/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/Arithmetic.java#L706)\\n\\n\"\n" // + + " \"markdown\" : \"## Chop\\n\\n```\\nChop(numerical-expr)\\n```\\n\\n> replaces numerical values in the `numerical-expr` which are close to zero with symbolic value `0`. \\n\\n```\\nChop(numerical-expr, delta)\\n```\\n\\n> uses a tolerance of `delta`. The default tolerance is `10^-10`.\\n \\n### Examples\\n\\n```\\n>> Chop(0.00000000001)\\n0\\n```\\n\\n\\n### Implementation status\\n\\n* ✅ - full supported\\n\\n### Github\\n\\n* [Implementation of Chop](https://github.com/axkr/symja_android_library/blob/master/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/Arithmetic.java#L706) \\n[Github master](https://github.com/axkr/symja_android_library/blob/master/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/Arithmetic.java#L705)\\n\\n\"\n" // + " } ]\n" // + " } ]\n" // + " }\n" // diff --git a/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/BooleanTest.java b/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/BooleanTest.java index 3e4b2b1a9..d06077cae 100644 --- a/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/BooleanTest.java +++ b/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/BooleanTest.java @@ -462,7 +462,6 @@ public void testEqual() { // "0.1111111111111111 == 0.1111111111111126", // // "True"); - // mathics expects result: 2. + 3.14159 I == 2 + 3 a check("2.+ I*Pi == 2 + 3*a", // "a==I*1.0472"); diff --git a/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/CompilerFunctionsTest.java b/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/CompilerFunctionsTest.java index 5b5eb99d1..92e788bea 100644 --- a/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/CompilerFunctionsTest.java +++ b/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/CompilerFunctionsTest.java @@ -283,7 +283,7 @@ public void testCompilePrint002() { + " double xd = engine.evalDouble(x);\n" // + " stack.set(top++, F.num(xd));\n" // + " \n" // - + " return F.num((20.085536923187668)-Math.cos((9.869604401089358)/evalDouble(stack.get(1))));\n" // + + " return F.num(20.085536923187668-Math.cos(9.869604401089358/evalDouble(stack.get(1))));\n" // + " \n" // + " }\n" // + " public double evalDouble(IExpr expr) {\n" // diff --git a/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/LinearAlgebraTestCase.java b/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/LinearAlgebraTestCase.java index 8aa6fc0ea..1c6877026 100644 --- a/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/LinearAlgebraTestCase.java +++ b/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/LinearAlgebraTestCase.java @@ -41,6 +41,32 @@ public void testAdjugate() { + " {-4.0,5.0}}"); } + @Test + public void testAnglePath() { + // avoid index out of bounds exception + check("AnglePath(RandomReal({-1, 1}, {100}));", // + ""); + check("AnglePath({90*Degree, 90*Degree, 90*Degree})", // + "{{0,0},{0,1},{-1,1},{-1,0}}"); + check("AnglePath({90*Degree, Pi/3, -Pi/4})", // + "{{0,0},{0,1},{-Sqrt(3)/2,3/2},{(1-Sqrt(3))/(2*Sqrt(2))-Sqrt(3)/2,3/2+(1+Sqrt(3))/(\n" + + "2*Sqrt(2))}}"); + check("AnglePath({{0.7, 90*Degree}, {2.3, Pi/3}, {3.5, -Pi/4}})", // + "{{0,0},{0.0,0.7},{-1.99186,1.85},{-2.89773,5.23074}}"); + + check("AnglePath({t1,t2,t3})", // + "{{0,0},{Cos(t1),Sin(t1)},{Cos(t1)+Cos(t1+t2),Sin(t1)+Sin(t1+t2)},{Cos(t1)+Cos(t1+t2)+Cos(t1+t2+t3),Sin(t1)+Sin(t1+t2)+Sin(t1+t2+t3)}}"); + + check("AnglePath({{r1,t1},{r2,t2},{r3,t3}})", // + "{{0,0},{r1*Cos(t1),r1*Sin(t1)},{r1*Cos(t1)+r2*Cos(t1+t2),r1*Sin(t1)+r2*Sin(t1+t2)},{r1*Cos(t1)+r2*Cos(t1+t2)+r3*Cos(t1+t2+t3),r1*Sin(t1)+r2*Sin(t1+t2)+r3*Sin(t1+t2+t3)}}"); + + check("AnglePath({{x, y},t0}, {{r1,t1},{r2,t2},{r3,t3}})", // + "{{x,y},{x+r1*Cos(t0+t1),y+r1*Sin(t0+t1)},{x+r1*Cos(t0+t1)+r2*Cos(t0+t1+t2),y+r1*Sin(t0+t1)+r2*Sin(t0+t1+t2)},{x+r1*Cos(t0+t1)+r2*Cos(t0+t1+t2)+r3*Cos(t0+t1+t2+t3),y+r1*Sin(t0+t1)+r2*Sin(t0+t1+t2)+r3*Sin(t0+t1+t2+t3)}}"); + check("AnglePath({{x, y},t0}, { })", // + "{{x,y}}"); + + } + @Test public void testAngleVector() { check("AngleVector(x)", // @@ -51,6 +77,8 @@ public void testAngleVector() { "{0,1}"); check("AngleVector({1, 10}, a)", // "{1+Cos(a),10+Sin(a)}"); + check("AngleVector({x,y}, {r,t})", // + "{x+r*Cos(t),y+r*Sin(t)}"); } @Test diff --git a/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/LowercaseTestCase.java b/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/LowercaseTestCase.java index a3352a916..05a6c625e 100644 --- a/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/LowercaseTestCase.java +++ b/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/LowercaseTestCase.java @@ -4303,6 +4303,20 @@ public void testCyclotomic() { @Test public void testD() { + // check("D(a*3^x,{x,n})", // + // "a*E^x"); + // TODO + check("D(a*Exp(x),{x,n})", // + "a*E^x"); + check("D(a*f(x),{x,10})", // + "a*Derivative(10)[f][x]"); + check("D(a*Exp(x),{x,3})", // + "a*E^x"); + check("D(Tan(x),{x,3})", // + "2*Sec(x)^4+4*Sec(x)^2*Tan(x)^2"); + check("D(Cot(x),{x,5})", // + "-16*Cot(x)^4*Csc(x)^2-88*Cot(x)^2*Csc(x)^4-16*Csc(x)^6"); + check("D((2*Sqrt(2)*(x^3))/(x^4),x)", // "(-2*Sqrt(2))/x^2"); check("D(z^n*E^(z),{z,n})", // @@ -4753,10 +4767,14 @@ public void testDelete() { "Identity(a,b,c)"); check("Delete({ }, 0)", // "Identity()"); - // print Cannot delete position 5 in {a,b,c,d} + check("Delete({1, 2}, 0)", // + "Identity(1,2)"); + // Delete: Part {5} of {a,b,c,d} does not exist. check("Delete({a, b, c, d}, 5)", // "Delete({a,b,c,d},5)"); - + // List: List of Java int numbers expected in {1,n}. + check("Delete({a, b, c, d}, {1, n})", // + "Delete({a,b,c,d},{1,n})"); check("Delete({a, b, c, d}, 3)", // "{a,b,d}"); check("Delete({a, b, c, d}, -2)", // @@ -4778,6 +4796,9 @@ public void testDelete() { "Delete(pos)[x]"); check("Delete(2)[{1,2,3,4}]", // "{1,3,4}"); + + check("Delete(f[a, b, u + v, c], {3, 0})", // + "f(a,b,u,v,c)"); } @Test @@ -5055,6 +5076,18 @@ public void testCapitalDifferentialD() { @Test public void testDerivative() { + check("Derivative(1)[Log10]", // + "1/(Log(10)*#1)&"); + check("Derivative(1)[Log2]", // + "1/(Log(2)*#1)&"); + check("Derivative(1)[Exp]", // + "E^#1&"); + check("Derivative(1)[Abs]", // + "Derivative(1)[Abs]"); + check("Derivative(1)[RealAbs]", // + "#1/RealAbs(#1)&"); + check("Derivative(3)[ArcCos]", // + "-(1+2*#1^2)/(1-#1^2)^(5/2)&"); check("Derivative(0,0,0,n)[Hypergeometric2F1Regularized]", // "Hypergeometric2F1Regularized(n+#1,n+#2,n+#3,#4)*Pochhammer(#1,n)*Pochhammer(#2,n)&"); check("Derivative(0,0,0,Sin(7))[Hypergeometric2F1Regularized]", // @@ -5063,8 +5096,6 @@ public void testDerivative() { "Hypergeometric2F1Regularized(3+#1,3+#2,3+#3,#4)*Pochhammer(#1,3)*Pochhammer(#2,3)&"); check("Derivative(0,0,0)[Sequence()]", // "Derivative(0,0,0)[]"); - check("Derivative(1)[Abs]", // - "Derivative(1)[Abs]"); check("Derivative(1,0)[StruveH][#1,#2]", // "Derivative(1,0)[StruveH][#1,#2]"); @@ -8682,6 +8713,7 @@ public void testFlatOrderlessOneIdentity() { @Test public void testFlatten() { + // message Flatten: Level specification value greater equal 0 expected instead of -Infinity. check("Flatten(f(g(u, v), f(x, y)), -Infinity, f)", // "Flatten(f(g(u,v),f(x,y)),-Infinity,f)"); @@ -11425,6 +11457,13 @@ public void testInverseCDF() { @Test public void testInverseFunction() { + check("InverseFunction(Log2)", // + "2^#1&"); + check("InverseFunction(Log10)", // + "10^#1&"); + check("InverseFunction(Erfi)", // + "-I*InverseErf(I*#1)&"); + check("InverseFunction(Power,1,2)", // "#1^(1/#2)&"); check("InverseFunction(Power,2,2)", // @@ -11593,7 +11632,7 @@ public void testJacobiSymbol() { "1"); // check("JacobiSymbol(n, 1)", "n"); check("JacobiSymbol(-3, {1, 3, 5, 7})", // - "{JacobiSymbol(-3,1),JacobiSymbol(-3,3),JacobiSymbol(-3,5),JacobiSymbol(-3,7)}"); + "{1,0,-1,1}"); } @Test @@ -11624,9 +11663,9 @@ public void testJavaForm() { check("JavaForm(E^3-Cos(Pi^2/x), Prefix->True)", // "F.Subtract(F.Exp(F.C3),F.Cos(F.Times(F.Sqr(F.Pi),F.Power(F.x,F.CN1))))"); check("JavaForm(E^3-Cos(Pi^2/x), Float->True)", // - "(20.085536923187668)-Math.cos((9.869604401089358)/x)"); + "20.085536923187668-Math.cos(9.869604401089358/x)"); check("JavaForm(E^3-Cos(Pi^2/x), Float)", // - "(20.085536923187668)-Math.cos((9.869604401089358)/x)"); + "20.085536923187668-Math.cos(9.869604401089358/x)"); check("JavaForm(Hold(D(sin(x)*cos(x),x)), prefix->True)", // "F.D(F.Times(F.Sin(F.x),F.Cos(F.x)),F.x)"); @@ -11673,7 +11712,7 @@ public void testJSForm() { + " return x;})()\n" + ""); check("JSForm(E^3-Cos(Pi^2/x))", // - "(20.085536923187668)-Math.cos((9.869604401089358)/x)"); + "20.085536923187668-Math.cos(9.869604401089358/x)"); check("Piecewise({{x, 0 < x < 1}, {x^3, 1 < x < 2}}) // JSForm", // "\n" // @@ -11701,7 +11740,7 @@ public void testJSForm() { check("JSForm(a+b)", // "a+b"); check("JSForm(E^3-Cos(Pi^2/x) )", // - "(20.085536923187668)-Math.cos((9.869604401089358)/x)"); + "20.085536923187668-Math.cos(9.869604401089358/x)"); // JSXGraph.org syntax EvalEngine.resetModuleCounter4JUnit(); // check( @@ -11905,6 +11944,25 @@ public void testKleinInvariantJ() { + "0.387321+I*(-0.100372),-0.051849,0.387321+I*0.100372,1.0}"); } + @Test + public void testKronekerSymbol() { + + check("KroneckerSymbol(2,3)", // + "-1"); + check("Table(KroneckerSymbol(n, m), {n, 0, 5}, {m, 0, 5})", // + "{{0,1,0,0,0,0},{1,1,1,1,1,1},{0,1,0,-1,0,-1},{0,1,-1,0,1,-1},{0,1,0,1,0,1},{0,1,-\n" // + + "1,-1,1,0}}"); + check("Table(KroneckerSymbol(n, m), {n, -5, -1}, {m, -5, -1})", // + "{{0,-1,-1,1,-1},{-1,0,1,0,-1},{1,-1,0,1,-1},{1,0,-1,0,-1},{-1,-1,1,-1,-1}}"); + check("KroneckerSymbol(10,13)", // + "1"); + check("KroneckerSymbol(10^11 + 1, Prime(2000))", // + "-1"); + check("KroneckerSymbol({2, 3, 5, 7, 11}, 6)", // + "{0,0,1,1,1}"); + + } + @Test public void testValues() { check("Values(<|a :> 1 + 1, b -> Nothing|>, Hold)", // @@ -13063,6 +13121,8 @@ public void testLinearModelFit() { @Test public void testLinearRecurrence() { + check("LinearRecurrence({1, 1}, {1, 1}, {5, 5})", // + "{5}"); check("LinearRecurrence({0, 1, 1}, {1, 1, 1}, 0)", // "LinearRecurrence({0,1,1},{1,1,1},0)"); check("LinearRecurrence({0, 1, 1}, {1, 1, 1}, 1)", // @@ -13381,6 +13441,8 @@ public void testLog() { @Test public void testLog10() { + checkNumeric("10*Log10(1000)", // + "30"); checkNumeric("Log10(Interval({1/3, 2}))", // "Interval({-Log(3)/Log(10),Log(2)/Log(10)})"); check("N(Log10(45), 100)", // @@ -13679,6 +13741,18 @@ public void testMap() { "{a,{x({b,c}),d,{e,x({f,g})}}}"); } + @Test + public void testMapApply() { + check("MapApply(h, {{a, b}, {c, d}})", // + "{h(a,b),h(c,d)}"); + check("h@@@{{a,b},{c,d}}", // + "{h(a,b),h(c,d)}"); + check("MapApply(h)[{{a, b}, {c}, {d, e}}]", // + "{h(a,b),h(c),h(d,e)}"); + check("MapApply(h, p(x)[q(y)], Heads -> True)", // + "h(x)[h(y)]"); + } + @Test public void testMapAt() { check("MapAt(f, {{a, b, c}, {d, e}}, {All, 2})", // @@ -15986,6 +16060,17 @@ public void testNothing() { "{b,d,e,f,g}"); } + @Test + public void testNumberDigit() { + check("RealDigits(123456)", // + "{{1,2,3,4,5,6},6}"); + check("NumberDigit(123456, 2)", // + "4"); + // TODO + // check("NumberDigit(12.3456, -1)", // + // "4"); + } + @Test public void testNumberQ() { check("NumberQ(3,4)", // @@ -17191,6 +17276,13 @@ public void testPi() { @Test public void testPick() { + check("Pick({a, b, c}, {False, True, False})", // + "{b}"); + check("Pick(f(g(1, 2), h(3, 4)), {{True, False}, {False, True}})", // + "f(g(1),h(4))"); + check("Pick({a, b, c, d, e}, {1, 2, 3.5, 4, 5.5}, _Integer)", // + "{a,b,d}"); + // check( // "Pick(<|s1-><|a->0,b:>1|>,s2:><|a->0,b:>1|>|>,(1+Sqrt(5))/2,5)", // // "{RuleDelayed(Association(0))}"); @@ -17457,6 +17549,8 @@ public void testPlusMinus() { public void testPolyLog() { // check("PolyLog(10007,-1.5707963267948966)", // // ""); + check("PolyLog(-7.0, I)", // + "136.0"); check("PolyLog(1, 3, z)", // "Pi^4/90-1/6*Log(1-z)^3*Log(z)-1/2*Log(1-z)^2*PolyLog(2,1-z)+Log(1-z)*PolyLog(3,1-z)-PolyLog(\n" // + "4,1-z)"); @@ -21345,6 +21439,8 @@ public void testSelectFirst() { @Test public void testSequence() { + check("Sequence( )", // + "Identity()"); check("Sequence(a,b,c)", // "Identity(a,b,c)"); check("{Sequence( ),a}", // @@ -22309,6 +22405,29 @@ public void testSort() { "{1.0,3+I,4,a}"); } + @Test + public void testReverseSort() { + check("ReverseSort({4, 1.0, a, 3+I})", // + "{a,4,3+I,1.0}"); + + check("ReverseSort({c, b, d, a})", // + "{d,c,b,a}"); + check("ReverseSort({-42,0,17,11,3,4,9})", // + "{17,11,9,4,3,0,-42}"); + // TODO sort `e` before `d` + check("ReverseSort(<|a -> 4, b -> 1, c -> 3, d -> 2, e -> 2|>)", // + "<|a->4,c->3,d->2,e->2,b->1|>"); + check("ReverseSort({0, 11, 13, 4, 9}, Greater)", // + "{0,4,9,11,13}"); + check("ReverseSort({c, b, d, a}, OrderedQ({#1, #2}) &)", // + "{d,c,b,a}"); + + // TODO define AlphabeticOrder + // check("ReverseSort({\"cat\", \"fish\", \"catfish\", \"Cat\"}, AlphabeticOrder(\"English\"))", + // // + // "{cat,fish,catfish,Cat}"); + } + @Test public void testSortBy() { check("SortBy({{5, 1}, {10, -1}}, Last)", // @@ -22539,6 +22658,8 @@ public void testStandardize() { @Test public void testSquaresR() { + check("Table(SquaresR(8, n), {n, 10})", // + "{16,112,448,1136,2016,3136,5504,9328,12112,14112}"); // TODO // check("TimeConstrained(SquaresR({3},2147483647),3)", // // ""); diff --git a/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/NumberTest.java b/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/NumberTest.java index 865aff931..779734a55 100644 --- a/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/NumberTest.java +++ b/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/NumberTest.java @@ -7,8 +7,6 @@ import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.util.Locale; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; import org.apfloat.Apfloat; import org.hamcrest.core.IsInstanceOf; import org.junit.Test; @@ -27,7 +25,6 @@ @RunWith(JUnit4.class) public class NumberTest { - private static final Logger LOGGER = LogManager.getLogger(); @Test public void testComplexNum() { @@ -75,7 +72,8 @@ public void testNumberFormat() { fail(); } } catch (RuntimeException rex) { - LOGGER.debug("NumberTest.testNumberFormat() failed", rex); + rex.printStackTrace(); + fail("NumberTest.testNumberFormat() failed"); } assertEquals(buf.toString(), "12345.12"); } diff --git a/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/SeriesTest.java b/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/SeriesTest.java index 4ad5bba63..7d7d12b51 100644 --- a/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/SeriesTest.java +++ b/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/SeriesTest.java @@ -116,6 +116,11 @@ public void testSeriesTaylor() { "1+x+x^2+O(x)^3"); } + @Test + public void testCoefficientList() { + check("CoefficientList(Series(Log(1-x), {x, 0, 9}), x)", // + "{0,-1,-1/2,-1/3,-1/4,-1/5,-1/6,-1/7,-1/8,-1/9}"); + } @Test public void testSeries() { // TODO check max power @@ -145,7 +150,7 @@ public void testSeries() { // ""); check("Series((1 + x)^n, {x, 0, 4})", // - "1+n*x+1/2*(-1+n)*n*x^2+1/6*(-2+n)*(-1+n)*n*x^3+1/24*(-3+n)*(-2+n)*(-1+n)*n*x^4+O(x)^\n" + "1+n*x+1/2*(-1+n)*n*x^2+1/6*(2*n-3*n^2+n^3)*x^3+1/24*(-6*n+11*n^2-6*n^3+n^4)*x^4+O(x)^\n" + "5"); check("Series(x^x, {x, 0, 4})", // "1+Log(x)*x+1/2*Log(x)^2*x^2+1/6*Log(x)^3*x^3+1/24*Log(x)^4*x^4+O(x)^5"); @@ -433,6 +438,10 @@ public void testIntegrateSeriesData() { @Test public void testSeriesCoefficient() { + check("SeriesCoefficient(ArcTan(x),{x,n,12})", // + "(3*n-55*n^3+198*n^5-198*n^7+55*n^9-3*n^11)/(3*(1+12*n^2+66*n^4+220*n^6+495*n^8+\n" // + + "792*n^10+924*n^12+792*n^14+495*n^16+220*n^18+66*n^20+12*n^22+n^24))"); + check("SeriesCoefficient(Fibonacci(z), {z, 0, n})", // "Piecewise({{(-(-I*Pi-ArcCsch(2))^n-(I*Pi-ArcCsch(2))^n+2*ArcCsch(2)^n)/(2*Sqrt(5)*n!),n>=\n" // + "1}},0)"); @@ -464,7 +473,7 @@ public void testSeriesCoefficient() { "Log(x)^4/24"); check("SeriesCoefficient(ChebyshevT(k, x), {x, 0, 2})", // - "((-1+k)*(1+k)*k^2*Pi)/(8*Gamma(1/2*(3-k))*Gamma(1/2*(3+k)))"); + "1/2*k^2*Cos(1/2*(-2+k)*Pi)"); check("SeriesCoefficient(d+4*x^e+7*x^f,{x, a, n})", // "Piecewise({{(4*a^e*Binomial(e,n)+7*a^f*Binomial(f,n))/a^n,n>0},{4*a^e+7*a^f+d,n==\n" + "0}},0)"); @@ -612,7 +621,8 @@ public void testPolyGammaSeries() { @Test public void testPowerSeries() { check("Series((a + x)^n, {x, 0, 2})", // - "a^n+(n*x)/a^(1-n)+((-1+n)*n*x^2)/(2*a^(2-n))+O(x)^3"); + "a^n+(n*x)/a^(1-n)+((-a^n*n+a^n*n^2)*x^2)/(2*a^2)+O(x)^3"); + // "a^n+(n*x)/a^(1-n)+((-1+n)*n*x^2)/(2*a^(2-n))+O(x)^3"); check("Series((a(x) + x)^n, {x, 0, 2})", // "a(0)^n+(n*(1+a'(0))*x)/a(0)^(1-n)+1/2*(((-1+n)*n*(1+a'(0))^2)/a(0)^(2-n)+(n*a''(\n" + "0))/a(0)^(1-n))*x^2+O(x)^3"); diff --git a/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/SimplifyTest.java b/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/SimplifyTest.java index dad89e441..551811d9c 100644 --- a/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/SimplifyTest.java +++ b/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/SimplifyTest.java @@ -850,16 +850,16 @@ public void testTrigSimplifyTR10i() { // assert TR10i(cos(x)/sqrt(6) + sin(x)/sqrt(2) + // cos(x)/sqrt(6)/3 + sin(x)/sqrt(2)/3) == 4*sqrt(6)*sin(x + pi/6)/9 - tr10i = TrigSimplifyFu.tr10i(F.Plus(// - F.Times(F.C1DSqrt6, F.Cos(F.x)), // - F.Times(F.C1DSqrt2, F.Sin(F.x)), // - F.Times(F.C1D3, F.C1DSqrt6, F.Cos(F.x)), // - F.Times(F.C1D3, F.C1DSqrt2, F.Sin(F.x)))); - tr10i = F.eval(tr10i); - assertEquals(tr10i.toString(), // - // 4*sqrt(6)*sin(x + pi/6)/9 - "4/3*Sqrt(2/3)*Sin(Pi/6+x)"); - + tr10i = TrigSimplifyFu.tr10i(F.Plus(// + F.Times(F.C1DSqrt6, F.Cos(F.x)), // + F.Times(F.C1DSqrt2, F.Sin(F.x)), // + F.Times(F.C1D3, F.C1DSqrt6, F.Cos(F.x)), // + F.Times(F.C1D3, F.C1DSqrt2, F.Sin(F.x)))); + tr10i = F.eval(tr10i); + assertEquals(tr10i.toString(), // + // 4*sqrt(6)*sin(x + pi/6)/9 + "4/3*Sqrt(2/3)*Sin(Pi/6+x)"); + // // assert TR10i(cos(x)/sqrt(6) + sin(x)/sqrt(2) + // // cos(y)/sqrt(6)/3 + sin(y)/sqrt(2)/3) == \ // // sqrt(6)*sin(x + pi/6)/3 + sqrt(6)*sin(y + pi/6)/9 @@ -957,6 +957,30 @@ public void testTrigSimplifyTR11() { "4*Cos(x)*Sin(x)*(1-2*Sin(x)^2)"); } + @Test + public void testTrigSimplifyTR11Simple() { + IExpr tr11 = TrigSimplifyFu.tr11(F.Cos(F.C2)); + assertEquals(tr11.toString(), // + "Cos(2)"); + + // TODO use base to get -Sin(2)^2 + Cos(2)**2 + // tr11 = TrigSimplifyFu.tr11(F.Cos(F.C2), 2); + // assertEquals(tr11.toString(), // + // " "); + } + + @Test + public void testTrigSimplifySO24819() { + // https://stackoverflow.com/a/79095795/24819 + // TR6(TR11(S('2 - 2*cos(2*pi*(x - y)/p)'))) + IExpr tr11 = TrigSimplifyFu.tr11(F.Subtract(F.C2, + F.Times(F.C2, F.Cos(F.Divide(F.Times(F.Times(F.C2, F.Pi), F.Subtract(F.x, F.y)), F.p))))); + IExpr tr6 = TrigSimplifyFu.tr6(tr11); + // TODO + assertEquals(tr6.toString(), // + "2-2*Cos((2*Pi*(x-y))/p)"); + } + @Test public void testTrigSimplifyTR12() { // tan(x + y) diff --git a/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/StringFunctionsTest.java b/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/StringFunctionsTest.java index 1847edf1c..46952ccd2 100644 --- a/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/StringFunctionsTest.java +++ b/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/StringFunctionsTest.java @@ -7,8 +7,8 @@ /** Tests for string functions */ public class StringFunctionsTest extends ExprEvaluatorTestCase { - @Test - public void testEditDistance() { + @Test + public void testEditDistance() { check("EditDistance(\"kitten\", \"kitchen\")", // "2"); check("EditDistance(\"abc\", \"ac\")", // @@ -21,8 +21,19 @@ public void testEditDistance() { "2"); } - @Test - public void testFileNameJoin() { + @Test + public void testFileNameDrop() { + String s = System.getProperty("os.name"); + if (s.contains("Windows")) { + check("FileNameDrop(\"\\\\a\\\\b\\\\c\", 2)", // + "b\\c"); + check("FileNameDrop(\"\\\\a\\\\b\\\\c\", -1)", // + "\\a\\b"); + } + } + + @Test + public void testFileNameJoin() { String s = System.getProperty("os.name"); if (s.contains("Windows")) { check("FileNameJoin({\"a\",\"b\",\"c\"})", // @@ -30,8 +41,8 @@ public void testFileNameJoin() { } } - @Test - public void testFileNameTake() { + @Test + public void testFileNameTake() { String s = System.getProperty("os.name"); if (s.contains("Windows")) { check("FileNameTake(\"/a/b/c.txt\")", // @@ -39,8 +50,8 @@ public void testFileNameTake() { } } - @Test - public void testFromLetterNumber() { + @Test + public void testFromLetterNumber() { check("FromLetterNumber({1,4,10,17})", // "{a,d,j,q}"); check("FromLetterNumber(26, \"Dutch\")", // @@ -53,16 +64,16 @@ public void testFromLetterNumber() { "Missing(NotApplicable)"); } - @Test - public void testHammingDistance() { + @Test + public void testHammingDistance() { check("HammingDistance(\"time\", \"dime\")", // "1"); check("HammingDistance(\"TIME\", \"dime\", IgnoreCase -> True)", // "1"); } - @Test - public void testAlphabet() { + @Test + public void testAlphabet() { // check( // "Alphabet(\"Hindi\")", // // "{अ,आ,इ,ई,उ,ऊ,ऋ,ए,ऐ,ओ,औ,क,ख,ग,घ,ङ,च,छ,ज,झ,ञ,ट,ठ,ड,ढ,ण,त,थ,द,ध,न,प,फ,ब,भ,म,य,र,ल,व,श,ष,स,ह}"); @@ -95,8 +106,8 @@ public void testAlphabet() { "{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z}"); } - @Test - public void testLetterNumber() { + @Test + public void testLetterNumber() { // English alphabet has only single character elements check("LetterNumber({\"P\", \"Pe\", \"P1\", \"eck\"})", // "{16,{16,5},{16,0},{5,3,11}}"); @@ -132,16 +143,16 @@ public void testLetterNumber() { "8"); } - @Test - public void testLongest() { + @Test + public void testLongest() { check("StringCases(\"aabaaab\", Longest(\"a\" ~~ __ ~~ \"b\"))", // "{aabaaab}"); check("StringCases(\"aabaaabaaabaaabaaab\", Longest(RegularExpression(\"a+b\")))", // "{aab,aaab,aaab,aaab,aaab}"); } - @Test - public void testShortest() { + @Test + public void testShortest() { check("StringCases(\"-(a)--(bb)--(c)-\", \"(\" ~~ __ ~~ \")\")", // "{(a)--(bb)--(c)}"); check("StringCases(\"-(a)--(bb)--(c)-\", Shortest(\"(\" ~~ __ ~~ \")\"))", // @@ -153,8 +164,8 @@ public void testShortest() { "{aab,aaab,aaab,aaab,aaab}"); } - @Test - public void testString() { + @Test + public void testString() { check("Head(\"abc\")", // "String"); check("\"abc\"", // @@ -175,14 +186,14 @@ public void testString() { "next line"); } - @Test - public void testStringExpression() { + @Test + public void testStringExpression() { check("\"a\" ~~ \"b\" ~~ \"c\" // FullForm ", // "\"abc\""); } - @Test - public void testStringForm() { + @Test + public void testStringForm() { // TODO fix case of mixing notations: // check("StringForm(\"`1` bla `2` blub `` bla `2`\", a, b, c)", // // "a bla b blub c bla b"); @@ -196,8 +207,8 @@ public void testStringForm() { "e1 e2 e3 e4 e5"); } - @Test - public void testStringFormat() { + @Test + public void testStringFormat() { check("StringFormat(\"abcd 1234\")", // "Text"); check("StringFormat(\"1 2 3\\n 5 6 7\\n 8 9 0\\n\")", // @@ -208,8 +219,8 @@ public void testStringFormat() { "TSV"); } - @Test - public void testStringFreeQ() { + @Test + public void testStringFreeQ() { check("StringFreeQ(2^x,\"a\")", // "StringFreeQ(2^x,a)"); check("StringFreeQ(\"symja\", \"s\" ~~__ ~~\"a\")", // @@ -228,8 +239,8 @@ public void testStringFreeQ() { "{True,True,False,False,False}"); } - @Test - public void testStringCount() { + @Test + public void testStringCount() { check( "StringCount(\"https://github.com/axkr/symja_android_library\", #) & /@ CharacterRange(\"a\", \"z\")", // "{4,2,1,2,0,0,1,2,3,1,1,1,2,1,2,1,0,4,2,3,1,0,0,1,2,0}"); @@ -250,8 +261,8 @@ public void testStringCount() { "1"); } - @Test - public void testStringCases() { + @Test + public void testStringCases() { check("StringCases(\"AaBBccDDeefG\", CharacterRange(\"A\", \"Z\") ..)", // "{A,BB,DD,G}"); check("StringCases(\"a#ä_123\", WordCharacter)", // @@ -277,8 +288,8 @@ public void testStringCases() { "{ab,ac,adaf}"); } - @Test - public void testStringContainsQ() { + @Test + public void testStringContainsQ() { check("StringContainsQ( \"BC\" , IgnoreCase -> True)[\"abcd\"]", // "True"); check("StringContainsQ({\"the quick brown fox\", \"jumps\", \"over the lazy dog\"}, \"the\")", // @@ -310,8 +321,8 @@ public void testStringContainsQ() { "True"); } - @Test - public void testStringDrop() { + @Test + public void testStringDrop() { check("StringDrop(\"abcdefghijklm\", 4)", // "efghijklm"); check("StringDrop(\"abcdefghijklm\", -4)", // @@ -320,8 +331,8 @@ public void testStringDrop() { "StringDrop(,-1)"); } - @Test - public void testStringInsert() { + @Test + public void testStringInsert() { check("StringInsert({\"\", \"Symja\"}, \"\", {1, 1, -1})", // "{,Symja}"); check("StringInsert({\"\", \"Symja\"}, \"X\", {1, 1, -1})", // @@ -346,8 +357,8 @@ public void testStringInsert() { "1.234.567.890.123.456"); } - @Test - public void testStringJoin() { + @Test + public void testStringJoin() { check("StringJoin({\"a\", \"b\"})// InputForm", // "\"ab\""); check("StringJoin(\"test\")", // @@ -366,14 +377,14 @@ public void testStringJoin() { "Java8"); } - @Test - public void testStringLength() { + @Test + public void testStringLength() { check("StringLength(\"symja\")", // "5"); } - @Test - public void testStringMatchQ() { + @Test + public void testStringMatchQ() { // message: StringMatchQ: String or list of strings expected at position 1 in // StringMatchQ(1/2,y___). check("StringMatchQ(1/2,y___)", // @@ -413,8 +424,8 @@ public void testStringMatchQ() { "True"); } - @Test - public void testStringPart() { + @Test + public void testStringPart() { check("StringPart(\"abcdefghijlkm\", 14)", // "StringPart(abcdefghijlkm,14)"); check("StringPart(\"abcdefghijlkm\", 13)", // @@ -429,8 +440,8 @@ public void testStringPart() { "{1,3,0}"); } - @Test - public void testStringPosition() { + @Test + public void testStringPosition() { check("StringPosition(1317624576693539401)[2^10007,{x__},1/0]", // "StringPosition(1317624576693539401)[2553680789607370732651189968234988907294075944814326342210571455811768170268409\\\n" + "1688857550955566329085311143845661707679067592308927249639830520045993083294666\\\n" @@ -477,8 +488,8 @@ public void testStringPosition() { "{{4,6},{9,11}}"); } - @Test - public void testStringTrim() { + @Test + public void testStringTrim() { check("StringJoin(\"a\", StringTrim(\" \\tb\\n \"), \"c\")", // "abc"); check("StringTrim(\"ababaxababyaabab\", RegularExpression(\"(ab)+\"))", // @@ -491,16 +502,16 @@ public void testStringTrim() { "\"aaa bbb ccc \""); } - @Test - public void testStringQ() { + @Test + public void testStringQ() { check("StringQ(a)", // "False"); check("StringQ(\"a\")", // "True"); } - @Test - public void testStringSplit() { + @Test + public void testStringSplit() { check("StringSplit(\"a bbb cccc aa d\")", // "{a,bbb,cccc,aa,d}"); check("StringSplit(\"a--bbb---ccc--dddd\", \"--\")", // @@ -569,25 +580,25 @@ public void testStringSplit() { "{a,b,c,d,efghijlkm}"); } - @Test - public void testStringExpresion() { + @Test + public void testStringExpresion() { check("\"ab\" ~~ _", // "ab~~_"); } - @Test - public void testStringRepeat() { + @Test + public void testStringRepeat() { check("StringRepeat(\"abc\", 3)", // "abcabcabc"); check("StringRepeat(\"abc\", 10, 7)", // "abcabca"); } - @Test - public void testStringReplace() { - // TODO use MMA logic for lists of rules - // check("StringReplace(\"ABBA\", {\"A\" -> \"AB\", \"B\" -> \"BA\"})", // - // "ABBABAAB "); + @Test + public void testStringReplace() { + // TODO use MMA logic for lists of rules + // check("StringReplace(\"ABBA\", {\"A\" -> \"AB\", \"B\" -> \"BA\"})", // + // "ABBABAAB "); check( "StringReplace(\"The number 17 is a prime number, 42 is not\", WordBoundary ~~ x:DigitCharacter.. ~~ WordBoundary /; PrimeQ(ToExpression(x)) :> \"*\" <> x <> \"*\")", // "The number *17* is a prime number, 42 is not"); @@ -631,15 +642,22 @@ public void testStringReplace() { "\" see you later alligator.\""); } - @Test - public void testStringReverse() { + @Test + public void testStringReplace_List() { + // https://en.wikipedia.org/wiki/Palindrome + check("StringReplace({\"abbaabbaa\",\"abababa\"}, \"ab\" -> \"X\")", // + "{XbaXbaa,XXXa}"); + } + + @Test + public void testStringReverse() { // https://en.wikipedia.org/wiki/Palindrome check("StringReverse(\"Never odd or even\")", // "neve ro ddo reveN"); } - @Test - public void testStringRiffle() { + @Test + public void testStringRiffle() { check("StringRiffle({\"a\", \"b\", \"c\", \"d\", \"e\"})", // "a b c d e"); @@ -666,8 +684,8 @@ public void testStringRiffle() { "(a-b-c\n" + "d-e-f)"); } - @Test - public void testStringTake() { + @Test + public void testStringTake() { // TODO // check( // "StringTake( \"abc\",{{1,1},{1,3},{0,0},{1,2},{-1},{4}}) // InputForm", // @@ -755,16 +773,16 @@ public void testStringTake() { "jklm"); } - @Test - public void testStringTemplate() { + @Test + public void testStringTemplate() { // operator form check( "StringTemplate(\"The quick brown `a` jumps over the lazy `b`.\")[<|\"a\" -> \"fox\", \"b\" -> \"dog\"|>]", // "The quick brown fox jumps over the lazy dog."); } - @Test - public void testTemplateApply() { + @Test + public void testTemplateApply() { check( "TemplateApply(\"The quick brown `a` jumps over the lazy `b`.\",<|\"a\" -> \"fox\", \"b\" -> \"dog\"|>)", // "The quick brown fox jumps over the lazy dog."); @@ -803,8 +821,8 @@ public void testTemplateApply() { "We use the Pebble template engine."); } - @Test - public void testTemplateIf() { + @Test + public void testTemplateIf() { check( "t=TemplateIf( TemplateSlot(\"summer\"), \"in summer ice cream is delicious\", \"ice cream is boring in winter\"); TemplateApply(t, <|\"summer\" -> True|>)", // "in summer ice cream is delicious"); @@ -813,20 +831,20 @@ public void testTemplateIf() { "True"); } - @Test - public void testToLowerCase() { + @Test + public void testToLowerCase() { check("ToLowerCase(\"This is a Test\")", // "this is a test"); } - @Test - public void testToUpperCase() { + @Test + public void testToUpperCase() { check("ToUpperCase(\"This is a Test\")", // "THIS IS A TEST"); } - @Test - public void testWhitespace() { + @Test + public void testWhitespace() { check("StringMatchQ(\"\\r \\n\", Whitespace)", // "True"); @@ -834,22 +852,22 @@ public void testWhitespace() { "{a,b,c,d}"); } - @Test - public void testWhitespaceCharacter() { + @Test + public void testWhitespaceCharacter() { check("StringMatchQ(\"\\n\", WhitespaceCharacter)", // "True"); check("StringSplit(\"a\\nb\\nc d\", WhitespaceCharacter)", // "{a,b,c,d}"); } - @Test - public void testWordBoundary() { + @Test + public void testWordBoundary() { check("StringReplace(\"apple banana orange artichoke\", \"e\" ~~ WordBoundary -> \"E\")", // "applE banana orangE artichokE"); } - @Test - public void testWordCharacter() { + @Test + public void testWordCharacter() { check("StringMatchQ(#, WordCharacter) &/@ {\"1\", \"a\", \"A\", \",\", \" \"}", // "{True,True,True,False,False}"); check("StringMatchQ(\"abc123DEF\", WordCharacter..)", //