
    \h                     V   S r SSKJr  SSKJr  SSKJrJr  SSKJ	r	J
r
  SSKJrJr  SSKJrJr  SSKJr  SS	KJr  / S
Qr " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r\" SS9 " S S5      5       rg) zBImplementations of characteristic curves for musculotendon models.    )	dataclass)UnevaluatedExpr)ArgumentIndexErrorFunction)FloatInteger)explog)coshsinh)sqrt)
PRECEDENCE)	CharacteristicCurveCollectionCharacteristicCurveFunction"FiberForceLengthActiveDeGroote2016#FiberForceLengthPassiveDeGroote2016*FiberForceLengthPassiveInverseDeGroote2016FiberForceVelocityDeGroote2016%FiberForceVelocityInverseDeGroote2016TendonForceLengthDeGroote2016$TendonForceLengthInverseDeGroote2016c                   Z    \ rS rSrSr\S 5       rS r\r\r	\r
\r\r\r\r\r\r\r\rSrg)r      z@Base class for all musculotendon characteristic curve functions.c                 :    SU R                   < S3n[        U5      e)NzCannot directly instantiate zD, instances of characteristic curves must be of a concrete subclass.)__name__	TypeError)clsmsgs     X/var/www/auris/envauris/lib/python3.13/site-packages/sympy/physics/biomechanics/curve.pyeval CharacteristicCurveFunction.eval   s-     +3<<*: ;D E 	
 n    c           	      n    UR                  UR                  U R                  SSS9[        S   5      5      $ )a  Print code for the function defining the curve using a printer.

Explanation
===========

The order of operations may need to be controlled as constant folding
the numeric terms within the equations of a musculotendon
characteristic curve can sometimes results in a numerically-unstable
expression.

Parameters
==========

printer : Printer
    The printer to be used to print a string representation of the
    characteristic curve as valid code in the target language.

FdeepevaluateAtom)_printparenthesizedoitr   )selfprinters     r   _print_code'CharacteristicCurveFunction._print_code'   s9    & ~~g22II55I1:f3E
  	r"    N)r   
__module____qualname____firstlineno____doc__classmethodr    r-   _ccode	_cupycode_cxxcode_fcode_jaxcode_lambdacode_mpmathcode_octave_pythoncode
_numpycode
_scipycode__static_attributes__r/   r"   r   r   r      sU    J . FIHFHKKGKJJr"   r   c                   b    \ rS rSrSr\S 5       r\S 5       rS rSS jr	SS jr
SS jrS	 rS
rg)r   K   a  Tendon force-length curve based on De Groote et al., 2016 [1]_.

Explanation
===========

Gives the normalized tendon force produced as a function of normalized
tendon length.

The function is defined by the equation:

$fl^T = c_0 \exp{c_3 \left( \tilde{l}^T - c_1 \right)} - c_2$

with constant values of $c_0 = 0.2$, $c_1 = 0.995$, $c_2 = 0.25$, and
$c_3 = 33.93669377311689$.

While it is possible to change the constant values, these were carefully
selected in the original publication to give the characteristic curve
specific and required properties. For example, the function produces no
force when the tendon is in an unstrained state. It also produces a force
of 1 normalized unit when the tendon is under a 5% strain.

Examples
========

The preferred way to instantiate :class:`TendonForceLengthDeGroote2016` is using
the :meth:`~.with_defaults` constructor because this will automatically
populate the constants within the characteristic curve equation with the
floating point values from the original publication. This constructor takes
a single argument corresponding to normalized tendon length. We'll create a
:class:`~.Symbol` called ``l_T_tilde`` to represent this.

>>> from sympy import Symbol
>>> from sympy.physics.biomechanics import TendonForceLengthDeGroote2016
>>> l_T_tilde = Symbol('l_T_tilde')
>>> fl_T = TendonForceLengthDeGroote2016.with_defaults(l_T_tilde)
>>> fl_T
TendonForceLengthDeGroote2016(l_T_tilde, 0.2, 0.995, 0.25,
33.93669377311689)

It's also possible to populate the four constants with your own values too.

>>> from sympy import symbols
>>> c0, c1, c2, c3 = symbols('c0 c1 c2 c3')
>>> fl_T = TendonForceLengthDeGroote2016(l_T_tilde, c0, c1, c2, c3)
>>> fl_T
TendonForceLengthDeGroote2016(l_T_tilde, c0, c1, c2, c3)

You don't just have to use symbols as the arguments, it's also possible to
use expressions. Let's create a new pair of symbols, ``l_T`` and
``l_T_slack``, representing tendon length and tendon slack length
respectively. We can then represent ``l_T_tilde`` as an expression, the
ratio of these.

>>> l_T, l_T_slack = symbols('l_T l_T_slack')
>>> l_T_tilde = l_T/l_T_slack
>>> fl_T = TendonForceLengthDeGroote2016.with_defaults(l_T_tilde)
>>> fl_T
TendonForceLengthDeGroote2016(l_T/l_T_slack, 0.2, 0.995, 0.25,
33.93669377311689)

To inspect the actual symbolic expression that this function represents,
we can call the :meth:`~.doit` method on an instance. We'll use the keyword
argument ``evaluate=False`` as this will keep the expression in its
canonical form and won't simplify any constants.

>>> fl_T.doit(evaluate=False)
-0.25 + 0.2*exp(33.93669377311689*(l_T/l_T_slack - 0.995))

The function can also be differentiated. We'll differentiate with respect
to l_T using the ``diff`` method on an instance with the single positional
argument ``l_T``.

>>> fl_T.diff(l_T)
6.787338754623378*exp(33.93669377311689*(l_T/l_T_slack - 0.995))/l_T_slack

References
==========

.. [1] De Groote, F., Kinney, A. L., Rao, A. V., & Fregly, B. J., Evaluation
       of direct collocation optimal control problem formulations for
       solving the muscle redundancy problem, Annals of biomedical
       engineering, 44(10), (2016) pp. 2922-2936

