Skip to content

Commit

Permalink
Merge pull request #28 from prekel/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
prekel authored Jun 10, 2018
2 parents bf86df0 + 4d8c257 commit 007912b
Show file tree
Hide file tree
Showing 35 changed files with 1,000 additions and 183 deletions.
23 changes: 16 additions & 7 deletions MyExpression.Console/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@ public class Program
{
private static void Main(string[] args)
{
System.Console.Write("Equation: ");
var s = System.Console.ReadLine();
var p = Polynomial.Parse(s);
var e = new PolynomialEquation(p, 1e-8);
e.Solve();
//System.Console.WriteLine(String.Join(" ", e.AllRoots));
System.Console.WriteLine(" Roots: " + String.Join(" ", e.Roots));
//System.Console.Write("Equation: ");
//var s = System.Console.ReadLine();
//System.Console.Write(" Epsilon: ");
//var eps = System.Console.ReadLine();
//var p = Polynomial.Parse(s);
//var e = new PolynomialEquation(p, Double.Parse(eps));
//e.Solve();
////System.Console.WriteLine(String.Join(" ", e.AllRoots));
//System.Console.WriteLine(" Roots: " + String.Join(" ", e.Roots));
//System.Console.ReadKey();

//var s = System.Console.ReadLine();
//var evaluator = new CodeDomEval(s);
Expand Down Expand Up @@ -48,6 +51,12 @@ private static void Main(string[] args)
//e.Solve();
////System.Console.WriteLine(String.Join(" ", e.AllRoots));
//System.Console.WriteLine(" Roots: " + String.Join(" ", e.Roots));

//var f = new CodeDomEval("pow(x, 3) - 2 * pow(x, 2) - x + 2");
//var f = new CodeDomEval("sin(x)");
var e = new FunctionEquation(Math.Sin, new Interval(-5, 5), eps: 1e-15);
e.Solve();
var r = e.AllRoots;
}
}
}
28 changes: 20 additions & 8 deletions MyExpression.Core.Tests/CodeDomEvalTests.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
using NUnit.Framework;
// Copyright (c) 2018 Vladislav Prekel

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using NUnit.Framework;

namespace MyExpression.Core.Tests
{
[TestFixture]
Expand All @@ -13,30 +16,39 @@ public class CodeDomEvalTests
[Test]
public void RandomSinCos()
{
Func<double, double> evalsin = new CodeDomEval("Math.Sin(x)").Calculate;
double sin(double x) => Math.Sin(x);
Func<double, double> evalcos = new CodeDomEval("Math.Cos(x)").Calculate;
Func<double, double> evalcos = new CodeDomEval("cos(x)").Calculate;
double cos(double x) => Math.Cos(x);
var r = new MyRandom();
for (var i = 0; i < 100; i++)
for (var i = 0; i < 10; i++)
{
var x = r.Next(100) * r.NextDouble();
Assert.AreEqual(sin(x), evalsin(x));
Assert.AreEqual(cos(x), evalcos(x));
}
}

[Test]
public void Random()
{
Func<double, double> f1 = new CodeDomEval("Math.Sin(x)*1/x*4383+2143/1414+141-1.2*23*x*Math.Abs(x*Math.Sin(x))").Calculate;
Func<double, double> f1 = new CodeDomEval("sin(x)*1/x*4383+2143/1414+141-1.2*23*x*Math.Abs(x*Math.Sin(x))").Calculate;
double f(double x) => Math.Sin(x) * 1 / x * 4383 + 2143 / 1414 + 141 - 1.2 * 23 * x * Math.Abs(x * Math.Sin(x));
var r = new MyRandom();
for (var i = 0; i < 1000; i++)
for (var i = 0; i < 100; i++)
{
var x = r.Next(100) * r.NextDouble();
Assert.AreEqual(f(x), f1(x), 1e-8);
}
}

[Test]
public void ReadmeTest()
{
var s = "sin(x)";
var c = new CodeDomEval(s);
Func<double, double> f = c.Calculate;
Assert.AreEqual(0, f(0), 1e-7);
Assert.AreEqual(1, f(Math.PI / 2), 1e-7);
Assert.AreEqual(0, f(Math.PI), 1e-7);
Assert.AreEqual(Math.Sqrt(2) / 2, f(Math.PI / 4), 1e-7);
}
}
}
23 changes: 23 additions & 0 deletions MyExpression.Core.Tests/FunctionEquationTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) 2018 Vladislav Prekel

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using NUnit.Framework;

namespace MyExpression.Core.Tests
{
[TestFixture]
public class FunctionEquationTests
{
[Test]
public void CustomTest()
{
var e1 = new FunctionEquation((x) => Math.Sin(x) * Math.Sin(x) * Math.Cos(x) / Math.Tan(x), new Interval(-5, 5), 1e-3, 1e-5);
e1.Solve();
}
}
}
25 changes: 25 additions & 0 deletions MyExpression.Core.Tests/LinearEquationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,30 @@ public void ParseTest_Random()
Assert.AreEqual(a, le.A);
Assert.AreEqual(b, le.B);
}

