OpenSim
OpenSim 3.1
|
This class contains the quintic Bezier curves, x(u) and y(u), that have been created by SmoothSegmentedFunctionFactory to follow a physiologically meaningful muscle characteristic. More...
#include <SmoothSegmentedFunction.h>
Public Member Functions | |
SmoothSegmentedFunction () | |
The default constructor, which populates the member data fields with NaN's. | |
double | calcValue (double x) const |
Calculates the value of the curve this object represents. | |
double | calcDerivative (double x, int order) const |
Calculates the value of the derivative of the curve this object represents. | |
double | calcIntegral (double x) const |
This will return the value of the integral of this objects curve evaluated at x. | |
bool | isIntegralAvailable () const |
Returns a bool that indicates if the integral curve has been computed. | |
bool | isIntegralComputedLeftToRight () const |
Returns a bool that indicates if the integral computed is compuated left to right, or right to left. | |
std::string | getName () const |
Returns a string that is the name for this curve, which is set at the time of construction and cannot be changed after construction. | |
void | setName (std::string &name) |
SimTK::Vec2 | getCurveDomain () const |
This function returns a SimTK::Vec2 that contains in its 0th element the lowest value of the curve domain, and in its 1st element the highest value in the curve domain of the curve. | |
void | printMuscleCurveToCSVFile (const std::string &path, double domainMin, double domainMax) const |
This function will generate a csv file (of 'name_curveName.csv', where name is the one used in the constructor) of the muscle curve, and 'curveName' corresponds to the function that was called from SmoothSegmentedFunctionFactory to create the curve. |
Friends | |
class | SmoothSegmentedFunctionFactory |
No human should be constructing a SmoothSegmentedFunction, so the constructor is made private so that mere mortals cannot look at it. |
This class contains the quintic Bezier curves, x(u) and y(u), that have been created by SmoothSegmentedFunctionFactory to follow a physiologically meaningful muscle characteristic.
A SmoothSegmentedFunction cannot be created directly, you must use SmoothSegmentedFunctionFactory to create the muscle curve of interest.
Future Upgrades 1. Add a hint object to keep the last u that corresponded to the location of interest to prevent unnecessary redundant evaluations of u. This hint could be similar in form to the used by the SimTK::BicubicSurface class
Computational Cost Details All computational costs assume the following operation costs:
Operation Type : #flops +,-,=,Boolean Op : 1 / : 10 sqrt: 20 trig: 40
These relative weightings will vary processor to processor, and so any of the quoted computational costs are approximate.
OpenSim::SmoothSegmentedFunction::SmoothSegmentedFunction | ( | ) |
The default constructor, which populates the member data fields with NaN's.
double OpenSim::SmoothSegmentedFunction::calcDerivative | ( | double | x, |
int | order | ||
) | const |
Calculates the value of the derivative of the curve this object represents.
x | The domain point of interest. |
order | The order of the derivative to compute. Note that order must be between 0 and 2. Calling 0 just calls calcValue. |
OpenSim::Exception | -If anything but 0's are stored in derivComponents -If more than the 6th derivative is asked for -If ax has a size other than 1 |
Computational Costs
x in curve domain : ~391 flops x in linear section: ~2 flops
double OpenSim::SmoothSegmentedFunction::calcIntegral | ( | double | x | ) | const |
This will return the value of the integral of this objects curve evaluated at x.
x | the domain point of interest |
OpenSim::Exception | -If the function does not have a pre-computed integral |
The integral is approximate, though its errors are small. The integral is computed by numerically integrating the function when the constructor for this class is called (if computeIntegral is true) and then splining the result, thus the regions between the knot points may have some error in them. A very fine mesh of points is used to create the spline so the errors will be small
Computational Costs
x in curve domain : ~13 flops x in linear section: ~19 flops
double OpenSim::SmoothSegmentedFunction::calcValue | ( | double | x | ) | const |
Calculates the value of the curve this object represents.
x | The domain point of interest |
OpenSim::Exception | -If ax does not have a size of 1 |
The curve is parameterized as a set of Bezier curves. If x is within the domain of these Bezier curves they will be evaluated. If x is outside of the domain of these Bezier curves a linear extrapolation will be evalulated
Computational Costs
x in curve domain : ~282 flops x in linear section: ~5 flops
SimTK::Vec2 OpenSim::SmoothSegmentedFunction::getCurveDomain | ( | ) | const |
This function returns a SimTK::Vec2 that contains in its 0th element the lowest value of the curve domain, and in its 1st element the highest value in the curve domain of the curve.
Outside of this domain the curve is approximated using linear extrapolation.
std::string OpenSim::SmoothSegmentedFunction::getName | ( | ) | const |
Returns a string that is the name for this curve, which is set at the time of construction and cannot be changed after construction.
bool OpenSim::SmoothSegmentedFunction::isIntegralAvailable | ( | ) | const |
Returns a bool that indicates if the integral curve has been computed.
bool OpenSim::SmoothSegmentedFunction::isIntegralComputedLeftToRight | ( | ) | const |
Returns a bool that indicates if the integral computed is compuated left to right, or right to left.
void OpenSim::SmoothSegmentedFunction::printMuscleCurveToCSVFile | ( | const std::string & | path, |
double | domainMin, | ||
double | domainMax | ||
) | const |
This function will generate a csv file (of 'name_curveName.csv', where name is the one used in the constructor) of the muscle curve, and 'curveName' corresponds to the function that was called from SmoothSegmentedFunctionFactory to create the curve.
path | The full path to the location. Note '/' slashes must be used, and do not put a '/' after the last folder. |
domainMin | the left most domain point of the curve to print. The curve will extend to at least this point. |
domainMax | the right most domain point of the curve to print. The printed curve will extend at least to this point, perhaps beyond. |
OpenSim::Exception | -If the filename is empty |
For example the tendon curve for a muscle named 'glutmax' will be:
'glutmax_tendonForceLengthCurve.csv'
The file will contain the following columns:
Col# 1, 2, 3, 4, 5 x, y, dy/dx, d2y/dx2, iy
Where iy is the integral of y(x). If the curve has been set not to have an integral, this column will not exist.
The curve will be sampled from its linear extrapolation region, through the curve, out to the other linear extrapolation region. The width of each linear extrapolation region is 10% of the entire range of x, or 0.1*(x1-x0).
The number of rows used will vary from curve to curve. Each quintic Bezier curve section will have 100 samples. Each linearily extrapolated region will have 10 samples each. Some muscle curves (the tendon, parallel elements, compressive elements) consist of only 1 elbow, and so these matrices will have only 100+20 rows. The force velocity curve is made up of 2 elbows and will have 200+20 rows. The active force length curve has 5 elbows, and so its sampled matrix will have 500+20 rows
Computational Costs This varies depending on the curve (as mentioned above).
~97,400 to 487,000 flops
Example To read the csv file with a header in from Matlab, you need to use csvread set so that it will ignore the header row. This is accomplished by using the extra two numerical arguments for csvread to tell the function to begin reading from the 1st row, and the 0th index (csvread is 0 indexed).
data=csvread('test_tendonForceLengthCurve.csv',1,0);
void OpenSim::SmoothSegmentedFunction::setName | ( | std::string & | name | ) |
|
friend |
No human should be constructing a SmoothSegmentedFunction, so the constructor is made private so that mere mortals cannot look at it.
SmoothSegmentedFunctionFactory should be used to create MuscleCurveFunctions and that's why its a friend