static void VerifyDifferentialEquations() { List <string> expressions = new List <string> { "2 * y1 - y + time * exp(time)", "y1" }; List <DEVariable> leftVariables = new List <DEVariable> { new DEVariable("y", 2), new DEVariable("y1", 1), }; DEVariable timeVariable = new DEVariable("time", 0); DifferentialEquationSystem.DifferentialEquationSystem differentialEquationSystem = new DifferentialEquationSystem.DifferentialEquationSystem(expressions, leftVariables, null, timeVariable, 1.5, 0.001); List <List <DEVariable> > perTime = new List <List <DEVariable> >(); double calcTime = 0; List <DEVariable> resultEuler; calcTime = differentialEquationSystem.Calculate(CalculationTypeName.Euler, out resultEuler, perTime); double calcTimeForecast = 0; List <List <DEVariable> > perTimeForecast = new List <List <DEVariable> >(); List <DEVariable> resultForecastCorrection; calcTimeForecast = differentialEquationSystem.Calculate(CalculationTypeName.ForecastCorrection, out resultForecastCorrection, perTimeForecast); double calcTimeRK2 = 0; List <List <DEVariable> > perTimeRK2 = new List <List <DEVariable> >(); List <DEVariable> resultRK2; calcTimeRK2 = differentialEquationSystem.Calculate(CalculationTypeName.RK2, out resultRK2, perTimeRK2); double calcTimeRK4 = 0; List <List <DEVariable> > perTimeRK4 = new List <List <DEVariable> >(); List <DEVariable> resultRK4; calcTimeRK4 = differentialEquationSystem.Calculate(CalculationTypeName.RK4, out resultRK4, perTimeRK4); double calcTimeAdams1 = 0; List <List <DEVariable> > perTimeAdams1 = new List <List <DEVariable> >(); List <DEVariable> resultAdams1; calcTimeAdams1 = differentialEquationSystem.Calculate(CalculationTypeName.AdamsExtrapolationOne, out resultAdams1, perTimeAdams1); double calcTimeAdams2 = 0; List <List <DEVariable> > perTimeAdams2 = new List <List <DEVariable> >(); List <DEVariable> resultAdams2; calcTimeAdams2 = differentialEquationSystem.Calculate(CalculationTypeName.AdamsExtrapolationTwo, out resultAdams2, perTimeAdams2); double calcTimeAdams3 = 0; List <List <DEVariable> > perTimeAdams3 = new List <List <DEVariable> >(); List <DEVariable> resultAdams3; calcTimeAdams3 = differentialEquationSystem.Calculate(CalculationTypeName.AdamsExtrapolationThree, out resultAdams3, perTimeAdams3); double calcTimeAdams4 = 0; List <List <DEVariable> > perTimeAdams4 = new List <List <DEVariable> >(); List <DEVariable> resultAdams4; calcTimeAdams4 = differentialEquationSystem.Calculate(CalculationTypeName.AdamsExtrapolationFour, out resultAdams4, perTimeAdams4); double calcTimeMiln = 0; List <List <DEVariable> > perTimeMiln = new List <List <DEVariable> >(); List <DEVariable> resultMiln; calcTimeMiln = differentialEquationSystem.Calculate(CalculationTypeName.Miln, out resultMiln, perTimeMiln); #region CalculateWithGroupOfMethodsSync List <CalculationTypeName> calculationTypes = new List <CalculationTypeName> { CalculationTypeName.Euler, CalculationTypeName.EulerAsyc, CalculationTypeName.ForecastCorrection, CalculationTypeName.ForecastCorrectionAsync, CalculationTypeName.RK2, CalculationTypeName.RK2Async, CalculationTypeName.RK4, CalculationTypeName.RK4Async, CalculationTypeName.AdamsExtrapolationOne, CalculationTypeName.AdamsExtrapolationOneAsync, CalculationTypeName.AdamsExtrapolationTwo, CalculationTypeName.AdamsExtrapolationTwoAsync, CalculationTypeName.AdamsExtrapolationThree, CalculationTypeName.AdamsExtrapolationThreeAsync, CalculationTypeName.AdamsExtrapolationFour, CalculationTypeName.AdamsExtrapolationFourAsync, CalculationTypeName.Miln, CalculationTypeName.MilnAsync }; Dictionary <CalculationTypeName, List <DEVariable> > results; Dictionary <CalculationTypeName, List <List <DEVariable> > > variablesAtAllSteps = new Dictionary <CalculationTypeName, List <List <DEVariable> > >(); Dictionary <CalculationTypeName, double> calcTimes = differentialEquationSystem.CalculateWithGroupOfMethodsSync(calculationTypes, out results, variablesAtAllSteps); Reporting.GenerateExcelReport(calculationTypes, calcTimes, results, variablesAtAllSteps, "csharp-Excel.xls", differentialEquationSystem); #endregion }
/// <summary> /// Generates the excel report for the results /// </summary> /// <param name="calculationTypes">List of calculation types for which it is required to generate a report</param> /// <param name="times">Calculation times for each calculation method</param> /// <param name="results">Results for each calculation method</param> /// <param name="allVariables">All variables results for each step of each calculation type</param> /// <param name="excelPath">A path, where the report document is supposed to be saved</param> public static void GenerateExcelReport(List <CalculationTypeName> calculationTypes, Dictionary <CalculationTypeName, double> times, Dictionary <CalculationTypeName, List <DEVariable> > results, Dictionary <CalculationTypeName, List <List <DEVariable> > > allVariables, string excelPath, DifferentialEquationSystem differentialEquationSystem) { Excel.Application xlApp = new Excel.Application(); if (xlApp == null) { throw new NullReferenceException("Excel is not properly installed!!"); } Excel.Workbook xlWorkbook = xlApp.Workbooks.Add(); // Adding variables per each steps for (int i = calculationTypes.Count - 1; i >= 0; i--) { Excel.Worksheet itemWorkSheet = (Excel.Worksheet)xlWorkbook.Worksheets.Add(); SetCalculationResults(itemWorkSheet, calculationTypes[i], differentialEquationSystem.LeftVariables, results[calculationTypes[i]], allVariables[calculationTypes[i]], times[calculationTypes[i]]); } // Generate common results when the amount of calculation times more than 1 if (calculationTypes.Count > 1) { Excel.Worksheet commonResultsWorksheet = (Excel.Worksheet)xlWorkbook.Worksheets.Add(); SetCommonResults(commonResultsWorksheet, times, results); } Excel.Worksheet initialXlWorkSheet = (Excel.Worksheet)xlWorkbook.Worksheets.Add(); SetInitalSheet(initialXlWorkSheet, calculationTypes, differentialEquationSystem.LeftVariables, differentialEquationSystem.TimeVariable, differentialEquationSystem.Tau, differentialEquationSystem.TEnd, differentialEquationSystem.ExpressionSystem); xlWorkbook.SaveAs(excelPath, Excel.XlFileFormat.xlWorkbookNormal); xlWorkbook.Close(); xlApp.Quit(); Marshal.ReleaseComObject(initialXlWorkSheet); Marshal.ReleaseComObject(xlWorkbook); Marshal.ReleaseComObject(xlApp); }
/// <summary> /// Method calculates a differential equation system with Extrapolation Adams One method /// </summary> /// <param name="variablesAtAllStep">Container where the intermediate parameters are supposed to be saved</param> /// <returns>List of result variables</returns> private List <DEVariable> AdamsExtrapolationOneSync(List <List <DEVariable> > variablesAtAllStep = null) { #region Calculation preparation List <Variable> allVars; List <Variable> currentLeftVariables = new List <Variable>(); List <Variable> nextLeftVariables = new List <Variable>(); // Copy this.LeftVariables to the current one and to the nex one // To leave this.LeftVariables member unchanged (for further calculations) DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, currentLeftVariables); DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, nextLeftVariables); // Setting of current time (to leave this.TimeVariable unchanged) Variable currentTime = new Variable(this.TimeVariable); // If it is required to save intermediate calculations - save the start values if (variablesAtAllStep != null) { // This is the first record for intermediate calculations containier // It has to be clear variablesAtAllStep.Clear(); DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, this.LeftVariables, currentTime); } #endregion #region First variables // Varables at "timestart + tau" is supposed to be calculated with other method // It was chosen to use Euler method // Generated a new instance for its calculation DifferentialEquationSystem differentialEquationSystem = new DifferentialEquationSystem(this.ExpressionSystem, this.LeftVariables, this.Constants, this.TimeVariable, this.TimeVariable.Value + this.Tau, this.Tau); // Calculation List <Variable> firstLeftVariables; differentialEquationSystem.Calculate(CalculationTypeName.Euler, out List <DEVariable> bufer); firstLeftVariables = DifferentialEquationSystemHelpers.ConvertDEVariablesToVariables(bufer); // Save the second variables calculated with Euler method if (variablesAtAllStep != null) { DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, firstLeftVariables, new Variable(currentTime.Name, currentTime.Value + this.Tau)); } #endregion allVars = DifferentialEquationSystemHelpers.CollectVariables(currentLeftVariables, this.Constants, currentTime); double[,] Q = new double[2, this.ExpressionSystem.Count]; for (int i = 0; i < this.ExpressionSystem.Count; i++) { Q[0, i] = this.Tau * this.ExpressionSystem[i].GetResultValue(allVars); } currentTime.Value += this.Tau; allVars = DifferentialEquationSystemHelpers.CollectVariables(firstLeftVariables, this.Constants, currentTime); for (int i = 0; i < this.ExpressionSystem.Count; i++) { Q[1, i] = this.Tau * this.ExpressionSystem[i].GetResultValue(allVars); } do { for (int i = 0; i < nextLeftVariables.Count; i++) { nextLeftVariables[i].Value = currentLeftVariables[i].Value + 0.5 * (3 * Q[1, i] - Q[0, i]); } allVars = DifferentialEquationSystemHelpers.CollectVariables(nextLeftVariables, this.Constants, new Variable(currentTime.Name, currentTime.Value + this.Tau)); for (int i = 0; i < nextLeftVariables.Count; i++) { Q[0, i] = Q[1, i]; Q[1, i] = this.Tau * this.ExpressionSystem[i].GetResultValue(allVars); } if (variablesAtAllStep != null) { DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, nextLeftVariables, new Variable(currentTime.Name, currentTime.Value + this.Tau)); } DifferentialEquationSystemHelpers.CopyVariables(nextLeftVariables, currentLeftVariables); // calculation time incrimentation currentTime.Value += this.Tau; } while (currentTime.Value < this.TEnd); List <DEVariable> result = new List <DEVariable>(); DifferentialEquationSystemHelpers.CopyVariables(currentLeftVariables, result); return(result); }
/// <summary> /// Sets the initial parameters of the DifferentialEquationSystem class. /// </summary> /// <param name="differentialEquationSystem">Input instance</param> public DifferentialEquationSystem(DifferentialEquationSystem differentialEquationSystem) : this(differentialEquationSystem.ExpressionSystem, differentialEquationSystem.LeftVariables, differentialEquationSystem.Constants, differentialEquationSystem.TimeVariable, differentialEquationSystem.TEnd, differentialEquationSystem.Tau) { }
/// <summary> /// Method calculates a differential equation system with Extrapolation Adams Three method /// </summary> /// <param name="variablesAtAllStep">Container where the intermediate parameters are supposed to be saved</param> /// <returns>List of result variables</returns> private List <DEVariable> AdamsExtrapolationThreeAsync(List <List <DEVariable> > variablesAtAllStep = null) { #region Calculation preparation List <Variable> allVars; List <Variable> currentLeftVariables = new List <Variable>(); List <Variable> nextLeftVariables = new List <Variable>(); // Copy this.LeftVariables to the current one and to the nex one // To leave this.LeftVariables member unchanged (for further calculations) DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, currentLeftVariables); DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, nextLeftVariables); // Setting of current time (to leave this.TimeVariable unchanged) Variable currentTime = new Variable(this.TimeVariable); // If it is required to save intermediate calculations - save the start values if (variablesAtAllStep != null) { // This is the first record for intermediate calculations containier // It has to be clear variablesAtAllStep.Clear(); DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, this.LeftVariables, currentTime); } #endregion #region First variables DifferentialEquationSystem differentialEquationSystem = new DifferentialEquationSystem(this.ExpressionSystem, this.LeftVariables, this.Constants, this.TimeVariable, this.TimeVariable.Value + 3 * this.Tau, this.Tau); List <List <DEVariable> > firstVariables = new List <List <DEVariable> >(); differentialEquationSystem.Calculate(CalculationTypeName.Euler, out List <DEVariable> bufer, firstVariables); List <Variable> firstLeftVariables; List <Variable> secondLeftVariables; List <Variable> thirdLeftVariables; firstLeftVariables = DifferentialEquationSystemHelpers.ConvertDEVariablesToVariables(firstVariables[1]); secondLeftVariables = DifferentialEquationSystemHelpers.ConvertDEVariablesToVariables(firstVariables[2]); thirdLeftVariables = DifferentialEquationSystemHelpers.ConvertDEVariablesToVariables(firstVariables[3]); firstLeftVariables.RemoveAt(firstLeftVariables.Count - 1); secondLeftVariables.RemoveAt(secondLeftVariables.Count - 1); thirdLeftVariables.RemoveAt(thirdLeftVariables.Count - 1); if (variablesAtAllStep != null) { DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, firstLeftVariables, new Variable(currentTime.Name, currentTime.Value + this.Tau)); DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, secondLeftVariables, new Variable(currentTime.Name, currentTime.Value + 2 * this.Tau)); DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, thirdLeftVariables, new Variable(currentTime.Name, currentTime.Value + 3 * this.Tau)); } #endregion double[,] Q = new double[4, this.ExpressionSystem.Count]; allVars = DifferentialEquationSystemHelpers.CollectVariables(currentLeftVariables, this.Constants, currentTime); Parallel.For(0, this.ExpressionSystem.Count, (i) => { Q[0, i] = this.Tau * this.ExpressionSystem[i].GetResultValue(allVars); }); currentTime.Value += this.Tau; allVars = DifferentialEquationSystemHelpers.CollectVariables(firstLeftVariables, this.Constants, currentTime); Parallel.For(0, this.ExpressionSystem.Count, (i) => { Q[1, i] = this.Tau * this.ExpressionSystem[i].GetResultValue(allVars); }); currentTime.Value += this.Tau; allVars = DifferentialEquationSystemHelpers.CollectVariables(secondLeftVariables, this.Constants, currentTime); Parallel.For(0, this.ExpressionSystem.Count, (i) => { Q[2, i] = this.Tau * this.ExpressionSystem[i].GetResultValue(allVars); }); currentTime.Value += this.Tau; allVars = DifferentialEquationSystemHelpers.CollectVariables(thirdLeftVariables, this.Constants, currentTime); Parallel.For(0, this.ExpressionSystem.Count, (i) => { Q[3, i] = this.Tau * this.ExpressionSystem[i].GetResultValue(allVars); }); DifferentialEquationSystemHelpers.CopyVariables(thirdLeftVariables, currentLeftVariables); do { Parallel.For(0, nextLeftVariables.Count, (i) => { nextLeftVariables[i].Value = currentLeftVariables[i].Value + 1.0 / 24 * (55 * Q[3, i] - 59 * Q[2, i] + 37 * Q[1, i] - 9 * Q[0, i]); }); allVars = DifferentialEquationSystemHelpers.CollectVariables(nextLeftVariables, this.Constants, new Variable(currentTime.Name, currentTime.Value + this.Tau)); Parallel.For(0, nextLeftVariables.Count, (i) => { Q[0, i] = Q[1, i]; Q[1, i] = Q[2, i]; Q[2, i] = Q[3, i]; Q[3, i] = this.Tau * this.ExpressionSystem[i].GetResultValue(allVars); }); if (variablesAtAllStep != null) { DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, nextLeftVariables, new Variable(currentTime.Name, currentTime.Value + this.Tau)); } DifferentialEquationSystemHelpers.CopyVariables(nextLeftVariables, currentLeftVariables); currentTime.Value += this.Tau; } while (currentTime.Value < this.TEnd); List <DEVariable> result = new List <DEVariable>(); DifferentialEquationSystemHelpers.CopyVariables(currentLeftVariables, result); return(result); }
/// <summary> /// Method calculates a differential equation system with Miln method /// </summary> /// <param name="variablesAtAllStep">Container where the intermediate parameters are supposed to be saved</param> /// <returns>List of result variables</returns> private List <DEVariable> MilnSync(List <List <DEVariable> > variablesAtAllStep = null) { #region Calculation preparation List <Variable> allVars; List <Variable> currentLeftVariables = new List <Variable>(); List <Variable> milnPredicted = new List <Variable>(); List <Variable> nextLeftVariables = new List <Variable>(); // Copy this.LeftVariables to the current one and to the nex one // To leave this.LeftVariables member unchanged (for further calculations) DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, currentLeftVariables); DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, milnPredicted); DifferentialEquationSystemHelpers.CopyVariables(this.LeftVariables, nextLeftVariables); // Setting of current time (to leave this.TimeVariable unchanged) Variable currentTime = new Variable(this.TimeVariable); // If it is required to save intermediate calculations - save the start values if (variablesAtAllStep != null) { // This is the first record for intermediate calculations containier // It has to be clear variablesAtAllStep.Clear(); DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, this.LeftVariables, currentTime); } #endregion #region First variables DifferentialEquationSystem differentialEquationSystem = new DifferentialEquationSystem(this.ExpressionSystem, this.LeftVariables, this.Constants, this.TimeVariable, this.TimeVariable.Value + 3 * this.Tau, this.Tau); List <List <DEVariable> > firstVariables = new List <List <DEVariable> >(); List <DEVariable> bufer; differentialEquationSystem.Calculate(CalculationTypeName.Euler, out bufer, firstVariables); List <Variable> firstLeftVariables; List <Variable> secondLeftVariables; List <Variable> thirdLeftVariables; firstLeftVariables = DifferentialEquationSystemHelpers.ConvertDEVariablesToVariables(firstVariables[1]); secondLeftVariables = DifferentialEquationSystemHelpers.ConvertDEVariablesToVariables(firstVariables[2]); thirdLeftVariables = DifferentialEquationSystemHelpers.ConvertDEVariablesToVariables(firstVariables[3]); firstLeftVariables.RemoveAt(firstLeftVariables.Count - 1); secondLeftVariables.RemoveAt(secondLeftVariables.Count - 1); thirdLeftVariables.RemoveAt(thirdLeftVariables.Count - 1); if (variablesAtAllStep != null) { DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, firstLeftVariables, new Variable(currentTime.Name, currentTime.Value + this.Tau)); DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, secondLeftVariables, new Variable(currentTime.Name, currentTime.Value + 2 * this.Tau)); DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, thirdLeftVariables, new Variable(currentTime.Name, currentTime.Value + 3 * this.Tau)); } #endregion double[,] Q = new double[4, this.ExpressionSystem.Count]; double[,] prevValues = new double[4, this.ExpressionSystem.Count]; allVars = DifferentialEquationSystemHelpers.CollectVariables(currentLeftVariables, this.Constants, currentTime); for (int i = 0; i < this.ExpressionSystem.Count; i++) { Q[0, i] = this.ExpressionSystem[i].GetResultValue(allVars); prevValues[0, i] = currentLeftVariables[i].Value; } currentTime.Value += this.Tau; allVars = DifferentialEquationSystemHelpers.CollectVariables(firstLeftVariables, this.Constants, currentTime); for (int i = 0; i < this.ExpressionSystem.Count; i++) { Q[1, i] = this.ExpressionSystem[i].GetResultValue(allVars); prevValues[1, i] = firstLeftVariables[i].Value; } currentTime.Value += this.Tau; allVars = DifferentialEquationSystemHelpers.CollectVariables(secondLeftVariables, this.Constants, currentTime); for (int i = 0; i < this.ExpressionSystem.Count; i++) { Q[2, i] = this.ExpressionSystem[i].GetResultValue(allVars); prevValues[2, i] = secondLeftVariables[i].Value; } currentTime.Value += this.Tau; allVars = DifferentialEquationSystemHelpers.CollectVariables(thirdLeftVariables, this.Constants, currentTime); for (int i = 0; i < this.ExpressionSystem.Count; i++) { Q[3, i] = this.ExpressionSystem[i].GetResultValue(allVars); prevValues[3, i] = thirdLeftVariables[i].Value; } DifferentialEquationSystemHelpers.CopyVariables(thirdLeftVariables, currentLeftVariables); do { for (int i = 0; i < milnPredicted.Count; i++) { milnPredicted[i].Value = prevValues[0, i] + 4 * this.Tau / 3 * (2 * Q[1, i] - Q[2, i] + 2 * Q[3, i]); } double[] predictedValues = new double[milnPredicted.Count]; allVars = DifferentialEquationSystemHelpers.CollectVariables(milnPredicted, this.Constants, new Variable(currentTime.Name, currentTime.Value + this.Tau)); for (int i = 0; i < predictedValues.Length; i++) { predictedValues[i] = this.ExpressionSystem[i].GetResultValue(allVars); } for (int i = 0; i < nextLeftVariables.Count; i++) { nextLeftVariables[i].Value = prevValues[2, i] + this.Tau / 3 * (Q[2, i] + 4 * this.ExpressionSystem[i].GetResultValue(DifferentialEquationSystemHelpers.CollectVariables(currentLeftVariables, this.Constants, currentTime)) + predictedValues[i]); } allVars = DifferentialEquationSystemHelpers.CollectVariables(nextLeftVariables, this.Constants, new Variable(currentTime.Name, currentTime.Value + this.Tau)); for (int i = 0; i < nextLeftVariables.Count; i++) { Q[0, i] = Q[1, i]; Q[1, i] = Q[2, i]; Q[2, i] = Q[3, i]; Q[3, i] = this.ExpressionSystem[i].GetResultValue(allVars); prevValues[0, i] = prevValues[1, i]; prevValues[1, i] = prevValues[2, i]; prevValues[2, i] = prevValues[3, i]; prevValues[3, i] = nextLeftVariables[i].Value; } if (variablesAtAllStep != null) { DifferentialEquationSystemHelpers.SaveLeftVariableToStatistics(variablesAtAllStep, nextLeftVariables, new Variable(currentTime.Name, currentTime.Value + this.Tau)); } DifferentialEquationSystemHelpers.CopyVariables(nextLeftVariables, currentLeftVariables); currentTime.Value += this.Tau; } while (currentTime.Value < this.TEnd); List <DEVariable> result = new List <DEVariable>(); DifferentialEquationSystemHelpers.CopyVariables(currentLeftVariables, result); return(result); }