[Test]
public void ToStringTest()
{
var l = new LinearEquation(1, 1);
Assert.AreEqual("x+1", l.ToString());
l = new LinearEquation(0, 1);
Assert.AreEqual("1", l.ToString());
l = new LinearEquation(1, 0);
Assert.AreEqual("x", l.ToString());
l = new LinearEquation(-1, 0);
Assert.AreEqual("-x", l.ToString());
l = new LinearEquation(-1, -1);
Assert.AreEqual("-x-1", l.ToString());
l = new LinearEquation(2, 2);
Assert.AreEqual("2x+2", l.ToString());
l = new LinearEquation(0, 2);
Assert.AreEqual("2", l.ToString());
l = new LinearEquation(2, 0);
Assert.AreEqual("2x", l.ToString());
l = new LinearEquation(-2, 0);
Assert.AreEqual("-2x", l.ToString());
l = new LinearEquation(-2, -2);
Assert.AreEqual("-2x-2", l.ToString());
}
}
}
1 change: 1 addition & 0 deletions MyExpression.Core.Tests/MyExpression.Core.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
<ItemGroup>
<Compile Include="AssemblyInfo.cs" />
<Compile Include="CodeDomEvalTests.cs" />
<Compile Include="FunctionEquationTests.cs" />
<Compile Include="IntervalTests.cs" />
<Compile Include="OpenCloseIntervalTests.cs" />
<Compile Include="MyRandom.cs" />
Expand Down
64 changes: 23 additions & 41 deletions MyExpression.Core.Tests/PolynomialEquationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public void Cubic_Vieta_Dgt0_Random()
}

var p = new Polynomial(a, b, c, d);
var pe = new PolynomialEquation(p, 1e-9);
var pe = new PolynomialEquation(p, 1e-11);
pe.Solve();

Assert.AreEqual(3, pe.AllRoots.Count);
Expand Down Expand Up @@ -95,7 +95,7 @@ public void Cubic_Manual()

for (var i = 0; i < e.Count; i++)
{
var pe = new PolynomialEquation(new Polynomial(e[i]), 1e-9);
var pe = new PolynomialEquation(new Polynomial(e[i]), 1e-10);
pe.Solve();
for (var j = 0; j < pe.Roots.Count; j++)
{
Expand Down Expand Up @@ -125,7 +125,7 @@ public void Cubic_Int_Deq0_Random()
new Monomial(c, 1),
new Monomial(d, 0),
};
var pe = new PolynomialEquation(p, 1e-10);
var pe = new PolynomialEquation(p, 1e-11);
pe.Solve();

Assert.AreEqual(3, pe.AllRoots.Count);
Expand Down Expand Up @@ -158,7 +158,7 @@ public void Cubic_Int_Dlt0_Random()
new Monomial(c, 1),
new Monomial(d, 0),
};
var pe = new PolynomialEquation(p, 1e-9);
var pe = new PolynomialEquation(p, 1e-10);
pe.Solve();

Assert.AreEqual(1, pe.AllRoots.Count);
Expand Down Expand Up @@ -188,7 +188,7 @@ public void Cubic_Vieta_Dlt0_Random()
new Monomial(c, 1),
new Monomial(d, 0),
};
var pe = new PolynomialEquation(p, 1e-8);
var pe = new PolynomialEquation(p, 1e-9);
pe.Solve();

Assert.AreEqual(1, pe.AllRoots.Count);
Expand All @@ -197,40 +197,6 @@ public void Cubic_Vieta_Dlt0_Random()
Assert.AreEqual(0, p.Calculate(pe.Roots[0]), 1e-6);
}

//[Test]
//public void Cubic_Deq0_Random()
//{
// var r = new MyRandom();
// double a, b, c, d;
// while (true)
// {
// //a = 2 * r.NextDouble() * r.NextSign();
// a = 5 * r.NextDouble() * r.NextSign();
// b = 5 * r.NextDouble() * r.NextSign();
// c = 5 * r.NextDouble() * r.NextSign();
// d = 5 * r.NextDouble() * r.NextSign();
// if (Math.Abs(CubicDiscriminant(a, b, c, d)) < 1e-7 && Math.Abs(a) >= 1e-2) break;
// }

// var p = new Polynomial
// {
// new Monomial(a, 3),
// new Monomial(b, 2),
// new Monomial(c, 1),
// new Monomial(d, 0),
// };
// var pe = new PolynomialEquation(p, 1e-9);
// pe.Solve();

// Assert.AreEqual(3, pe.AllRoots.Count);
// Assert.IsTrue(new Interval(1, 2).IsInInterval(pe.Roots.Count), pe.Roots.Count.ToString());

// foreach (var i in pe.AllRoots)
// {
// Assert.AreEqual(0, p.Calculate(i), 1e-5);
// }
//}

