I just went through the SciML tutorials and now am trying to apply them by building a calculator for solving the compound interest equation. I have two working implementations, but neither seems very convenient. What is the best way to implement this model so that I can plug in all but one variable and solve for whichever one is missing?
I initially used just NonlinearSolve.jl directly. I wrote a function that steps sequentially through time. I then wrote a wrapper function to isolate the variable I wanted to solve for. Then I constructed an
IntervalNonlinearProblem and solved.
The issues here are that …
- The results overshot in whole year steps because of the steps in my
- I have to write a new wrapper function and
IntervalNonlinearProblemfor every variable. (Not implemented.)
Code for First Implementation
using NonlinearSolve """ finalvalue(; P=0, M=0, A=0, r=8, t=1) -> F Calculate the final value of an investment assuming interest is compounded monthly. # Arguments - `F`: final value (after `t` years) - `P`: principal value (before interest) - `M`: regular monthly contibution - `A`: regular annual contibution - `r`: annual interest rate (%) - `t`: total number of years """ function finalvalue(; P=0, M=0, A=0, r=8, t=1) r /= 100 # convert percent to decimal F = P # starting value for _ in 1:t for _ in 1:12 F *= 1 + r/12 # apply monthly interest F += M # add monthly contribution end F += A # add annual contribution end return round(F, digits=2) end function findt(t, p) P = p M = p A = p r = p F = p return finalvalue(; P, M, A, r, t) - F end p = [5000, 100, 0, 8, 14900] tspan = (0.0, 10.0) prob = IntervalNonlinearProblem(findt, tspan, p) t = round(solve(prob).u, digits=2)
Next I found and modeled the equation with ModelingToolkit.This resulted in better accuracy and smaller code. However,
- The only type that seemed applicable is a
NonlinearSystem, so I have to wrap everything in vectors.
- I could not figure out how to create an
NonlinearSystem, so I am using a
NonlinearProbleminstead. This seems like the wrong type of problem based on what I read in the docs.
- I don’t know how to switch which variables are
@variablesand which are
@parameterswithout copying and pasting the entire code over and over and tweaking it. I know of the
remakefunction, but that seems to only be able to change values not variables.
Code for Second Implementation
using ModelingToolkit, NonlinearSolve @variables t @parameters F P A r n eq = [F ~ P * (1 + r/100/n)^(n*t) + A * ((1 + r/100/n)^(n*t) - 1) / (r/100/n)] @named ns = NonlinearSystem(eq, [t], [F, P, A, r, n]) prob = NonlinearProblem(ns, , [F=>15000, P=>5000, A=>100, r=>8, n=>12]) sol = round(only(solve(prob).u), digits=2)