1 downside is that the API for ManifoldProjection will become a bit more verbose, because we are no longer solving a singular root-finding problem (which NLsolve does with pinv IIRC). Instead for in place problems we have to specify resid_prototype, no such restriction for OOP g (yes those are supported now!!).
If the internal solver fails, we terminate the solution process, unlike before where we just keep going.
Initial Benchmarks
For the first test in manifold_tests.jl
# Old Version
julia> @benchmark sol = solve(prob, Vern7(), callback = cb)
BenchmarkTools.Trial: 1054 samples with 1 evaluation.
Range (min … max): 4.466 ms … 12.455 ms ┊ GC (min … max): 0.00% … 59.69%
Time (median): 4.633 ms ┊ GC (median): 0.00%
Time (mean ± σ): 4.744 ms ± 745.682 μs ┊ GC (mean ± σ): 1.74% ± 6.35%
▄█▁
███▇▃▃▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▂▂ ▂
4.47 ms Histogram: frequency by time 10.6 ms <
Memory estimate: 1.02 MiB, allocs estimate: 10444.
# This PR
julia> @benchmark sol = solve(prob, Vern7(), callback = cb)
BenchmarkTools.Trial: 6087 samples with 1 evaluation.
Range (min … max): 558.404 μs … 3.089 ms ┊ GC (min … max): 0.00% … 54.91%
Time (median): 599.674 μs ┊ GC (median): 0.00%
Time (mean ± σ): 817.805 μs ± 392.500 μs ┊ GC (mean ± σ): 24.21% ± 23.11%
▇█▇▄▃▁ ▁▂▃▃▃▃▃▃▃▂▂▂▂▁▂▁ ▂
█████████▆▅▅▃▃▅▄▁▅▃▃▃▅▁▁▁▁▁▁▁▁▁▁▁▁▁▁▄▄██████████████████▆▇▆▆▆ █
558 μs Histogram: log(frequency) by time 1.75 ms <
Memory estimate: 11.68 MiB, allocs estimate: 11297.
1 downside is that the API for
ManifoldProjection
will become a bit more verbose, because we are no longer solving a singular root-finding problem (which NLsolve does withpinv
IIRC). Instead for in place problems we have to specifyresid_prototype
, no such restriction for OOPg
(yes those are supported now!!).If the internal solver fails, we terminate the solution process, unlike before where we just keep going.
Initial Benchmarks
For the first test in
manifold_tests.jl