public void AccuracyPerformanceTest_dim1() { //Create an ODE initial value problem ODEInitialValueProblem ivp = new ODEInitialValueProblem(1, 0.015625, 0); ExpressionParser parser = new ExpressionParser(); //1 dimensional first order nonlinear, nonhomogeneous, autonomous ivp.F.funcs[0] = parser.EvaluateExpression("-(y+1)*(y+3)").ToDelegate("t", "y"); ivp.SetState(new VectorND(-2.0), 0); //Solve the problem ivp.SolveTo(20); //Assess the error double error = 0; Func <double, double> actualSolution = (double tt) => { return(-3 + 2 * Math.Pow((1 + Math.Exp(-2 * tt)), -1)); }; double a = 1; //test error on [a,b] double b = 20; double htest = 1; //test at every this for (double t = a; t <= b; t += htest) { //Debug.Log("Estimated solution at t = " + t + ":" + ivp.SolutionData(0, t) //+ " ; versus Actual solution at t = " + t + ":" + actualSolution(t) //+ " ; Error = " + (ivp.SolutionData(0, t) - actualSolution(t))); error += Math.Abs(ivp.SolutionData(0, t) - actualSolution(t)); } //Test error against required total precision over the interval Assert.LessOrEqual(error, solution_total_error_benchmark * 20); }
public void SolutionData_OutOfBoundsNegative() { //Create an ODE initial value problem ODEInitialValueProblem ivp = new ODEInitialValueProblem(3, 0.2, 0); ExpressionParser parser = new ExpressionParser(); //Define a system in which the solution will be (3,4,5) at all times ivp.F.funcs[0] = parser.EvaluateExpression("0").ToDelegate("t"); ivp.F.funcs[1] = parser.EvaluateExpression("0").ToDelegate("t"); ivp.F.funcs[2] = parser.EvaluateExpression("0").ToDelegate("t"); ivp.SetState(new VectorND(3, 4, 5), 0); //Solve the problem ivp.SolveTo(3); //Check the solution data at t=25 where there is no data Assert.IsNaN(ivp.SolutionData(0, -1)); Assert.IsNaN(ivp.SolutionData(1, -1)); Assert.IsNaN(ivp.SolutionData(2, -1)); }
public void SolutionData_atUpperBound() { //Create an ODE initial value problem ODEInitialValueProblem ivp = new ODEInitialValueProblem(3, 0.2, 0); ExpressionParser parser = new ExpressionParser(); //Define a system in which the solution will be (3,4,5) at all times ivp.F.funcs[0] = parser.EvaluateExpression("0").ToDelegate("t"); ivp.F.funcs[1] = parser.EvaluateExpression("0").ToDelegate("t"); ivp.F.funcs[2] = parser.EvaluateExpression("0").ToDelegate("t"); ivp.SetState(new VectorND(3, 4, 5), 0); //Solve the problem ivp.SolveTo(3); //Check the solution data at t=3 Assert.AreEqual(3, ivp.SolutionData(0, 3), general_purpose_required_accuracy); Assert.AreEqual(4, ivp.SolutionData(1, 3), general_purpose_required_accuracy); Assert.AreEqual(5, ivp.SolutionData(2, 3), general_purpose_required_accuracy); }
public void AccuracyPerformanceTest_dim3() { //Create an ODE initial value problem ODEInitialValueProblem ivp = new ODEInitialValueProblem(3, 0.0001, 0); ExpressionParser parser = new ExpressionParser(); //3 dimensional first order linear non-homogenous non-autonomous ivp.F.funcs[0] = parser.EvaluateExpression("u1+2*u2-2*u3+e^(-t)").ToDelegate("t", "u1", "u2", "u3"); ivp.F.funcs[1] = parser.EvaluateExpression("u2+u3-2*e^(-t)").ToDelegate("t", "u1", "u2", "u3"); ivp.F.funcs[2] = parser.EvaluateExpression("u1+2*u2+e^(-t)").ToDelegate("t", "u1", "u2", "u3"); ivp.SetState(new VectorND(3, -1, 1), 0); //Solve the problem ivp.SolveTo(20); //Assess the error double error = 0; Func <double, VectorND> actualSolution = (double tt) => { VectorND r = new VectorND(3); r[0] = -3 * Math.Exp(-tt) - 3 * Math.Sin(tt) + 6 * Math.Cos(tt); r[1] = 1.5 * Math.Exp(-tt) + 0.3 * Math.Sin(tt) - 2.1 * Math.Cos(tt) - 0.4 * Math.Exp(2 * tt); r[2] = -Math.Exp(-tt) + 2.4 * Math.Cos(tt) + 1.8 * Math.Sin(tt) - 0.4 * Math.Exp(2 * tt); return(r); }; double a = 0; //test error on [a,b] double b = 1; double htest = 0.1; //test at every this for (double t = a; t <= b; t += htest) { error += Math.Abs(ivp.SolutionData(0, t) - actualSolution(t)[0]); error += Math.Abs(ivp.SolutionData(1, t) - actualSolution(t)[1]); error += Math.Abs(ivp.SolutionData(2, t) - actualSolution(t)[2]); } //Test error against required total precision over the interval Assert.LessOrEqual(error, solution_total_error_benchmark * 30); //3D * 10 points = 30 values }
//Updates the object's position public void UpdateObjectPosition() { //Some error checking, just in case. If error, simulation retains previous position. if ((currentTime < ivp.GetDataLowerBound()) || (currentTime > ivp.GetDataUpperBound())) { //if (!(paused)) Debug.Log("Data out of bounds error at time = " + currentTime + "; Available data is on [" + ivp.GetDataLowerBound() + ", " + ivp.GetDataUpperBound() + "]"); } else { if (!float.IsNaN((float)ivp.SolutionData(xIndex, currentTime)) && !float.IsNaN((float)ivp.SolutionData(yIndex, currentTime)) && !float.IsNaN((float)ivp.SolutionData(zIndex, currentTime)) && !float.IsInfinity((float)ivp.SolutionData(xIndex, currentTime)) && !float.IsInfinity((float)ivp.SolutionData(yIndex, currentTime)) && !float.IsInfinity((float)ivp.SolutionData(zIndex, currentTime))) { gameObject.transform.position = new Vector3( (float)ivp.SolutionData(xIndex, currentTime), (float)ivp.SolutionData(yIndex, currentTime), (float)ivp.SolutionData(zIndex, currentTime)); } } }