c                 n    [        S5      n[        S5      n[        S5      n[        S5      nU " XX4U5      $ )a  Recommended constructor that will use the published constants.

Explanation
===========

Returns a new instance of the tendon force-length function using the
four constant values specified in the original publication.

These have the values:

$c_0 = 0.2$
$c_1 = 0.995$
$c_2 = 0.25$
$c_3 = 33.93669377311689$

Parameters
==========

l_T_tilde : Any (sympifiable)
    Normalized tendon length.

0.20.9950.2533.93669377311689r   r   	l_T_tildec0c1c2c3s         r   with_defaults+TendonForceLengthDeGroote2016.with_defaults   s9    0 5\7^6]&'9""--r"   c                     g)aL  Evaluation of basic inputs.

Parameters
==========

l_T_tilde : Any (sympifiable)
    Normalized tendon length.
c0 : Any (sympifiable)
    The first constant in the characteristic equation. The published
    value is ``0.2``.
c1 : Any (sympifiable)
    The second constant in the characteristic equation. The published
    value is ``0.995``.
c2 : Any (sympifiable)
    The third constant in the characteristic equation. The published
    value is ``0.25``.
c3 : Any (sympifiable)
    The fourth constant in the characteristic equation. The published
    value is ``33.93669377311689``.

Nr/   rI   s         r   r    "TendonForceLengthDeGroote2016.eval       . 	r"   c                 @    U R                  SSS9R                  U5      $ z4Evaluate the expression numerically using ``evalf``.Fr$   r*   _eval_evalfr+   precs     r   rW   )TendonForceLengthDeGroote2016._eval_evalf        yyeey4@@FFr"   c                 6   U R                   tpEU(       a@  X#S'   UR                  " SSU0UD6nU Vs/ s H  ofR                  " SSU0UD6PM     snu  pxpOUu  pxpU(       a  U[        XU-
  -  5      -  U	-
  $ U[        U
[        XH-
  5      -  5      -  U	-
  $ s  snf ]  Evaluate the expression defining the function.

Parameters
==========

deep : bool
    Whether ``doit`` should be recursively called. Default is ``True``.
evaluate : bool.
    Whether the SymPy expression should be evaluated as it is
    constructed. If ``False``, then no constant folding will be
    conducted which will leave the expression in a more numerically-
    stable for values of ``l_T_tilde`` that correspond to a sensible
    operating range for a musculotendon. Default is ``True``.
**kwargs : dict[str, Any]
    Additional keyword argument pairs to be recursively passed to
    ``doit``.

r&   r%   r/   argsr*   r	   r   )r+   r%   r&   hintsrJ   	constantscrK   rL   rM   rN   s              r   r*   "TendonForceLengthDeGroote2016.doit   s    & !%			 (*!:D:E:IBKL)Qff8$8%8)LNBB&NBBc""n-..33#b8899B>> M   Bc                 z   U R                   u  p#pEnUS:X  a  X6-  [        U[        X$-
  5      -  5      -  $ US:X  a  [        U[        X$-
  5      -  5      $ US:X  a   U* U-  [        U[        X$-
  5      -  5      -  $ US:X  a  [        S5      $ US:X  a!  X2U-
  -  [        U[        X$-
  5      -  5      -  $ [	        X5      e  Derivative of the function with respect to a single argument.

Parameters
==========

argindex : int
    The index of the function's arguments with respect to which the
    derivative should be taken. Argument indexes start at ``1``.
    Default is ``1``.

               )r`   r	   r   r   r   )r+   argindexrJ   rK   rL   rM   rN   s          r   fdiff#TendonForceLengthDeGroote2016.fdiff   s     %)II!	rrq=5R	 ??@@@]r/).99::]3r6#b!@@AAA]2;]2~&s2oin.M+M'NNN 00r"   c                     [         $ zzInverse function.

Parameters
==========

argindex : int
    Value to start indexing the arguments at. Default is ``1``.

)r   r+   ro   s     r   inverse%TendonForceLengthDeGroote2016.inverse  s
     43r"   c                 L    U R                   S   nUR                  U5      nSU-  $ )Print a LaTeX representation of the function defining the curve.

Parameters
==========

printer : Printer
    The printer to be used to print the LaTeX string representation.

r   z%\operatorname{fl}^T \left( %s \right)r`   r(   )r+   r,   rJ   
_l_T_tildes       r   _latex$TendonForceLengthDeGroote2016._latex"  *     IIaL	^^I.
7*DDr"   r/   NTTri   r   r0   r1   r2   r3   r4   rO   r    rW   r*   rp   ru   r{   r@   r/   r"   r   r   r   K   sM    Sj . .:  0G?@14
4Er"   r   c                   b    \ rS rSrSr\S 5       r\S 5       rS rSS jr	SS jr
SS jrS	 rS
rg)r   i1  a
  Inverse tendon force-length curve based on De Groote et al., 2016 [1]_.

Explanation
===========

Gives the normalized tendon length that produces a specific normalized
tendon force.

The function is defined by the equation:

${fl^T}^{-1} = frac{\log{\frac{fl^T + c_2}{c_0}}}{c_3} + c_1$

with constant values of $c_0 = 0.2$, $c_1 = 0.995$, $c_2 = 0.25$, and
$c_3 = 33.93669377311689$. This function is the exact analytical inverse
of the related tendon force-length curve ``TendonForceLengthDeGroote2016``.

While it is possible to change the constant values, these were carefully
selected in the original publication to give the characteristic curve
specific and required properties. For example, the function produces no
force when the tendon is in an unstrained state. It also produces a force
of 1 normalized unit when the tendon is under a 5% strain.

Examples
========

The preferred way to instantiate :class:`TendonForceLengthInverseDeGroote2016` is
using the :meth:`~.with_defaults` constructor because this will automatically
populate the constants within the characteristic curve equation with the
floating point values from the original publication. This constructor takes
a single argument corresponding to normalized tendon force-length, which is
equal to the tendon force. We'll create a :class:`~.Symbol` called ``fl_T`` to
represent this.

>>> from sympy import Symbol
>>> from sympy.physics.biomechanics import TendonForceLengthInverseDeGroote2016
>>> fl_T = Symbol('fl_T')
>>> l_T_tilde = TendonForceLengthInverseDeGroote2016.with_defaults(fl_T)
>>> l_T_tilde
TendonForceLengthInverseDeGroote2016(fl_T, 0.2, 0.995, 0.25,
33.93669377311689)

It's also possible to populate the four constants with your own values too.

>>> from sympy import symbols
>>> c0, c1, c2, c3 = symbols('c0 c1 c2 c3')
>>> l_T_tilde = TendonForceLengthInverseDeGroote2016(fl_T, c0, c1, c2, c3)
>>> l_T_tilde
TendonForceLengthInverseDeGroote2016(fl_T, c0, c1, c2, c3)

To inspect the actual symbolic expression that this function represents,
we can call the :meth:`~.doit` method on an instance. We'll use the keyword
argument ``evaluate=False`` as this will keep the expression in its
canonical form and won't simplify any constants.

>>> l_T_tilde.doit(evaluate=False)
c1 + log((c2 + fl_T)/c0)/c3

The function can also be differentiated. We'll differentiate with respect
to l_T using the ``diff`` method on an instance with the single positional
argument ``l_T``.

>>> l_T_tilde.diff(fl_T)
1/(c3*(c2 + fl_T))

References
==========

.. [1] De Groote, F., Kinney, A. L., Rao, A. V., & Fregly, B. J., Evaluation
       of direct collocation optimal control problem formulations for
       solving the muscle redundancy problem, Annals of biomedical
       engineering, 44(10), (2016) pp. 2922-2936

c                 n    [        S5      n[        S5      n[        S5      n[        S5      nU " XX4U5      $ )a  Recommended constructor that will use the published constants.

Explanation
===========

Returns a new instance of the inverse tendon force-length function
using the four constant values specified in the original publication.

These have the values:

$c_0 = 0.2$
$c_1 = 0.995$
$c_2 = 0.25$
$c_3 = 33.93669377311689$

Parameters
==========

fl_T : Any (sympifiable)
    Normalized tendon force as a function of tendon length.

rD   rE   rF   rG   rH   r   fl_TrK   rL   rM   rN   s         r   rO   2TendonForceLengthInverseDeGroote2016.with_defaults|  s9    0 5\7^6]&'4RR((r"   c                     g)ae  Evaluation of basic inputs.

Parameters
==========

fl_T : Any (sympifiable)
    Normalized tendon force as a function of tendon length.
c0 : Any (sympifiable)
    The first constant in the characteristic equation. The published
    value is ``0.2``.
c1 : Any (sympifiable)
    The second constant in the characteristic equation. The published
    value is ``0.995``.
c2 : Any (sympifiable)
    The third constant in the characteristic equation. The published
    value is ``0.25``.
c3 : Any (sympifiable)
    The fourth constant in the characteristic equation. The published
    value is ``33.93669377311689``.

Nr/   r   s         r   r    )TendonForceLengthInverseDeGroote2016.eval  rS   r"   c                 @    U R                  SSS9R                  U5      $ rU   rV   rX   s     r   rW   0TendonForceLengthInverseDeGroote2016._eval_evalf  r[   r"   c                 6   U R                   tpEU(       a@  X#S'   UR                  " SSU0UD6nU Vs/ s H  ofR                  " SSU0UD6PM     snu  pxpOUu  pxpU(       a  [        XI-   U-  5      U
-  U-   $ [        [        XI-   U-  5      5      U
-  U-   $ s  snf r]   )r`   r*   r
   r   )r+   r%   r&   ra   r   rb   rc   rK   rL   rM   rN   s              r   r*   )TendonForceLengthInverseDeGroote2016.doit  s    &  99 (*990$0%0DBKL)Qff8$8%8)LNBB&NBB	2~&r)B..?DIr>23B6;; Mre   c                     U R                   u  p#pEnUS:X  a
  SXbU-   -  -  $ US:X  a  SX6-  -  $ US:X  a  [        S5      $ US:X  a
  SXbU-   -  -  $ US:X  a   [        [        X%-   U-  5      5      * US-  -  $ [	        X5      e)rh   ri   rj   rm   rk   rl   rn   )r`   r   r
   r   r   )r+   ro   r   rK   rL   rM   rN   s          r   rp   *TendonForceLengthInverseDeGroote2016.fdiff  s      $yy""q=b)n%%]ru:]1:]b)n%%]B788Q>> 00r"   c                     [         $ rs   )r   rt   s     r   ru   ,TendonForceLengthInverseDeGroote2016.inverse  s
     -,r"   c                 L    U R                   S   nUR                  U5      nSU-  $ )rx   r   z9\left( \operatorname{fl}^T \right)^{-1} \left( %s \right)ry   )r+   r,   r   _fl_Ts       r   r{   +TendonForceLengthInverseDeGroote2016._latex  *     yy|t$KeSSr"   r/   Nr~   r   r   r/   r"   r   r   r   1  sM    HT ) ):  0G<@14
-Tr"   r   c                   b    \ rS rSrSr\S 5       r\S 5       rS rSS jr	SS jr
SS jrS	 rS
rg)r   i  a  Passive muscle fiber force-length curve based on De Groote et al., 2016
[1]_.

Explanation
===========

The function is defined by the equation:

$fl^M_{pas} = \frac{\frac{\exp{c_1 \left(\tilde{l^M} - 1\right)}}{c_0} - 1}{\exp{c_1} - 1}$

with constant values of $c_0 = 0.6$ and $c_1 = 4.0$.

While it is possible to change the constant values, these were carefully
selected in the original publication to give the characteristic curve
specific and required properties. For example, the function produces a
passive fiber force very close to 0 for all normalized fiber lengths
between 0 and 1.

Examples
========

The preferred way to instantiate :class:`FiberForceLengthPassiveDeGroote2016` is
using the :meth:`~.with_defaults` constructor because this will automatically
populate the constants within the characteristic curve equation with the
floating point values from the original publication. This constructor takes
a single argument corresponding to normalized muscle fiber length. We'll
create a :class:`~.Symbol` called ``l_M_tilde`` to represent this.

>>> from sympy import Symbol
>>> from sympy.physics.biomechanics import FiberForceLengthPassiveDeGroote2016
>>> l_M_tilde = Symbol('l_M_tilde')
>>> fl_M = FiberForceLengthPassiveDeGroote2016.with_defaults(l_M_tilde)
>>> fl_M
FiberForceLengthPassiveDeGroote2016(l_M_tilde, 0.6, 4.0)

It's also possible to populate the two constants with your own values too.

>>> from sympy import symbols
>>> c0, c1 = symbols('c0 c1')
>>> fl_M = FiberForceLengthPassiveDeGroote2016(l_M_tilde, c0, c1)
>>> fl_M
FiberForceLengthPassiveDeGroote2016(l_M_tilde, c0, c1)

You don't just have to use symbols as the arguments, it's also possible to
use expressions. Let's create a new pair of symbols, ``l_M`` and
``l_M_opt``, representing muscle fiber length and optimal muscle fiber
length respectively. We can then represent ``l_M_tilde`` as an expression,
the ratio of these.

>>> l_M, l_M_opt = symbols('l_M l_M_opt')
>>> l_M_tilde = l_M/l_M_opt
>>> fl_M = FiberForceLengthPassiveDeGroote2016.with_defaults(l_M_tilde)
>>> fl_M
FiberForceLengthPassiveDeGroote2016(l_M/l_M_opt, 0.6, 4.0)

To inspect the actual symbolic expression that this function represents,
we can call the :meth:`~.doit` method on an instance. We'll use the keyword
argument ``evaluate=False`` as this will keep the expression in its
canonical form and won't simplify any constants.

>>> fl_M.doit(evaluate=False)
0.0186573603637741*(-1 + exp(6.66666666666667*(l_M/l_M_opt - 1)))

The function can also be differentiated. We'll differentiate with respect
to l_M using the ``diff`` method on an instance with the single positional
argument ``l_M``.

>>> fl_M.diff(l_M)
0.12438240242516*exp(6.66666666666667*(l_M/l_M_opt - 1))/l_M_opt

References
==========

.. [1] De Groote, F., Kinney, A. L., Rao, A. V., & Fregly, B. J., Evaluation
       of direct collocation optimal control problem formulations for
       solving the muscle redundancy problem, Annals of biomedical
       engineering, 44(10), (2016) pp. 2922-2936

c                 @    [        S5      n[        S5      nU " XU5      $ )at  Recommended constructor that will use the published constants.

Explanation
===========

Returns a new instance of the muscle fiber passive force-length
function using the four constant values specified in the original
publication.

These have the values:

$c_0 = 0.6$
$c_1 = 4.0$

Parameters
==========

l_M_tilde : Any (sympifiable)
    Normalized muscle fiber length.

0.64.0rH   r   	l_M_tilderK   rL   s       r   rO   1FiberForceLengthPassiveDeGroote2016.with_defaults]  s#    . 5\5\9"%%r"   c                     g)a\  Evaluation of basic inputs.

Parameters
==========

l_M_tilde : Any (sympifiable)
    Normalized muscle fiber length.
c0 : Any (sympifiable)
    The first constant in the characteristic equation. The published
    value is ``0.6``.
c1 : Any (sympifiable)
    The second constant in the characteristic equation. The published
    value is ``4.0``.

Nr/   r   s       r   r    (FiberForceLengthPassiveDeGroote2016.evalx      " 	r"   c                 @    U R                  SSS9R                  U5      $ rU   rV   rX   s     r   rW   /FiberForceLengthPassiveDeGroote2016._eval_evalf  r[   r"   c                 p   U R                   tpEU(       a?  X#S'   UR                  " SSU0UD6nU Vs/ s H  ofR                  " SSU0UD6PM     snu  pxOUu  pxU(       a%  [        XS-
  -  U-  5      S-
  [        U5      S-
  -  $ [        U[        US-
  5      -  U-  5      S-
  [        U5      S-
  -  $ s  snf r^   r&   r%   ri   r/   r_   )	r+   r%   r&   ra   r   rb   rc   rK   rL   s	            r   r*   (FiberForceLengthPassiveDeGroote2016.doit  s    & !%			 (*!:D:E:I:CD)Qff0$0%0)DFBFB]+R/014s2w{CCR	A66:;a?#b'A+NN Es   B3c           	      2   U R                   u  p#nUS:X  a2  U[        U[        US-
  5      -  U-  5      -  U[        U5      S-
  -  -  $ US:X  aE  U* [        U[        US-
  5      -  U-  5      -  [        US-
  5      -  US-  [        U5      S-
  -  -  $ US:X  au  [        U5      * S[        U[        US-
  5      -  U-  5      -   -  [        U5      S-
  S-  -  [        U[        US-
  5      -  U-  5      US-
  -  U[        U5      S-
  -  -  -   $ [        X5      e)rh   ri   rj   rk   rm   )r`   r	   r   r   )r+   ro   r   rK   rL   s        r   rp   )FiberForceLengthPassiveDeGroote2016.fdiff  sB    !II	rq=c"_Y];;B>??SWq[AQRR]C?9q=99"<== Q/013QB!1DF ]R"s2oi!m&D#DR#GHHI3r7UV;YZJZZbQ77:;Y]KRQTUWQX[\Q\M]^_
 !00r"   c                     [         $ rs   )r   rt   s     r   ru   +FiberForceLengthPassiveDeGroote2016.inverse  s
     :9r"   c                 L    U R                   S   nUR                  U5      nSU-  $ )rx   r   z+\operatorname{fl}^M_{pas} \left( %s \right)ry   r+   r,   r   
_l_M_tildes       r   r{   *FiberForceLengthPassiveDeGroote2016._latex  *     IIaL	^^I.
=
JJr"   r/   Nr~   r   r   r/   r"   r   r   r     sN    N` & &4  $GO@18
:Kr"   r   c                   b    \ rS rSrSr\S 5       r\S 5       rS rSS jr	SS jr
SS jrS	 rS
rg)r   i  a!  Inverse passive muscle fiber force-length curve based on De Groote et
al., 2016 [1]_.

Explanation
===========

Gives the normalized muscle fiber length that produces a specific normalized
passive muscle fiber force.

The function is defined by the equation:

${fl^M_{pas}}^{-1} = \frac{c_0 \log{\left(\exp{c_1} - 1\right)fl^M_pas + 1}}{c_1} + 1$

with constant values of $c_0 = 0.6$ and $c_1 = 4.0$. This function is the
exact analytical inverse of the related tendon force-length curve
``FiberForceLengthPassiveDeGroote2016``.

While it is possible to change the constant values, these were carefully
selected in the original publication to give the characteristic curve
specific and required properties. For example, the function produces a
passive fiber force very close to 0 for all normalized fiber lengths
between 0 and 1.

Examples
========

The preferred way to instantiate
:class:`FiberForceLengthPassiveInverseDeGroote2016` is using the
:meth:`~.with_defaults` constructor because this will automatically populate the
constants within the characteristic curve equation with the floating point
values from the original publication. This constructor takes a single
argument corresponding to the normalized passive muscle fiber length-force
component of the muscle fiber force. We'll create a :class:`~.Symbol` called
``fl_M_pas`` to represent this.

>>> from sympy import Symbol
>>> from sympy.physics.biomechanics import FiberForceLengthPassiveInverseDeGroote2016
>>> fl_M_pas = Symbol('fl_M_pas')
>>> l_M_tilde = FiberForceLengthPassiveInverseDeGroote2016.with_defaults(fl_M_pas)
>>> l_M_tilde
FiberForceLengthPassiveInverseDeGroote2016(fl_M_pas, 0.6, 4.0)

It's also possible to populate the two constants with your own values too.

>>> from sympy import symbols
>>> c0, c1 = symbols('c0 c1')
>>> l_M_tilde = FiberForceLengthPassiveInverseDeGroote2016(fl_M_pas, c0, c1)
>>> l_M_tilde
FiberForceLengthPassiveInverseDeGroote2016(fl_M_pas, c0, c1)

To inspect the actual symbolic expression that this function represents,
we can call the :meth:`~.doit` method on an instance. We'll use the keyword
argument ``evaluate=False`` as this will keep the expression in its
canonical form and won't simplify any constants.

>>> l_M_tilde.doit(evaluate=False)
c0*log(1 + fl_M_pas*(exp(c1) - 1))/c1 + 1

The function can also be differentiated. We'll differentiate with respect
to fl_M_pas using the ``diff`` method on an instance with the single positional
argument ``fl_M_pas``.

>>> l_M_tilde.diff(fl_M_pas)
c0*(exp(c1) - 1)/(c1*(fl_M_pas*(exp(c1) - 1) + 1))

References
==========

.. [1] De Groote, F., Kinney, A. L., Rao, A. V., & Fregly, B. J., Evaluation
       of direct collocation optimal control problem formulations for
       solving the muscle redundancy problem, Annals of biomedical
       engineering, 44(10), (2016) pp. 2922-2936

c                 @    [        S5      n[        S5      nU " XU5      $ )a  Recommended constructor that will use the published constants.

Explanation
===========

Returns a new instance of the inverse muscle fiber passive force-length
function using the four constant values specified in the original
publication.

These have the values:

$c_0 = 0.6$
$c_1 = 4.0$

Parameters
==========

fl_M_pas : Any (sympifiable)
    Normalized passive muscle fiber force as a function of muscle fiber
    length.

r   r   rH   r   fl_M_pasrK   rL   s       r   rO   8FiberForceLengthPassiveInverseDeGroote2016.with_defaults2  s#    0 5\5\8$$r"   c                     g)ab  Evaluation of basic inputs.

Parameters
==========

fl_M_pas : Any (sympifiable)
    Normalized passive muscle fiber force.
c0 : Any (sympifiable)
    The first constant in the characteristic equation. The published
    value is ``0.6``.
c1 : Any (sympifiable)
    The second constant in the characteristic equation. The published
    value is ``4.0``.

Nr/   r   s       r   r    /FiberForceLengthPassiveInverseDeGroote2016.evalN  r   r"   c                 @    U R                  SSS9R                  U5      $ rU   rV   rX   s     r   rW   6FiberForceLengthPassiveInverseDeGroote2016._eval_evalfa  r[   r"   c           	      r   U R                   tpEU(       a?  X#S'   UR                  " SSU0UD6nU Vs/ s H  ofR                  " SSU0UD6PM     snu  pxOUu  pxU(       a&  U[        U[        U5      S-
  -  S-   5      -  U-  S-   $ U[        [	        U[        U5      S-
  -  5      S-   5      -  U-  S-   $ s  snf r   )r`   r*   r
   r	   r   )	r+   r%   r&   ra   r   rb   rc   rK   rL   s	            r   r*   /FiberForceLengthPassiveInverseDeGroote2016.doite  s    &  $yy (*}}8$8%8H:CD)Qff0$0%0)DFBFBc(CGaK01455b81<<#ohB!&<=ABB2EII Es   B4c                    U R                   u  p#nUS:X  a(  U[        U5      S-
  -  XB[        U5      S-
  -  S-   -  -  $ US:X  a   [        U[        U5      S-
  -  S-   5      U-  $ US:X  aN  X2-  [        U5      -  XB[        U5      S-
  -  S-   -  -  U[        U[        U5      S-
  -  S-   5      -  US-  -  -
  $ [        X5      e)rh   ri   rj   rk   )r`   r	   r
   r   )r+   ro   r   rK   rL   s        r   rp   0FiberForceLengthPassiveInverseDeGroote2016.fdiff  s      99bq=s2w{#R3r7Q;)?!)C%DEE]xR1-12255]CG#R3r7Q;)?!)C%DES3r7Q;/!344RU:;
 !00r"   c                     [         $ rs   )r   rt   s     r   ru   2FiberForceLengthPassiveInverseDeGroote2016.inverse  s
     32r"   c                 L    U R                   S   nUR                  U5      nSU-  $ )rx   r   z?\left( \operatorname{fl}^M_{pas} \right)^{-1} \left( %s \right)ry   )r+   r,   r   	_fl_M_pass       r   r{   1FiberForceLengthPassiveInverseDeGroote2016._latex  s+     99Q<NN8,	QT]]]r"   r/   Nr~   r   r   r/   r"   r   r   r     sN    IV % %6  $GJ@12
3^r"   r   c                   X    \ rS rSrSr\S 5       r\S 5       rS rSS jr	SS jr
S rS	rg
)r   i  a  Active muscle fiber force-length curve based on De Groote et al., 2016
[1]_.

Explanation
===========

The function is defined by the equation:

$fl_{\text{act}}^M = c_0 \exp\left(-\frac{1}{2}\left(\frac{\tilde{l}^M - c_1}{c_2 + c_3 \tilde{l}^M}\right)^2\right)
+ c_4 \exp\left(-\frac{1}{2}\left(\frac{\tilde{l}^M - c_5}{c_6 + c_7 \tilde{l}^M}\right)^2\right)
+ c_8 \exp\left(-\frac{1}{2}\left(\frac{\tilde{l}^M - c_9}{c_{10} + c_{11} \tilde{l}^M}\right)^2\right)$

with constant values of $c0 = 0.814$, $c1 = 1.06$, $c2 = 0.162$,
$c3 = 0.0633$, $c4 = 0.433$, $c5 = 0.717$, $c6 = -0.0299$, $c7 = 0.2$,
$c8 = 0.1$, $c9 = 1.0$, $c10 = 0.354$, and $c11 = 0.0$.

While it is possible to change the constant values, these were carefully
selected in the original publication to give the characteristic curve
specific and required properties. For example, the function produces a
active fiber force of 1 at a normalized fiber length of 1, and an active
fiber force of 0 at normalized fiber lengths of 0 and 2.

Examples
========

The preferred way to instantiate :class:`FiberForceLengthActiveDeGroote2016` is
using the :meth:`~.with_defaults` constructor because this will automatically
populate the constants within the characteristic curve equation with the
floating point values from the original publication. This constructor takes
a single argument corresponding to normalized muscle fiber length. We'll
create a :class:`~.Symbol` called ``l_M_tilde`` to represent this.

>>> from sympy import Symbol
>>> from sympy.physics.biomechanics import FiberForceLengthActiveDeGroote2016
>>> l_M_tilde = Symbol('l_M_tilde')
>>> fl_M = FiberForceLengthActiveDeGroote2016.with_defaults(l_M_tilde)
>>> fl_M
FiberForceLengthActiveDeGroote2016(l_M_tilde, 0.814, 1.06, 0.162, 0.0633,
0.433, 0.717, -0.0299, 0.2, 0.1, 1.0, 0.354, 0.0)

It's also possible to populate the two constants with your own values too.

>>> from sympy import symbols
>>> c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11 = symbols('c0:12')
>>> fl_M = FiberForceLengthActiveDeGroote2016(l_M_tilde, c0, c1, c2, c3,
...     c4, c5, c6, c7, c8, c9, c10, c11)
>>> fl_M
FiberForceLengthActiveDeGroote2016(l_M_tilde, c0, c1, c2, c3, c4, c5, c6,
c7, c8, c9, c10, c11)

You don't just have to use symbols as the arguments, it's also possible to
use expressions. Let's create a new pair of symbols, ``l_M`` and
``l_M_opt``, representing muscle fiber length and optimal muscle fiber
length respectively. We can then represent ``l_M_tilde`` as an expression,
the ratio of these.

>>> l_M, l_M_opt = symbols('l_M l_M_opt')
>>> l_M_tilde = l_M/l_M_opt
>>> fl_M = FiberForceLengthActiveDeGroote2016.with_defaults(l_M_tilde)
>>> fl_M
FiberForceLengthActiveDeGroote2016(l_M/l_M_opt, 0.814, 1.06, 0.162, 0.0633,
0.433, 0.717, -0.0299, 0.2, 0.1, 1.0, 0.354, 0.0)

To inspect the actual symbolic expression that this function represents,
we can call the :meth:`~.doit` method on an instance. We'll use the keyword
argument ``evaluate=False`` as this will keep the expression in its
canonical form and won't simplify any constants.

>>> fl_M.doit(evaluate=False)
0.814*exp(-(l_M/l_M_opt
- 1.06)**2/(2*(0.0633*l_M/l_M_opt + 0.162)**2))
+ 0.433*exp(-(l_M/l_M_opt - 0.717)**2/(2*(0.2*l_M/l_M_opt - 0.0299)**2))
+ 0.1*exp(-3.98991349867535*(l_M/l_M_opt - 1.0)**2)

The function can also be differentiated. We'll differentiate with respect
to l_M using the ``diff`` method on an instance with the single positional
argument ``l_M``.

>>> fl_M.diff(l_M)
((-0.79798269973507*l_M/l_M_opt
+ 0.79798269973507)*exp(-3.98991349867535*(l_M/l_M_opt - 1.0)**2)
+ (0.433*(-l_M/l_M_opt + 0.717)/(0.2*l_M/l_M_opt - 0.0299)**2
+ 0.0866*(l_M/l_M_opt - 0.717)**2/(0.2*l_M/l_M_opt
- 0.0299)**3)*exp(-(l_M/l_M_opt - 0.717)**2/(2*(0.2*l_M/l_M_opt - 0.0299)**2))
+ (0.814*(-l_M/l_M_opt + 1.06)/(0.0633*l_M/l_M_opt
+ 0.162)**2 + 0.0515262*(l_M/l_M_opt
- 1.06)**2/(0.0633*l_M/l_M_opt
+ 0.162)**3)*exp(-(l_M/l_M_opt
- 1.06)**2/(2*(0.0633*l_M/l_M_opt + 0.162)**2)))/l_M_opt

References
==========

.. [1] De Groote, F., Kinney, A. L., Rao, A. V., & Fregly, B. J., Evaluation
       of direct collocation optimal control problem formulations for
       solving the muscle redundancy problem, Annals of biomedical
       engineering, 44(10), (2016) pp. 2922-2936

c                 &   [        S5      n[        S5      n[        S5      n[        S5      n[        S5      n[        S5      n[        S5      n[        S5      n	[        S	5      n
[        S
5      n[        S5      n[        S5      nU " XX4XVXxXXU5      $ )a'  Recommended constructor that will use the published constants.

Explanation
===========

Returns a new instance of the inverse muscle fiber act force-length
function using the four constant values specified in the original
publication.

These have the values:

$c0 = 0.814$
$c1 = 1.06$
$c2 = 0.162$
$c3 = 0.0633$
$c4 = 0.433$
$c5 = 0.717$
$c6 = -0.0299$
$c7 = 0.2$
$c8 = 0.1$
$c9 = 1.0$
$c10 = 0.354$
$c11 = 0.0$

Parameters
==========

fl_M_act : Any (sympifiable)
    Normalized passive muscle fiber force as a function of muscle fiber
    length.

z0.814z1.06z0.162z0.0633z0.433z0.717z-0.0299rD   z0.1z1.0z0.354z0.0rH   r   r   rK   rL   rM   rN   c4c5c6c7c8c9c10c11s                 r   rO   0FiberForceLengthActiveDeGroote2016.with_defaults  s    D 7^6]7^8_7^7^95\5\5\GnEl9"""""3OOr"   c                     g)a  Evaluation of basic inputs.

Parameters
==========

l_M_tilde : Any (sympifiable)
    Normalized muscle fiber length.
c0 : Any (sympifiable)
    The first constant in the characteristic equation. The published
    value is ``0.814``.
c1 : Any (sympifiable)
    The second constant in the characteristic equation. The published
    value is ``1.06``.
c2 : Any (sympifiable)
    The third constant in the characteristic equation. The published
    value is ``0.162``.
c3 : Any (sympifiable)
    The fourth constant in the characteristic equation. The published
    value is ``0.0633``.
c4 : Any (sympifiable)
    The fifth constant in the characteristic equation. The published
    value is ``0.433``.
c5 : Any (sympifiable)
    The sixth constant in the characteristic equation. The published
    value is ``0.717``.
c6 : Any (sympifiable)
    The seventh constant in the characteristic equation. The published
    value is ``-0.0299``.
c7 : Any (sympifiable)
    The eighth constant in the characteristic equation. The published
    value is ``0.2``.
c8 : Any (sympifiable)
    The ninth constant in the characteristic equation. The published
    value is ``0.1``.
c9 : Any (sympifiable)
    The tenth constant in the characteristic equation. The published
    value is ``1.0``.
c10 : Any (sympifiable)
    The eleventh constant in the characteristic equation. The published
    value is ``0.354``.
c11 : Any (sympifiable)
    The tweflth constant in the characteristic equation. The published
    value is ``0.0``.

Nr/   r   s                 r   r    'FiberForceLengthActiveDeGroote2016.evalN  s    ^ 	r"   c                 @    U R                  SSS9R                  U5      $ rU   rV   rX   s     r   rW   .FiberForceLengthActiveDeGroote2016._eval_evalf  r[   r"   c                    U R                   tpEU(       a;  X#S'   UR                  " SSU0UD6nU Vs/ s H  ofR                  " SSU0UD6PM     nnUu  pxpppnnnnU(       aa  U[        XH-
  XU-  -   -  S-  * S-  5      -  U[        XL-
  XU-  -   -  S-  * S-  5      -  -   U[        UU-
  UUU-  -   -  S-  * S-  5      -  -   $ U[        [        XH-
  5      XU-  -   -  S-  * S-  5      -  U[        [        XL-
  5      XU-  -   -  S-  * S-  5      -  -   U[        [        UU-
  5      UUU-  -   -  S-  * S-  5      -  -   $ s  snf )a]  Evaluate the expression defining the function.

Parameters
==========

deep : bool
    Whether ``doit`` should be recursively called. Default is ``True``.
evaluate : bool.
    Whether the SymPy expression should be evaluated as it is
    constructed. If ``False``, then no constant folding will be
    conducted which will leave the expression in a more numerically-
    stable for values of ``l_M_tilde`` that correspond to a sensible
    operating range for a musculotendon. Default is ``True``.
**kwargs : dict[str, Any]
    Additional keyword argument pairs to be recursively passed to
    ``doit``.

r&   r%   rj   r/   r_   )r+   r%   r&   ra   r   rb   rc   rK   rL   rM   rN   r   r   r   r   r   r   r   r   s                      r   r*   'FiberForceLengthActiveDeGroote2016.doit  s   & !%			 (*!:D:E:I=FGY3T3U3YIG;D8BS39>BI,=>BCAEFFSY^bi<.?@1DEaGHHISY^cC	M.ABQFGIJJK soin5ryL7HIAMNqPQQ	7l9JKaOPQRRSST	B7s9}9LMPQQRSTTUUV	
 Hs   D?c                    U R                   u  p#pEpgpppnUS:X  a  UXbU-
  S-  -  XVU-  -   S-  -  XB-
  XVU-  -   S-  -  -   -  [        X$-
  S-  * SXVU-  -   S-  -  -  5      -  UXU-
  S-  -  XU-  -   S-  -  X-
  XU-  -   S-  -  -   -  [        X(-
  S-  * SXU-  -   S-  -  -  5      -  -   UXU-
  S-  -  XU-  -   S-  -  X-
  XU-  -   S-  -  -   -  [        X,-
  S-  * SXU-  -   S-  -  -  5      -  -   $ US:X  a  [        X$-
  S-  * SXVU-  -   S-  -  -  5      $ US:X  a2  X2U-
  -  XVU-  -   S-  -  [        X$-
  S-  * SXVU-  -   S-  -  -  5      -  $ US:X  a5  X2U-
  S-  -  XVU-  -   S-  -  [        X$-
  S-  * SXVU-  -   S-  -  -  5      -  $ US:X  a7  X2-  X$-
  S-  -  XVU-  -   S-  -  [        X$-
  S-  * SXVU-  -   S-  -  -  5      -  $ US:X  a  [        X(-
  S-  * SXU-  -   S-  -  -  5      $ US:X  a2  XrU-
  -  XU-  -   S-  -  [        X(-
  S-  * SXU-  -   S-  -  -  5      -  $ US:X  a5  XrU-
  S-  -  XU-  -   S-  -  [        X(-
  S-  * SXU-  -   S-  -  -  5      -  $ US	:X  a7  Xr-  X(-
  S-  -  XU-  -   S-  -  [        X(-
  S-  * SXU-  -   S-  -  -  5      -  $ US
:X  a  [        X,-
  S-  * SXU-  -   S-  -  -  5      $ US:X  a2  XU-
  -  XU-  -   S-  -  [        X,-
  S-  * SXU-  -   S-  -  -  5      -  $ US:X  a5  XU-
  S-  -  XU-  -   S-  -  [        X,-
  S-  * SXU-  -   S-  -  -  5      -  $ US:X  a7  X-  X,-
  S-  -  XU-  -   S-  -  [        X,-
  S-  * SXU-  -   S-  -  -  5      -  $ [        X5      e)rh   ri   rj   rk   rl   rn            	   
            )r`   r	   r   )r+   ro   r   rK   rL   rM   rN   r   r   r   r   r   r   r   r   s                  r   rp   (FiberForceLengthActiveDeGroote2016.fdiff  sl    GKiiC	rrrrrq=B**BI,=+AA~l):Q(>?@ 	**AryL/@1.D,DEFG B**BI,=+AA~l):Q(>?@ 	**AryL/@1.D,DEFG	G R!++Sy=-@1,DD~9})<q(@AB 	**As]/BQ.F,FGHII ]!++Q	\0AA/E-EFGG]N#RY,%6$::y~))AryL/@1.D,DEFG ]NQ&&	\(9A'==y~))1bi<.?!-C+CDEF ]inq00")|2Ca1GGy~))1bi<.?!-C+CDEF ]!++Q	\0AA/E-EFGG]N#RY,%6$::y~))AryL/@1.D,DEFG ]NQ&&	\(9A'==y~))1bi<.?!-C+CDEF ]inq00")|2Ca1GGy~))1bi<.?!-C+CDEF ^!++Q)m0Ca/G-GHII^N#Sy=%81$<<y~))As]/BQ.F,FGHI ^NQ&&)m(;a'??y~))1c	M.AA-E+EFGH ^inq00#I2E1IIy~))1c	M.AA-E+EFGH
 !00r"   c                 L    U R                   S   nUR                  U5      nSU-  $ )rx   r   z+\operatorname{fl}^M_{act} \left( %s \right)ry   r   s       r   r{   )FiberForceLengthActiveDeGroote2016._latex  r   r"   r/   Nr~   r   )r   r0   r1   r2   r3   r4   rO   r    rW   r*   rp   r{   r@   r/   r"   r   r   r     sN    bH -P -P^ . .`G%
NP1dKr"   r   c                   b    \ rS rSrSr\S 5       r\S 5       rS rSS jr	SS jr
SS jrS	 rS
rg)r   i  a  Muscle fiber force-velocity curve based on De Groote et al., 2016 [1]_.

Explanation
===========

Gives the normalized muscle fiber force produced as a function of
normalized tendon velocity.

The function is defined by the equation:

$fv^M = c_0 \log{\left(c_1 \tilde{v}_m + c_2\right) + \sqrt{\left(c_1 \tilde{v}_m + c_2\right)^2 + 1}} + c_3$

with constant values of $c_0 = -0.318$, $c_1 = -8.149$, $c_2 = -0.374$, and
$c_3 = 0.886$.

While it is possible to change the constant values, these were carefully
selected in the original publication to give the characteristic curve
specific and required properties. For example, the function produces a
normalized muscle fiber force of 1 when the muscle fibers are contracting
isometrically (they have an extension rate of 0).

Examples
========

The preferred way to instantiate :class:`FiberForceVelocityDeGroote2016` is using
the :meth:`~.with_defaults` constructor because this will automatically populate
the constants within the characteristic curve equation with the floating
point values from the original publication. This constructor takes a single
argument corresponding to normalized muscle fiber extension velocity. We'll
create a :class:`~.Symbol` called ``v_M_tilde`` to represent this.

>>> from sympy import Symbol
>>> from sympy.physics.biomechanics import FiberForceVelocityDeGroote2016
>>> v_M_tilde = Symbol('v_M_tilde')
>>> fv_M = FiberForceVelocityDeGroote2016.with_defaults(v_M_tilde)
>>> fv_M
FiberForceVelocityDeGroote2016(v_M_tilde, -0.318, -8.149, -0.374, 0.886)

It's also possible to populate the four constants with your own values too.

>>> from sympy import symbols
>>> c0, c1, c2, c3 = symbols('c0 c1 c2 c3')
>>> fv_M = FiberForceVelocityDeGroote2016(v_M_tilde, c0, c1, c2, c3)
>>> fv_M
FiberForceVelocityDeGroote2016(v_M_tilde, c0, c1, c2, c3)

You don't just have to use symbols as the arguments, it's also possible to
use expressions. Let's create a new pair of symbols, ``v_M`` and
``v_M_max``, representing muscle fiber extension velocity and maximum
muscle fiber extension velocity respectively. We can then represent
``v_M_tilde`` as an expression, the ratio of these.

>>> v_M, v_M_max = symbols('v_M v_M_max')
>>> v_M_tilde = v_M/v_M_max
>>> fv_M = FiberForceVelocityDeGroote2016.with_defaults(v_M_tilde)
>>> fv_M
FiberForceVelocityDeGroote2016(v_M/v_M_max, -0.318, -8.149, -0.374, 0.886)

To inspect the actual symbolic expression that this function represents,
we can call the :meth:`~.doit` method on an instance. We'll use the keyword
argument ``evaluate=False`` as this will keep the expression in its
canonical form and won't simplify any constants.

>>> fv_M.doit(evaluate=False)
0.886 - 0.318*log(-8.149*v_M/v_M_max - 0.374 + sqrt(1 + (-8.149*v_M/v_M_max
- 0.374)**2))

The function can also be differentiated. We'll differentiate with respect
to v_M using the ``diff`` method on an instance with the single positional
argument ``v_M``.

>>> fv_M.diff(v_M)
2.591382*(1 + (-8.149*v_M/v_M_max - 0.374)**2)**(-1/2)/v_M_max

References
==========

.. [1] De Groote, F., Kinney, A. L., Rao, A. V., & Fregly, B. J., Evaluation
       of direct collocation optimal control problem formulations for
       solving the muscle redundancy problem, Annals of biomedical
       engineering, 44(10), (2016) pp. 2922-2936

c                 n    [        S5      n[        S5      n[        S5      n[        S5      nU " XX4U5      $ )a  Recommended constructor that will use the published constants.

Explanation
===========

Returns a new instance of the muscle fiber force-velocity function
using the four constant values specified in the original publication.

These have the values:

$c_0 = -0.318$
$c_1 = -8.149$
$c_2 = -0.374$
$c_3 = 0.886$

Parameters
==========

v_M_tilde : Any (sympifiable)
    Normalized muscle fiber extension velocity.

-0.318-8.149-0.3740.886rH   r   	v_M_tilderK   rL   rM   rN   s         r   rO   ,FiberForceVelocityDeGroote2016.with_defaults`  s7    0 8_8_8_7^9""--r"   c                     g)aX  Evaluation of basic inputs.

Parameters
==========

v_M_tilde : Any (sympifiable)
    Normalized muscle fiber extension velocity.
c0 : Any (sympifiable)
    The first constant in the characteristic equation. The published
    value is ``-0.318``.
c1 : Any (sympifiable)
    The second constant in the characteristic equation. The published
    value is ``-8.149``.
c2 : Any (sympifiable)
    The third constant in the characteristic equation. The published
    value is ``-0.374``.
c3 : Any (sympifiable)
    The fourth constant in the characteristic equation. The published
    value is ``0.886``.

Nr/   r   s         r   r    #FiberForceVelocityDeGroote2016.eval~  rS   r"   c                 @    U R                  SSS9R                  U5      $ rU   rV   rX   s     r   rW   *FiberForceVelocityDeGroote2016._eval_evalf  r[   r"   c           
         U R                   tpEU(       a@  X#S'   UR                  " SSU0UD6nU Vs/ s H  ofR                  " SSU0UD6PM     snu  pxpOUu  pxpU(       a-  U[        X-  U	-   [        X-  U	-   S-  S-   5      -   5      -  U
-   $ U[        X-  U	-   [        [	        X-  U	-   5      S-  S-   5      -   5      -  U
-   $ s  snf )a]  Evaluate the expression defining the function.

Parameters
==========

deep : bool
    Whether ``doit`` should be recursively called. Default is ``True``.
evaluate : bool.
    Whether the SymPy expression should be evaluated as it is
    constructed. If ``False``, then no constant folding will be
    conducted which will leave the expression in a more numerically-
    stable for values of ``v_M_tilde`` that correspond to a sensible
    operating range for a musculotendon. Default is ``True``.
**kwargs : dict[str, Any]
    Additional keyword argument pairs to be recursively passed to
    ``doit``.

r&   r%   rj   ri   r/   )r`   r*   r
   r   r   )r+   r%   r&   ra   r   rb   rc   rK   rL   rM   rN   s              r   r*   #FiberForceVelocityDeGroote2016.doit  s    & !%			 (*!:D:E:IBKL)Qff8$8%8)LNBB&NBBc",+dBL24E3IA3M.NNOORTTT#blR'$r|b?P/QST/TWX/X*YYZZ]___ Ms   Cc           	         U R                   u  p#pEnUS:X  a$  X4-  [        [        XB-  U-   5      S-  S-   5      -  $ US:X  a0  [        XB-  U-   [        [        XB-  U-   5      S-  S-   5      -   5      $ US:X  a$  X2-  [        [        XB-  U-   5      S-  S-   5      -  $ US:X  a"  U[        [        XB-  U-   5      S-  S-   5      -  $ US:X  a  [	        S5      $ [        X5      e)rh   ri   rj   rk   rl   rn   )r`   r   r   r
   r   r   )r+   ro   r   rK   rL   rM   rN   s          r   rp   $FiberForceVelocityDeGroote2016.fdiff  s     %)II!	rrq=5oblR.?@!CaGHHH]r!r|b'891<q@AB  ]<_R\B5F%G%JQ%N OOO]d?2<"+<=q@1DEEE]1: 00r"   c                     [         $ rs   )r   rt   s     r   ru   &FiberForceVelocityDeGroote2016.inverse  s
     54r"   c                 L    U R                   S   nUR                  U5      nSU-  $ )rx   r   z%\operatorname{fv}^M \left( %s \right)ry   )r+   r,   r   
_v_M_tildes       r   r{   %FiberForceVelocityDeGroote2016._latex  r}   r"   r/   Nr~   r   r   r/   r"   r   r   r     sN    Rh . .:  0G`@1:
5Er"   r   c                   b    \ rS rSrSr\S 5       r\S 5       rS rSS jr	SS jr
SS jrS	 rS
rg)r   i  a  Inverse muscle fiber force-velocity curve based on De Groote et al.,
2016 [1]_.

Explanation
===========

Gives the normalized muscle fiber velocity that produces a specific
normalized muscle fiber force.

The function is defined by the equation:

${fv^M}^{-1} = \frac{\sinh{\frac{fv^M - c_3}{c_0}} - c_2}{c_1}$

with constant values of $c_0 = -0.318$, $c_1 = -8.149$, $c_2 = -0.374$, and
$c_3 = 0.886$. This function is the exact analytical inverse of the related
muscle fiber force-velocity curve ``FiberForceVelocityDeGroote2016``.

While it is possible to change the constant values, these were carefully
selected in the original publication to give the characteristic curve
specific and required properties. For example, the function produces a
normalized muscle fiber force of 1 when the muscle fibers are contracting
isometrically (they have an extension rate of 0).

Examples
========

The preferred way to instantiate :class:`FiberForceVelocityInverseDeGroote2016`
is using the :meth:`~.with_defaults` constructor because this will automatically
populate the constants within the characteristic curve equation with the
floating point values from the original publication. This constructor takes
a single argument corresponding to normalized muscle fiber force-velocity
component of the muscle fiber force. We'll create a :class:`~.Symbol` called
``fv_M`` to represent this.

>>> from sympy import Symbol
>>> from sympy.physics.biomechanics import FiberForceVelocityInverseDeGroote2016
>>> fv_M = Symbol('fv_M')
>>> v_M_tilde = FiberForceVelocityInverseDeGroote2016.with_defaults(fv_M)
>>> v_M_tilde
FiberForceVelocityInverseDeGroote2016(fv_M, -0.318, -8.149, -0.374, 0.886)

It's also possible to populate the four constants with your own values too.

>>> from sympy import symbols
>>> c0, c1, c2, c3 = symbols('c0 c1 c2 c3')
>>> v_M_tilde = FiberForceVelocityInverseDeGroote2016(fv_M, c0, c1, c2, c3)
>>> v_M_tilde
FiberForceVelocityInverseDeGroote2016(fv_M, c0, c1, c2, c3)

To inspect the actual symbolic expression that this function represents,
we can call the :meth:`~.doit` method on an instance. We'll use the keyword
argument ``evaluate=False`` as this will keep the expression in its
canonical form and won't simplify any constants.

>>> v_M_tilde.doit(evaluate=False)
(-c2 + sinh((-c3 + fv_M)/c0))/c1

The function can also be differentiated. We'll differentiate with respect
to fv_M using the ``diff`` method on an instance with the single positional
argument ``fv_M``.

>>> v_M_tilde.diff(fv_M)
cosh((-c3 + fv_M)/c0)/(c0*c1)

References
==========

.. [1] De Groote, F., Kinney, A. L., Rao, A. V., & Fregly, B. J., Evaluation
       of direct collocation optimal control problem formulations for
       solving the muscle redundancy problem, Annals of biomedical
       engineering, 44(10), (2016) pp. 2922-2936

c                 n    [        S5      n[        S5      n[        S5      n[        S5      nU " XX4U5      $ )a  Recommended constructor that will use the published constants.

Explanation
===========

Returns a new instance of the inverse muscle fiber force-velocity
function using the four constant values specified in the original
publication.

These have the values:

$c_0 = -0.318$
$c_1 = -8.149$
$c_2 = -0.374$
$c_3 = 0.886$

Parameters
==========

fv_M : Any (sympifiable)
    Normalized muscle fiber extension velocity.

r   r   r   r   rH   r   fv_MrK   rL   rM   rN   s         r   rO   3FiberForceVelocityInverseDeGroote2016.with_defaults>  s7    2 8_8_8_7^4RR((r"   c                     g)a{  Evaluation of basic inputs.

Parameters
==========

fv_M : Any (sympifiable)
    Normalized muscle fiber force as a function of muscle fiber
    extension velocity.
c0 : Any (sympifiable)
    The first constant in the characteristic equation. The published
    value is ``-0.318``.
c1 : Any (sympifiable)
    The second constant in the characteristic equation. The published
    value is ``-8.149``.
c2 : Any (sympifiable)
    The third constant in the characteristic equation. The published
    value is ``-0.374``.
c3 : Any (sympifiable)
    The fourth constant in the characteristic equation. The published
    value is ``0.886``.

Nr/   r   s         r   r    *FiberForceVelocityInverseDeGroote2016.eval]  s    0 	r"   c                 @    U R                  SSS9R                  U5      $ rU   rV   rX   s     r   rW   1FiberForceVelocityInverseDeGroote2016._eval_evalfw  r[   r"   c                 6   U R                   tpEU(       a@  X#S'   UR                  " SSU0UD6nU Vs/ s H  ofR                  " SSU0UD6PM     snu  pxpOUu  pxpU(       a  [        XJ-
  U-  5      U	-
  U-  $ [        [        XJ-
  5      U-  5      U	-
  U-  $ s  snf )aX  Evaluate the expression defining the function.

Parameters
==========

deep : bool
    Whether ``doit`` should be recursively called. Default is ``True``.
evaluate : bool.
    Whether the SymPy expression should be evaluated as it is
    constructed. If ``False``, then no constant folding will be
    conducted which will leave the expression in a more numerically-
    stable for values of ``fv_M`` that correspond to a sensible
    operating range for a musculotendon. Default is ``True``.
**kwargs : dict[str, Any]
    Additional keyword argument pairs to be recursively passed to
    ``doit``.

r&   r%   r/   )r`   r*   r   r   )r+   r%   r&   ra   r   rb   rc   rK   rL   rM   rN   s              r   r*   *FiberForceVelocityInverseDeGroote2016.doit{  s    &  99 (*990$0%0DBKL)Qff8$8%8)LNBB&NBB$)R(2-r11_TY/23b8"<< Mre   c                 B   U R                   u  p#pEnUS:X  a  [        X&-
  U-  5      X4-  -  $ US:X  a  Xb-
  [        X&-
  U-  5      -  US-  U-  -  $ US:X  a  U[        X&-
  U-  5      -
  US-  -  $ US:X  a  SU-  $ US:X  a  [        X&-
  U-  5      * X4-  -  $ [        X5      erg   )r`   r   r   r   )r+   ro   r   rK   rL   rM   rN   s          r   rp   +FiberForceVelocityInverseDeGroote2016.fdiff  s      $yy""q=B'//]ItTYN33RU2X>>]ty"n--r1u44]b5L]$)R(("%00 00r"   c                     [         $ rs   )r   rt   s     r   ru   -FiberForceVelocityInverseDeGroote2016.inverse  s
     .-r"   c                 L    U R                   S   nUR                  U5      nSU-  $ )rx   r   z9\left( \operatorname{fv}^M \right)^{-1} \left( %s \right)ry   )r+   r,   r   _fv_Ms       r   r{   ,FiberForceVelocityInverseDeGroote2016._latex  r   r"   r/   Nr~   r   r   r/   r"   r   r   r     sM    HT ) )<  2G=@14
.Tr"   r   T)frozenc                   f    \ rS rSr% Sr\\S'   \\S'   \\S'   \\S'   \\S'   \\S'   \\S	'   S
 rSrg)r   i  zFSimple data container to group together related characteristic curves.tendon_force_lengthtendon_force_length_inversefiber_force_length_passive"fiber_force_length_passive_inversefiber_force_length_activefiber_force_velocityfiber_force_velocity_inversec              #      #    U R                   v   U R                  v   U R                  v   U R                  v   U R                  v   U R
                  v   U R                  v   g7f)z7Iterator support for ``CharacteristicCurveCollection``.N)r  r  r  r	  r
  r  r  )r+   s    r   __iter__&CharacteristicCurveCollection.__iter__  sY     &&&...---555,,,'''///s   A$A&r/   N)	r   r0   r1   r2   r3   r   __annotations__r  r@   r/   r"   r   r   r     s4    P44!<< ;;(CC::55"==0r"   r   N)r3   dataclassesr   sympy.core.exprr   sympy.core.functionr   r   sympy.core.numbersr   r   &sympy.functions.elementary.exponentialr	   r
   %sympy.functions.elementary.hyperbolicr   r   (sympy.functions.elementary.miscellaneousr   sympy.printing.precedencer   __all__r   r   r   r   r   r   r   r   r   r/   r"   r   <module>r     s    H ! + < - ; < 9 0
-( -`cE$? cELXT+F XTvWK*E WKtP^1L P^fOK)D OKd
eE%@ eEPZT,G ZTz $0 0 0r"   