Interpolation (WIP)#4
Interpolation (WIP)#4joris997 merged 7 commits intojoris997:interpolationfrom adamkewley:interpolation
Conversation
|
This is still work-in-progress. I need to see if it's actually as correct as the original implementation (the algorithm is the same, but it has been majorly refactored). However, anecdotally, it does seem to be a little bit (~30 %) faster: Before (from here): After: Again, though, I need to ensure that it's actually correct. |
|
I fixed a few edge-case bugs that pop up in real simulations (e.g. What can happen is that the real coordinate value falls out of The other thing that was changed was the default number of discretization points. In addition, the implementation has been hard-coded to only handling paths with up to The The test suite now has a new test that collects all the datapoints from a PBP and and FBP into two I noticed the derivative implementation isn't continuous. Rather, it takes the value two nearby points and performs discrete derivatization. The reason I mention this is because that implementation doubles the amount of computation (the derivative is asked for a lot at runtime). It also causes weird runtime bugs if |
|
I've committed the code I developed as-is, @joris997 , so you'll need to remove the hardcoded paths. The script I'm using to test accuracy is: import pandas
import matplotlib
import matplotlib.pyplot as plt
df = pandas.read_csv("datatable.tsv", sep="\t", index_col=0)
df.plot()
plt.show()Which requires |
This is still a WIP, but hopefully will clean up + accelerate the implementation. Changes:
.osimfileosimfile now contains the evaluations, rather than some external filefinalizeFromPropertiesandfinalizeConnectionsphases of the model, because they used to rely on loading external files, which can fail if (e.g.) the model is copied in-memory (and, therefore, has no backing file from which the parent directory can be computed) or if the model file is opened by a GUI running in a different working directory (which requires careful handling of the current working directory during the finalization phase, which causes other bugs)generateDecorations) now warn once per application bootgenerateDecorationsrepeatably would have its log spammed with the same warning messageFunctionBasedPath::FittingParamsstructChanged signature of
FunctionBasedPath::fromPointBasedPathto return astd::unique_ptr<FunctionBasedPath>rather than aFunctionBasedPath(and also, so that it takes theFittingParams, above)nullptr, which the caller can handle as "can't fit"FittingParamsto limit how "far" the fitting implementation should go. E.g. if it's known that some muscles are affected by many coordinates, it's probably best to leave it as aPointBasedPath(this is likely to be the case for larger models)Refactored the algorithm to maximize performance + readability:
getInterpDer-->Impl_GetPathLengthDerivative,getInterp-->Impl_GetPathLength)dS-->discretizations,n-->closestDiscretizationSteps)g_MaxCoordsThatCanBeInterpolated)Interpolation. Many of them can be computed on-the-fly by the CPU (e.g. `gridsize == (discretization.end-discretization.start)/(discretization.steps-1)). Most of these datastructures are now created + populated at runtime in stack-based arrays that have no allocation overheadv = begin + n*stepSize(solved forn)acc += x*y) inside loops withstd::fma(e.g.acc = std::fma(x, y, acc);). This reduces error propagation when accumulating small values onto larger values in a loop (e.g.z += beta*v)perfandvalgrind. This mostly involved doing things like switchingpowcalls for in-source equivalents (e.g.pow(frac, 2)-->frac*frac). Some compilers do not optimizepow(yet)