[Test]
public void Cubic_Vieta_RootsToCoef_Random()
{
Expand All @@ -252,7 +218,7 @@ public void Cubic_Vieta_RootsToCoef_Random()
c = CubicVietaC(a, x);
d = CubicVietaD(a, x);
Assert.Greater(CubicDiscriminant(a, b, c, d), 0);
pe = new PolynomialEquation(new Polynomial(a, b, c, d), 1e-7);
pe = new PolynomialEquation(new Polynomial(a, b, c, d), 1e-9);
pe.Solve();
Assert.AreEqual(3, pe.AllRoots.Count);
Assert.AreEqual(3, pe.Roots.Count);
Expand Down Expand Up @@ -280,7 +246,7 @@ public void Cubic_Vieta_RootsToCoef_Random()
c = CubicVietaC(a, z);
d = CubicVietaD(a, z);
Assert.AreEqual(0, CubicDiscriminant(a, b, c, d));
pe = new PolynomialEquation(new Polynomial(a, b, c, d), 1e-6);
pe = new PolynomialEquation(new Polynomial(a, b, c, d), 1e-8);
pe.Solve();
Assert.AreEqual(3, pe.AllRoots.Count);
Assert.IsTrue(new Interval(1, 2).IsInInterval(pe.Roots.Count), pe.Roots.Count.ToString());
Expand All @@ -289,5 +255,21 @@ public void Cubic_Vieta_RootsToCoef_Random()
Assert.AreEqual(z[2], pe.AllRoots[2], 1e-5);
}
}

[Test]
public void ReadmeTest()
{
var s = "x^3-2x^2-x+2";
var eps = 1e-8;
var p = Polynomial.Parse(s);
var e = new PolynomialEquation(p, eps);
e.Solve();
Assert.AreEqual(-1, e.Roots[0], 1e-7);
Assert.AreEqual(0, p.Calculate(e.Roots[0]), 1e-7);
Assert.AreEqual(1, e.Roots[1], 1e-7);
Assert.AreEqual(0, p.Calculate(e.Roots[1]), 1e-7);
Assert.AreEqual(2, e.Roots[2], 1e-7);
Assert.AreEqual(0, p.Calculate(e.Roots[2]), 1e-7);
}
}
}
42 changes: 39 additions & 3 deletions MyExpression.Core/CodeDomEval.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,41 @@ public double Evaluate(double x)
}
}
}";
private string ReformExpression(string e)
{
var sb = new StringBuilder(e);
sb.Replace(" ", "");
sb.Replace("abs", "Math.Abs");
sb.Replace("acos", "Math.Acos");
sb.Replace("asin", "Math.Asin");
sb.Replace("atan", "Math.Atan");
sb.Replace("atan2", "Math.Atan2");
sb.Replace("bigmul", "Math.BigMul");
sb.Replace("ceiling", "Math.Ceiling");
sb.Replace("cos", "Math.Cos");
sb.Replace("cosh", "Math.Cosh");
sb.Replace("divrem", "Math.DivRem");
sb.Replace("e", "Math.E");
sb.Replace("exp", "Math.Exp");
sb.Replace("floor", "Math.Floor");
sb.Replace("ieeeremainder", "Math.IEEERemainder");
sb.Replace("log", "Math.Log");
sb.Replace("log10", "Math.Log10");
sb.Replace("max", "Math.Max");
sb.Replace("min", "Math.Min");
sb.Replace("pi", "Math.PI");
sb.Replace("pow", "Math.Pow");
sb.Replace("round", "Math.Round");
sb.Replace("sign", "Math.Sign");
sb.Replace("sin", "Math.Sin");
sb.Replace("sinh", "Math.Sinh");
sb.Replace("sqrt", "Math.Sqrt");
sb.Replace("tan", "Math.Tan");
sb.Replace("tanh", "Math.Tanh");
sb.Replace("truncate", "Math.Truncate");
return sb.ToString();
}

/// <summary>
/// Конструктор
/// </summary>
Expand All @@ -49,7 +84,8 @@ public CodeDomEval(string expression)
// Компиляция сборки с вычисляющим классом
var compilerParams = CreateCompilerParameters();
//var src = String.Format(SourceFormat, expression);
var src = SourceFormat.Replace("[|<expression>|]", expression);
var rfex = ReformExpression(expression);
var src = SourceFormat.Replace("[|<expression>|]", rfex);
CompilerResults = provider.CompileAssemblyFromSource(compilerParams, src);

if (CompilerResults.Errors.Count == 0)
Expand All @@ -62,9 +98,9 @@ public CodeDomEval(string expression)
// Сбор ошибок компиляции
foreach (CompilerError error in CompilerResults.Errors)
{
sb.Append(error.ErrorText + "\n");
sb.Append(error + "\n");
}
throw new Exception("Ошибка сборки\n" + sb);
throw new ApplicationException("Ошибка сборки\n" + sb);
}

if (!IsSuccessfulBuild) throw new Exception("Ошибка сборки");
Expand Down
Loading

0 comments on commit 007912b

Please sign in to comment.