public static T Switch <T>( this CorrectorIteratorMethod iteratorMethod, Func <T> onFunctional, Func <T> onChordWithUserJacobian, Func <T> onChordWithGeneratedJacobian, Func <T> onChordWithDiagonalJacobian, Func <T> onChordWithBandedUserJacobian, Func <T> onChordWithBandedGeneratedJacobian ) => iteratorMethod == Functional?onFunctional() : iteratorMethod == ChordWithUserJacobian?onChordWithUserJacobian() : iteratorMethod == ChordWithGeneratedJacobian?onChordWithGeneratedJacobian() : iteratorMethod == ChordWithDiagonalJacobian?onChordWithDiagonalJacobian() : iteratorMethod == ChordWithBandedUserJacobian?onChordWithBandedUserJacobian() : iteratorMethod == ChordWithBandedGeneratedJacobian?onChordWithBandedGeneratedJacobian() : throw CorrectorIteratorMethod.ToInvalidDataException(iteratorMethod);
static void RunDLSODE(int numberOfEquations, SolutionMethod solutionMethod, CorrectorIteratorMethod iteratorMethod) { Console.WriteLine("Calling DLSODE..."); SolverParams getChordWithDiagonalJacobianSolver() => new(new ChordWithDiagonalJacobianSolver(numberOfEquations, solutionMethod), GetInitialValues(numberOfEquations)) { StartTime = StartTime, EndTime = EndTime, }; SolverParams getFunctionalSolver() => new(new FunctionalSolver(numberOfEquations, solutionMethod), GetInitialValues(numberOfEquations)) { StartTime = StartTime, EndTime = EndTime, }; SolverParams throwNotSupported() => throw new NotSupportedException($"Iterator method: {iteratorMethod} is not supported."); var solverParam = iteratorMethod.Switch( onFunctional: getFunctionalSolver, onChordWithUserJacobian: throwNotSupported, onChordWithGeneratedJacobian: throwNotSupported, onChordWithDiagonalJacobian: getChordWithDiagonalJacobianSolver, onChordWithBandedUserJacobian: throwNotSupported, onChordWithBandedGeneratedJacobian: throwNotSupported); SolverResult solverResult; var sw = new Stopwatch(); sw.Start(); unsafe { solverResult = OdeSolver.Run(solverParam, FImpl2); } var elapsed = sw.Elapsed; OutputResults(solverResult, elapsed); }
/// <summary> /// F# workaround version due to: /// System.InvalidProgramException: Common Language Runtime detected an invalid program /// issue. /// </summary> public static T RunFSharp <T>( Func <F> creator, int solutionMethodKey, int correctorIteratorMethodKey, double tStart, double tEnd, double[] initialValues, Func <SolverResult, TimeSpan, T> resultMapper, double[] absoluteTolerance, double[] relativeTolerance) { unsafe { var f = creator(); var solutionMethod = SolutionMethod.TryCreate(solutionMethodKey) ?? throw new InvalidDataException($"Invalid key of solution method: {solutionMethodKey}"); var iteratorMethod = CorrectorIteratorMethod.TryCreate(correctorIteratorMethodKey) ?? throw new InvalidDataException($"Invalid key of corrector iterator method: {correctorIteratorMethodKey}"); SolverParams getChordWithDiagonalJacobianSolver() => new( new ChordWithDiagonalJacobianSolver(initialValues.Length, solutionMethod), initialValues, absoluteTolerance, relativeTolerance) { StartTime = tStart, EndTime = tEnd, }; SolverParams getFunctionalSolver() => new( new FunctionalSolver(initialValues.Length, solutionMethod), initialValues, absoluteTolerance, relativeTolerance) { StartTime = tStart, EndTime = tEnd, }; SolverParams throwNotSupported() => throw new NotSupportedException($"Iterator method: {iteratorMethod} is not supported."); var solverParams = iteratorMethod.Switch( onFunctional: getFunctionalSolver, onChordWithUserJacobian: throwNotSupported, onChordWithGeneratedJacobian: throwNotSupported, onChordWithDiagonalJacobian: getChordWithDiagonalJacobianSolver, onChordWithBandedUserJacobian: throwNotSupported, onChordWithBandedGeneratedJacobian: throwNotSupported); var sw = new Stopwatch(); sw.Start(); var result = Run(solverParams, f); var output = resultMapper(result, sw.Elapsed); return(output); } }