Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions AngouriMath/Convenience/MathS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -324,5 +324,22 @@ public static Tensor Vector(params Entity[] p)
/// <param name="B"></param>
/// <returns></returns>
public static Entity ScalarProduct(Tensor A, Tensor B) => AngouriMath.Core.Sys.Items.Tensors.TensorFunctional.ScalarProduct(A, B);

/// <summary>
/// Checks tree for some unexpected bad occasions
/// Throws SysException's children
/// If you need a message, it's better to write
/// try
/// {
/// MathS.CheckTree(a);
/// }
/// catch (SysException e)
/// {
/// Console.WriteLine(e.Message);
/// }
/// </summary>
/// <param name="expr"></param>
/// <returns></returns>
public static void CheckTree(Entity expr) => TreeAnalyzer.CheckTree(expr);
}
}
1 change: 1 addition & 0 deletions AngouriMath/Core/FromString/SyntaxInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ internal static class SyntaxInfo
internal static readonly string goodCharsForNumbers = "1234567890i.";
internal static readonly string goodCharsForVars = "qwertyuiopasdfghjklzxcvbnm";
internal static readonly string goodCharsForOperators = "+-*/^,";
internal static int GetFuncArg(string name) => goodStringsForFunctions[name.Substring(0, name.Length - 1)];
internal static readonly Dictionary<string, int> goodStringsForFunctions = new Dictionary<string, int> {
{ "sin", 1 },
{ "cos", 1 },
Expand Down
3 changes: 2 additions & 1 deletion AngouriMath/Core/Sys/Exceptions/MathException.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;
using AngouriMath.Core.Exceptions;

namespace AngouriMath
{
public class MathSException : Exception
public class MathSException : SysException
{
public MathSException(string message) : base(message)
{
Expand Down
4 changes: 2 additions & 2 deletions AngouriMath/Core/Sys/Exceptions/SysExceptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

namespace AngouriMath.Core.Exceptions
{
internal class SysException : Exception
public class SysException : Exception
{
internal SysException(string msg) : base(msg) { }
public SysException(string msg) : base(msg) { }
}
}
18 changes: 2 additions & 16 deletions AngouriMath/Core/Sys/Items/Tensors/TensorFunctional.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,22 +135,8 @@ Entity Wrap(Entity p, Entity op)
{
var t1 = ch1 as Tensor;
var t2 = ch2 as Tensor;
if (expr.Name == "mulf")
{
if (t1.Dimensions == t2.Dimensions)
// if both are matrices, vectors, ...
{
if (t1.IsMatrix())
expr = DotProduct(t1, t2);
else
expr = ApplyPointwise(t1, t2, (a, b) => a * b);
}
}
else
{
string name = expr.Name;
expr = ApplyPointwise(t1, t2, (a, b) => MathFunctions.evalTable[name](new List<Entity>{ a, b }));
}
string name = expr.Name;
expr = ApplyPointwise(t1, t2, (a, b) => MathFunctions.evalTable[name](new List<Entity>{ a, b }));
}
else if (ch1.entType == Entity.EntType.TENSOR || ch2.entType == Entity.EntType.TENSOR)
{
Expand Down
21 changes: 20 additions & 1 deletion AngouriMath/Core/TreeAnalysis/CheckTree.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,12 @@ public partial class Tensor
{
internal override void Check()
{
// Can't have other name
TreeAnalyzer.AssertTree(Name == "tensort", "Tensors must have Name=tensort");
// Tensor can't be scalar
TreeAnalyzer.AssertTree(Dimensions > 0, "Dimensions can't be equal to 0");

// All elements are not null
for(int i = 0; i < Data.Length; i++)
TreeAnalyzer.AssertTree(Data[i] != null, "One tensor's element is null");
}
Expand All @@ -58,29 +62,44 @@ public partial class NumberEntity
{
internal override void Check()
{
TreeAnalyzer.AssertTree(Token.IsNumber(Name), "Number's name is number");
// Number has no children
TreeAnalyzer.AssertTree(Children.Count == 0, "A number cannot have children");
// Is null?
TreeAnalyzer.AssertTree(Token.IsNumber(Name), "Number's name is not number");
}
}
public partial class VariableEntity
{
internal override void Check()
{
// Var has no children
TreeAnalyzer.AssertTree(Children.Count == 0, "A variable cannot have children");
// Correct name for var
TreeAnalyzer.AssertTree(Token.IsVariable(Name), "Weird sequence in variable '" + Name + "'");
// Reserved word (e. g. "sumf") can't be a var's name
TreeAnalyzer.AssertTree(!Const.IsReservedName(Name), "`" + Name + "` is a reserved word");
}
}
public partial class FunctionEntity
{
internal override void Check()
{
// Number of children fits required number of args
TreeAnalyzer.AssertTree(Children.Count == SyntaxInfo.GetFuncArg(Name), "Wrong number of children");
// Checks whether the function exist
TreeAnalyzer.AssertTree(Const.IsReservedName(Name), "Unknown function");
}
}
public partial class OperatorEntity
{
internal override void Check()
{
// Only binary operators are available so far
TreeAnalyzer.AssertTree(Children.Count == 2, "Wrong number of children");
// If operator exists
TreeAnalyzer.AssertTree(Const.IsReservedName(Name), "Unknown operator");
// Detect division by 0
TreeAnalyzer.AssertTree(Name != "divf" || Children[1] != 0, "Division by zero");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,11 @@ internal static void FindDivisors(ref Entity expr, Func<Entity, Entity, bool> co
}
if (expr.entType == Entity.EntType.OPERATOR && expr.Name == "divf")
if (cond(expr.Children[0], expr.Children[1]))
{
expr = DividePolynoms(expr.Children[0], expr.Children[1]);
return;
}
}

internal static Entity DividePolynoms(Entity p, Entity q)
{
// Entity expr = "sqrt(x) * sin(y) + a ^ (-1) * x * 5 - x ^ 3 * sin(y) ^ 0.2 - 2 + a ^ 4";
// ---> (x^0.6 + 2x^0.3 + 1) / (x^0.3 + 1)
var replacementInfo = GatherAllPossiblePolynomials(p + q, replaceVars: true).replacementInfo;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,11 +236,7 @@ internal Entity BuildTree(Dictionary<int, Entity> keys)
internal class Pattern : Entity
{

internal override Entity InnerSimplify()
{
// Actually, no need to implement
throw new NotImplementedException();
}

public Pattern(int num, PatType type, string name = "") : base(name, EntType.PATTERN) {
PatternNumber = num;
PatternType = type;
Expand All @@ -267,6 +263,16 @@ protected override bool EqualsTo(Entity obj)
// Actually, no need to implement
throw new NotImplementedException();
}
internal override Entity InnerSimplify()
{
// Actually, no need to implement
throw new NotImplementedException();
}
internal override void Check()
{
// Actually, no need to implement
throw new NotImplementedException();
}

public static Pattern operator +(Pattern a, Pattern b) => Sumf.PHang(a, b);
public static Pattern operator +(Pattern a, Entity b) => Sumf.PHang(a, b);
Expand Down
21 changes: 6 additions & 15 deletions Samples/Samples/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,11 @@ static void Sample16()
Console.WriteLine(SySyn.Diff(expr, x, x));
}

static void Sample17()
private static void Sample17()
{
string x = MathS.ToBaseN(-32.25, 4);
Console.WriteLine("-32.25(10) = " + x + "(4)");
double y = MathS.FromBaseN("AB.3", 16);
var y = MathS.FromBaseN("AB.3", 16);
Console.WriteLine("AB.3(16) = " + y + "(1)");
}

Expand All @@ -143,19 +143,10 @@ static Complex MyFunc(Complex x)

static void Main(string[] _)
{

Tensor A = MathS.Matrix(2, 4,
1, 2, 3, 4,
5, 6, 7, 8
);
Tensor B = MathS.Matrix(4, 2,
1, 2,
3, 4,
5, 6,
7, 8
);
Console.WriteLine((A * B).EvalTensor().PrintOut());

Entity a = "x2";
Entity b = "(H - x)2 + (sqrt(2) * a)2";
var ans = (a - b).Solve("x")[0];
Console.WriteLine(ans.Simplify());
}
}
#pragma warning restore IDE0051
Expand Down
27 changes: 19 additions & 8 deletions Tests/UnitTests/Algebra/MatrixTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,35 @@ namespace UnitTests
[TestClass]
public class MatrixTest
{
public static readonly Tensor A = MathS.Matrix(2, 4,
1, 2, 3, 4,
5, 6, 7, 8
);
public static readonly Tensor A = MathS.Matrix(4, 2,
1, 2,
3, 4,
5, 6,
7, 8
);
public static readonly Tensor B = MathS.Matrix(4, 2,
1, 2,
3, 4,
5, 6,
7, 8
);

[TestMethod]
public void DotProduct1()
{
var C = MathS.Matrix(2, 2,
50, 60,
114, 140
);
var C = MathS.Matrix(4, 2,
1, 4,
9, 16,
25, 36,
49, 64
);
Assert.IsTrue((A * B).EvalTensor() == C);
}

[TestMethod]
public void SumProduct1()
{
Assert.IsTrue((A + B).EvalTensor() == (2 * A).EvalTensor());
}
}
}
20 changes: 14 additions & 6 deletions Tests/UnitTests/Common/CircleTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,52 +2,60 @@
using AngouriMath.Core;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace UnitTests
namespace UnitTests.Common
{
[TestClass]
public class CircleTest
{
public readonly static VariableEntity x = MathS.Var("x");
public static readonly VariableEntity x = MathS.Var("x");

[TestMethod]
public void Test1()
{
string expr = "1 + 2 * log(2, 3)";
const string expr = "1 + 2 * log(2, 3)";
Assert.AreEqual(expr, MathS.FromString(expr).ToString());
}

[TestMethod]
public void Test2()
{
string expr = "2 ^ 3 + sin(3)";
const string expr = "2 ^ 3 + sin(3)";
Assert.AreEqual(expr, MathS.FromString(expr).ToString());
}

[TestMethod]
public void Test3()
{
string expr = "23.3 + 3 / 3 + i";
const string expr = "23.3 + 3 / 3 + i";
Assert.AreEqual(expr, MathS.FromString(expr).ToString());
}

[TestMethod]
public void Test4()
{
MathS.FromString((MathS.Sin(x) / MathS.Cos(x)).Derive(x).ToString());
}

[TestMethod]
public void Test5()
{
Assert.IsTrue(MathS.Num(1).ToString() == "1");
Assert.IsTrue(MathS.Num(-1).ToString() == "-1");
}

[TestMethod]
public void Test6()
{
Assert.IsTrue(MathS.i.ToString() == "i");
Assert.IsTrue((-1 * MathS.i).ToString() == "-i");
}

[TestMethod]
public void Test7()
{
Assert.IsTrue(MathS.Sin(MathS.Arcsin(x * 3)).Simplify() == 3 * x);
}

[TestMethod]
public void Test8()
{
Expand Down Expand Up @@ -75,4 +83,4 @@ public void TestSys()
*/
}
}
}
}
47 changes: 47 additions & 0 deletions Tests/UnitTests/Common/ExceptionTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System;
using AngouriMath;
using AngouriMath.Core;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using AngouriMath.Core.Exceptions;

namespace UnitTests.Common
{
[TestClass]
public class ExceptionTest
{
public void AssertExceptionThrown(Func<bool> func)
{
try
{
func();
}
catch (SysException e)
{
// We don't do anything as it's ok
}
catch (Exception e)
{
Assert.Fail("Unexpected exception: " + e.Message);
}
}

[TestMethod]
public void TreeCheck1()
=> AssertExceptionThrown(() =>
{
Entity expr = "x2 + x3 / 0";
MathS.CheckTree(expr);
return true;
});

[TestMethod]
public void TreeCheck2()
=> AssertExceptionThrown(() =>
{
Entity expr = "x2 + x3 / 0";
expr.Children.Add(expr);
MathS.CheckTree(expr);
return true;
});
}
}
2 changes: 0 additions & 2 deletions Tests/UnitTests/Common/PerformanceTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ public long Measure(Func<object> func)
[TestMethod]
public void Test2() => Assert.IsTrue(Measure(() => MathS.FromString("x + log(2, 4)^2 * sin(cos(sin(cos(5)))) + x^3")) < 10);
[TestMethod]
public void Test3() => Assert.IsTrue(Measure(() => (x.Pow(3) + x.Pow(2) - 4 * x - 4).SolveNt(x, precision: 400)) < 300);
[TestMethod]
public void Test4() => Assert.IsTrue(Measure(() => x / x) < 1);
[TestMethod]
public void Test5() => Assert.IsTrue(Measure(() => (x * MathS.Pow(MathS.e, x) * MathS.Ln(x) - MathS.Sqrt(x / (x * x - 1))).Derive(x)) < 30);
Expand Down