_Function

it.grypho.scala.leonardo.scalar._Function
abstract class _Function extends _Expression

Attributes

Graph
Supertypes
trait _Expression
class Object
trait Matchable
class Any
Known subtypes
class Acos
class Acosh
class Asin
class Asinh
class Atan
class Atanh
class Beta
class BetaI
class Binom
class Catalan
class Ci
class Cos
class Cosh
class Cot
class Coth
class Csc
class Csch
class Digamma
class Ei
class Erf
class Erfc
class Exp
class Factorial
class FresnelC
class FresnelS
class Gamma
class GammaP
class GammaQ
class Harmonic
class Li
class Ln
class LogBase
class LogGamma
class Sec
class Sech
class Si
class Sin
class Sinh
class Tanh
class Tg
Show all

Members list

Value members

Concrete methods

protected def exactIntArg(r: _Rational): Option[BigInt]

The exact non-negative integer an argument denotes, if it denotes one.

The exact non-negative integer an argument denotes, if it denotes one.

The gate on every exact path in the factorial family: those functions are only closed over the rationals at non-negative integers, and everywhere else (Gamma(0.5), fact(-1)) the analytic kernels remain the right answer.

Value parameters

r

the exact argument

Attributes

Returns

Some(n) when r is a non-negative integer, None otherwise

protected def exactKernel: Option[_Rational => Option[Real]]

This function as an arbitrary-precision kernel, when it has one.

This function as an arbitrary-precision kernel, when it has one.

Returning None means "not defined here", and covers both cases: a function with no Real counterpart at all, and an argument outside the real domain — ln of a negative, asin beyond ±1. The domain is checked explicitly per function rather than by computing in Double first and seeing whether it came back finite, because that oracle gets exp(1000) exactly wrong: Double overflows to an infinity there while the true value is a perfectly finite 435-digit number, which is the acceptance case.

Out-of-domain arguments fall through to viaDouble, which owns the complex fallback.

Attributes

protected def mapMatrix(mv: _MatrixValue, f: Double => Double): Either[_Expression, _Value]

Applies a real scalar function element-wise over a dense matrix argument.

Applies a real scalar function element-wise over a dense matrix argument.

An out-of-domain element (e.g. ln of a negative entry yields NaN) leaves the whole node symbolic: the dense _MatrixValue carrier cannot hold the complex fallback value that a per-element scalar result would produce.

Value parameters

f

the scalar function to apply to each element

mv

the dense matrix to map over

Attributes

Returns

Right(_MatrixValue) when all elements are finite, Left(this) otherwise

protected def mapMatrixExpr(m: _MatrixShaped, env: Environment): Either[_Expression, _Value]

Applies this single-argument function element-wise over a symbolic matrix argument.

Applies this single-argument function element-wise over a symbolic matrix argument.

Rebuilds the matrix with this function wrapped around each cell and re-evaluates. Unlike mapMatrix, each cell degrades independently -- an out-of-domain cell becomes its own complex or symbolic result rather than dropping the whole matrix.

Value parameters

env

the evaluation environment

m

the symbolic matrix (_MatrixShaped) whose cells are not yet concrete

Attributes

Returns

the element-wise result, with numeric cells folded and symbolic cells kept

protected def viaDouble(args: List[_Expression], env: Environment): Either[_Expression, _Value]

Evaluates this function on exact arguments by way of the Double kernel, lifting the result back into the exact tier.

Evaluates this function on exact arguments by way of the Double kernel, lifting the result back into the exact tier.

No transcendental function is closed over the rationals — exp(1) and sin(1/3) are irrational — so the exact tier's contract for them is "compute, then re-approximate to the working precision", and this is that step.

Implemented by rebuilding the node with _Number arguments and re-evaluating, rather than by taking a Double => Double kernel: that reuses each node's own logic, including its domain handling and its complex fallback, instead of duplicating a function reference at fourteen call sites and getting one of them wrong. The rebuilt node hits its _Number case, so there is no recursion.

A complex or symbolic result passes through untouched — a complex value is inexact, so float contagion is already the right answer for it.

This is now the fallback: viaExact is what the transcendentals reach first, and it comes back here for an out-of-domain argument or a low working precision.

Value parameters

args

the same children, with every exact argument replaced by its Double

env

supplies the working precision

Attributes

Returns

the result lifted back to a _Rational, or whatever non-real result came out

protected def viaExact(r: _Rational, env: Environment): Either[_Expression, _Value]

Evaluates this function on an exact argument, at the working precision.

Evaluates this function on an exact argument, at the working precision.

Uses the Double kernel when the working precision is inside Double's reliable range: there is nothing to gain there and roughly 110× to lose, since a Real transcendental costs about 0.6 ms against 0.006 ms. The two agree to within the precision either claims, so which one ran is not observable — only how long it took.

Value parameters

env

supplies the working precision

r

the exact argument

Attributes

Returns

the result at the working precision, or the Double path's answer

Inherited and Abstract methods

def children: List[_Expression]

Sub-expressions subject to recursive structural traversal. Binder positions (e.g. the differentiation variable) are excluded.

Sub-expressions subject to recursive structural traversal. Binder positions (e.g. the differentiation variable) are excluded.

Attributes

Inherited from:
_Expression
def eval(env: Environment): Either[_Expression, _Value]

Reduces this expression in the given environment.

Reduces this expression in the given environment.

Value parameters

env

variable bindings and display precision

Attributes

Returns

Right(v) when all free variables resolved to concrete values; Left(e) when reduction is partial or impossible

Inherited from:
_Expression
def rebuild(newChildren: List[_Expression]): _Expression

Reconstructs the same node shape with replacement sub-expressions.

Reconstructs the same node shape with replacement sub-expressions.

Value parameters

newChildren

replacements in the same order and count as children

Attributes

Inherited from:
_Expression

Inherited fields

lazy val freeVars: Set[String]

Cached set of free variable names; O(1) after the first access.

Cached set of free variable names; O(1) after the first access.

Attributes

Inherited from:
_Expression