4.6. Math
Viskores comes with several math functions that tend to be useful for visualization algorithms. The implementation of basic math operations can vary subtly on different accelerators, and these functions provide cross platform support.
All math functions are located in the viskores package.
The functions are most useful in the execution environment, but they can also be used in the control environment when needed.
4.6.1. Basic Math
The viskores/Math.h header file contains several math functions that replicate the behavior of the basic POSIX math functions as well as related functionality.
Did You Know?
When writing worklets, you should favor using these math functions provided by Viskores over the standard math functions in viskores/Math.h.
Viskores’s implementation manages several compiling and efficiency issues when porting.
4.6.1.1. Comparison and Distance
-
template<typename Tx, typename Tlow, typename Thigh>
inline Tx viskores::Clamp(Tx &&x, Tlow &&low, Thigh &&high) Clamp
xto the given range.Given a value
xand a range of valid range of values, provides the value within the range. Ifxis already within the range, that value is just returned. Ifxis outside that range, the low or high value (whichever is closer) is returned.For convenience, the
lowandhighand high values will be typecast to the type ofx.Clampmay be called forVecandVec-like objects to do a component-wise clamp. It is an error if the number of components does not match.- Parameters:
x – The value to clamp to a specific range.
low – The minimum value of the valid range.
high – The maximum value of the valid range.
- Returns:
xadjusted to be in the range fromlowtohigh.
-
inline viskores::UInt64 viskores::FloatDistance(viskores::Float64 x, viskores::Float64 y)
Computes the number of representables between two floating point numbers.
This function is non-negative and symmetric in its arguments. If either argument is non-finite, the value returned is the maximum value allowed by 64-bit unsigned integers: 2^64-1.
-
inline viskores::UInt64 viskores::FloatDistance(viskores::Float32 x, viskores::Float32 y)
Computes the number of representables between two floating point numbers.
This function is non-negative and symmetric in its arguments. If either argument is non-finite, the value returned is the maximum value allowed by 64-bit unsigned integers: 2^64-1.
4.6.1.2. Exponentials
-
inline viskores::Float32 viskores::Exp(viskores::Float32 x)
Computes e^x, the base-e exponential of
x.
-
inline viskores::Float64 viskores::Exp(viskores::Float64 x)
Computes e^x, the base-e exponential of
x.
-
template<typename T>
static inline detail::FloatingPointReturnType<T>::Type viskores::Exp(const T &x) Computes e^x, the base-e exponential of
x.
-
template<typename T, viskores::IdComponent N>
static inline viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, N> viskores::Exp(const viskores::Vec<T, N> &x) Computes e^x, the base-e exponential of
x.
-
static inline viskores::Float32 viskores::Exp10(viskores::Float32 x)
Computes 10^x, the base-10 exponential of
x.
-
static inline viskores::Float64 viskores::Exp10(viskores::Float64 x)
Computes 10^x, the base-10 exponential of
x.
-
template<typename T>
static inline viskores::Float64 viskores::Exp10(T x) Computes 10^x, the base-10 exponential of
x.
-
template<typename T, viskores::IdComponent N>
static inline viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, N> viskores::Exp10(const viskores::Vec<T, N> &x) Computes 10^x, the base-10 exponential of
x.
-
inline viskores::Float32 viskores::Exp2(viskores::Float32 x)
Computes 2^x, the base-2 exponential of
x.
-
inline viskores::Float64 viskores::Exp2(viskores::Float64 x)
Computes 2^x, the base-2 exponential of
x.
-
template<typename T>
static inline detail::FloatingPointReturnType<T>::Type viskores::Exp2(const T &x) Computes 2^x, the base-2 exponential of
x.
-
template<typename T, viskores::IdComponent N>
static inline viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, N> viskores::Exp2(const viskores::Vec<T, N> &x) Computes 2^x, the base-2 exponential of
x.
-
inline viskores::Float32 viskores::ExpM1(viskores::Float32 x)
Computes (e^x) - 1, the of base-e exponental of
xthen minus 1. The accuracy of this function is good even for very small values ofx.
-
inline viskores::Float64 viskores::ExpM1(viskores::Float64 x)
Computes (e^x) - 1, the of base-e exponental of
xthen minus 1. The accuracy of this function is good even for very small values ofx.
-
template<typename T>
static inline detail::FloatingPointReturnType<T>::Type viskores::ExpM1(const T &x) Computes (e^x) - 1, the of base-e exponental of
xthen minus 1. The accuracy of this function is good even for very small values ofx.
-
template<typename T, viskores::IdComponent N>
static inline viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, N> viskores::ExpM1(const viskores::Vec<T, N> &x) Computes (e^x) - 1, the of base-e exponental of
xthen minus 1. The accuracy of this function is good even for very small values ofx.
-
template<typename T>
static inline detail::FloatingPointReturnType<T>::Type viskores::Log(const T &x) Computes the natural logarithm of
x.
-
template<typename T, viskores::IdComponent N>
static inline viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, N> viskores::Log(const viskores::Vec<T, N> &x) Computes the natural logarithm of
x.
-
template<typename T>
static inline detail::FloatingPointReturnType<T>::Type viskores::Log10(const T &x) Computes the logarithm base 10 of
x.
-
template<typename T, viskores::IdComponent N>
static inline viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, N> viskores::Log10(const viskores::Vec<T, N> &x) Computes the logarithm base 10 of
x.
-
inline viskores::Float32 viskores::Log1P(viskores::Float32 x)
Computes the value of log(1+x). This method is more accurate for very small values of x than the
viskores::Logfunction.
-
inline viskores::Float64 viskores::Log1P(viskores::Float64 x)
Computes the value of log(1+x). This method is more accurate for very small values of x than the
viskores::Logfunction.
-
template<typename T>
static inline detail::FloatingPointReturnType<T>::Type viskores::Log1P(const T &x) Computes the value of log(1+x). This method is more accurate for very small values of x than the
viskores::Logfunction.
-
template<typename T, viskores::IdComponent N>
static inline viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, N> viskores::Log1P(const viskores::Vec<T, N> &x) Computes the value of log(1+x). This method is more accurate for very small values of x than the
viskores::Logfunction.
-
template<typename T>
static inline detail::FloatingPointReturnType<T>::Type viskores::Log2(const T &x) Computes the logarithm base 2 of
x.
-
template<typename T, viskores::IdComponent N>
static inline viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, N> viskores::Log2(const viskores::Vec<T, N> &x) Computes the logarithm base 2 of
x.
4.6.1.3. Non-finites
-
template<typename T>
static inline T viskores::Infinity() Returns the representation for infinity. The result is greater than any other number except another infinity or NaN. When comparing two infinities or infinity to NaN, neither is greater than, less than, nor equal to the other. The
Infinity()function is templated to specify either a 32 or 64 bit floating point number. The convenience functionsInfinity32()andInfinity64()are non-templated versions that return the precision for a particular precision.
-
static inline viskores::Float32 viskores::Infinity32()
Returns the representation for infinity. The result is greater than any other number except another infinity or NaN. When comparing two infinities or infinity to NaN, neither is greater than, less than, nor equal to the other. The
Infinity()function is templated to specify either a 32 or 64 bit floating point number. The convenience functionsInfinity32()andInfinity64()are non-templated versions that return the precision for a particular precision.
-
static inline viskores::Float64 viskores::Infinity64()
Returns the representation for infinity. The result is greater than any other number except another infinity or NaN. When comparing two infinities or infinity to NaN, neither is greater than, less than, nor equal to the other. The
Infinity()function is templated to specify either a 32 or 64 bit floating point number. The convenience functionsInfinity32()andInfinity64()are non-templated versions that return the precision for a particular precision.
-
template<typename T>
static inline bool viskores::IsFinite(T x) Returns true if
xis a normal number (not NaN or infinite).
-
template<typename T>
static inline bool viskores::IsInf(T x) Returns true if
xis positive or negative infinity.
-
static inline bool viskores::IsNegative(viskores::Float32 x)
Returns true if
xis less than zero, false otherwise.
-
static inline bool viskores::IsNegative(viskores::Float64 x)
Returns true if
xis less than zero, false otherwise.
-
template<typename T>
static inline T viskores::Nan() Returns the representation for infinity. The result is greater than any other number except another infinity or NaN. When comparing two infinities or infinity to NaN, neither is greater than, less than, nor equal to the other. The
Nan()function is templated to specify either a 32 or 64 bit floating point number. The convenience functionsNan32()andNan64()are non-templated versions that return the precision for a particular precision.
-
static inline viskores::Float32 viskores::Nan32()
Returns the representation for infinity. The result is greater than any other number except another infinity or NaN. When comparing two infinities or infinity to NaN, neither is greater than, less than, nor equal to the other. The
Nan()function is templated to specify either a 32 or 64 bit floating point number. The convenience functionsNan32()andNan64()are non-templated versions that return the precision for a particular precision.
-
static inline viskores::Float64 viskores::Nan64()
Returns the representation for infinity. The result is greater than any other number except another infinity or NaN. When comparing two infinities or infinity to NaN, neither is greater than, less than, nor equal to the other. The
Nan()function is templated to specify either a 32 or 64 bit floating point number. The convenience functionsNan32()andNan64()are non-templated versions that return the precision for a particular precision.
-
template<typename T>
static inline T viskores::NegativeInfinity() Returns the representation for negative infinity. The result is less than any other number except another negative infinity or NaN. When comparing two negative infinities or negative infinity to NaN, neither is greater than, less than, nor equal to the other. The
NegativeInfinity()function is templated to specify either a 32 or 64 bit floating point number. The convenience functionsNegativeInfinity32()andNegativeInfinity64()are non-templated versions that return the precision for a particular precision.
-
static inline viskores::Float32 viskores::NegativeInfinity32()
Returns the representation for negative infinity. The result is less than any other number except another negative infinity or NaN. When comparing two negative infinities or negative infinity to NaN, neither is greater than, less than, nor equal to the other. The
NegativeInfinity()function is templated to specify either a 32 or 64 bit floating point number. The convenience functionsNegativeInfinity32()andNegativeInfinity64()are non-templated versions that return the precision for a particular precision.
-
static inline viskores::Float64 viskores::NegativeInfinity64()
Returns the representation for negative infinity. The result is less than any other number except another negative infinity or NaN. When comparing two negative infinities or negative infinity to NaN, neither is greater than, less than, nor equal to the other. The
NegativeInfinity()function is templated to specify either a 32 or 64 bit floating point number. The convenience functionsNegativeInfinity32()andNegativeInfinity64()are non-templated versions that return the precision for a particular precision.
4.6.1.4. Polynomials
-
template<typename T>
static inline detail::FloatingPointReturnType<T>::Type viskores::Cbrt(const T &x) Compute the cube root of
x.
-
template<typename T, viskores::IdComponent N>
static inline viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, N> viskores::Cbrt(const viskores::Vec<T, N> &x) Compute the cube root of
x.
-
template<typename T>
inline viskores::Vec<T, 2> viskores::QuadraticRoots(T a, T b, T c) Solves ax² + bx + c = 0.
Only returns the real roots. If there are real roots, the first element of the pair is less than or equal to the second. If there are no real roots, both elements are NaNs. If Viskores is compiled with FMA support, each root is accurate to 3 ulps; otherwise the discriminant is prone to catastrophic subtractive cancellation and no accuracy guarantees can be provided.
-
static inline viskores::Float32 viskores::RCbrt(viskores::Float32 x)
Compute the reciprocal cube root of
x. The result of this function is equivalent to1/Cbrt(x). However, on some devices it is faster to compute the reciprocal cube root than the regular cube root. Thus, you should use this function whenever dividing by the cube root.
-
static inline viskores::Float64 viskores::RCbrt(viskores::Float64 x)
Compute the reciprocal cube root of
x. The result of this function is equivalent to1/Cbrt(x). However, on some devices it is faster to compute the reciprocal cube root than the regular cube root. Thus, you should use this function whenever dividing by the cube root.
-
template<typename T>
static inline viskores::Float64 viskores::RCbrt(T x) Compute the reciprocal cube root of
x. The result of this function is equivalent to1/Cbrt(x). However, on some devices it is faster to compute the reciprocal cube root than the regular cube root. Thus, you should use this function whenever dividing by the cube root.
-
template<typename T, viskores::IdComponent N>
static inline viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, N> viskores::RCbrt(const viskores::Vec<T, N> &x) Compute the reciprocal cube root of
x. The result of this function is equivalent to1/Cbrt(x). However, on some devices it is faster to compute the reciprocal cube root than the regular cube root. Thus, you should use this function whenever dividing by the cube root.
-
static inline viskores::Float32 viskores::RSqrt(viskores::Float32 x)
Compute the reciprocal square root of
x. The result of this function is equivalent to1/Sqrt(x). However, on some devices it is faster to compute the reciprocal square root than the regular square root. Thus, you should use this function whenever dividing by the square root.
-
static inline viskores::Float64 viskores::RSqrt(viskores::Float64 x)
Compute the reciprocal square root of
x. The result of this function is equivalent to1/Sqrt(x). However, on some devices it is faster to compute the reciprocal square root than the regular square root. Thus, you should use this function whenever dividing by the square root.
-
template<typename T>
static inline viskores::Float64 viskores::RSqrt(T x) Compute the reciprocal square root of
x. The result of this function is equivalent to1/Sqrt(x). However, on some devices it is faster to compute the reciprocal square root than the regular square root. Thus, you should use this function whenever dividing by the square root.
-
template<typename T, viskores::IdComponent N>
static inline viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, N> viskores::RSqrt(const viskores::Vec<T, N> &x) Compute the reciprocal square root of
x. The result of this function is equivalent to1/Sqrt(x). However, on some devices it is faster to compute the reciprocal square root than the regular square root. Thus, you should use this function whenever dividing by the square root.
-
inline viskores::Float32 viskores::Sqrt(viskores::Float32 x)
Compute the square root of
x. On some hardware it is faster to find the reciprocal square root, soRSqrtshould be used if you actually plan to divide by the square root.
-
inline viskores::Float64 viskores::Sqrt(viskores::Float64 x)
Compute the square root of
x. On some hardware it is faster to find the reciprocal square root, soRSqrtshould be used if you actually plan to divide by the square root.
-
template<typename T>
static inline detail::FloatingPointReturnType<T>::Type viskores::Sqrt(const T &x) Compute the square root of
x. On some hardware it is faster to find the reciprocal square root, soRSqrtshould be used if you actually plan to divide by the square root.
-
template<typename T, viskores::IdComponent N>
static inline viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, N> viskores::Sqrt(const viskores::Vec<T, N> &x) Compute the square root of
x. On some hardware it is faster to find the reciprocal square root, soRSqrtshould be used if you actually plan to divide by the square root.
4.6.1.5. Remainders and Quotient
-
static inline viskores::Float32 viskores::ModF(viskores::Float32 x, viskores::Float32 &integral)
Gets the integral and fractional parts of
x. The return value is the fractional part andintegralis set to the integral part.
-
static inline viskores::Float64 viskores::ModF(viskores::Float64 x, viskores::Float64 &integral)
Gets the integral and fractional parts of
x. The return value is the fractional part andintegralis set to the integral part.
-
static inline viskores::Float32 viskores::Remainder(viskores::Float32 x, viskores::Float32 y)
Computes the remainder on division of 2 floating point numbers. The return value is
numerator- ndenominator, where n is the quotient ofnumeratordivided bydenominatorrounded towards the nearest integer (instead of toward zero like FMod). For example,FMod(6.5, 2.3)returns -0.4, which is 6.5 - 3*2.3.
-
static inline viskores::Float64 viskores::Remainder(viskores::Float64 x, viskores::Float64 y)
Computes the remainder on division of 2 floating point numbers. The return value is
numerator- ndenominator, where n is the quotient ofnumeratordivided bydenominatorrounded towards the nearest integer (instead of toward zero like FMod). For example,FMod(6.5, 2.3)returns -0.4, which is 6.5 - 3*2.3.
-
template<typename QType>
static inline viskores::Float32 viskores::RemainderQuotient(viskores::Float32 numerator, viskores::Float32 denominator, QType "ient) Returns the remainder on division of 2 floating point numbers just like Remainder. In addition, this function also returns the
quotientused to get that remainder.
-
template<typename QType>
static inline viskores::Float64 viskores::RemainderQuotient(viskores::Float64 numerator, viskores::Float64 denominator, QType "ient) Returns the remainder on division of 2 floating point numbers just like Remainder. In addition, this function also returns the
quotientused to get that remainder.
4.6.1.6. Rounding and Precision
-
inline viskores::Float32 viskores::Ceil(viskores::Float32 x)
Round
xto the smallest integer value not less than x.
-
inline viskores::Float64 viskores::Ceil(viskores::Float64 x)
Round
xto the smallest integer value not less than x.
-
template<typename T>
static inline detail::FloatingPointReturnType<T>::Type viskores::Ceil(const T &x) Round
xto the smallest integer value not less than x.
-
template<typename T, viskores::IdComponent N>
static inline viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, N> viskores::Ceil(const viskores::Vec<T, N> &x) Round
xto the smallest integer value not less than x.
-
static inline viskores::Float32 viskores::CopySign(viskores::Float32 x, viskores::Float32 y)
Copies the sign of
yontox. Ifyis positive, returns Abs(x). Ifyis negative, returns -Abs(x).
-
static inline viskores::Float64 viskores::CopySign(viskores::Float64 x, viskores::Float64 y)
Copies the sign of
yontox. Ifyis positive, returns Abs(x). Ifyis negative, returns -Abs(x).
-
template<typename T, viskores::IdComponent N>
static inline viskores::Vec<T, N> viskores::CopySign(const viskores::Vec<T, N> &x, const viskores::Vec<T, N> &y) Copies the sign of
yontox. Ifyis positive, returns Abs(x). Ifyis negative, returns -Abs(x).
-
template<typename T>
static inline T viskores::Epsilon() Returns the difference between 1 and the least value greater than 1 that is representable by a floating point number. Epsilon is useful for specifying the tolerance one should have when considering numerical error. The
Epsilon()function is templated to specify either a 32 or 64 bit floating point number. The convenience functionsEpsilon32()andEpsilon64()are non-templated versions that return the precision for a particular precision.
-
static inline viskores::Float32 viskores::Epsilon32()
Returns the difference between 1 and the least value greater than 1 that is representable by a floating point number. Epsilon is useful for specifying the tolerance one should have when considering numerical error. The
Epsilon()function is templated to specify either a 32 or 64 bit floating point number. The convenience functionsEpsilon32()andEpsilon64()are non-templated versions that return the precision for a particular precision.
-
static inline viskores::Float64 viskores::Epsilon64()
Returns the difference between 1 and the least value greater than 1 that is representable by a floating point number. Epsilon is useful for specifying the tolerance one should have when considering numerical error. The
Epsilon()function is templated to specify either a 32 or 64 bit floating point number. The convenience functionsEpsilon32()andEpsilon64()are non-templated versions that return the precision for a particular precision.
-
static inline viskores::Float32 viskores::FMod(viskores::Float32 x, viskores::Float32 y)
Computes the remainder on division of 2 floating point numbers. The return value is
numerator- ndenominator, where n is the quotient ofnumeratordivided bydenominatorrounded towards zero to an integer. For example,FMod(6.5, 2.3)returns 1.9, which is 6.5 - 2*2.3.
-
static inline viskores::Float64 viskores::FMod(viskores::Float64 x, viskores::Float64 y)
Computes the remainder on division of 2 floating point numbers. The return value is
numerator- ndenominator, where n is the quotient ofnumeratordivided bydenominatorrounded towards zero to an integer. For example,FMod(6.5, 2.3)returns 1.9, which is 6.5 - 2*2.3.
-
inline viskores::Float32 viskores::Round(viskores::Float32 x)
Round
xto the nearest integral value.
-
inline viskores::Float64 viskores::Round(viskores::Float64 x)
Round
xto the nearest integral value.
4.6.1.7. Sign
-
static inline viskores::Int32 viskores::Abs(viskores::Int32 x)
Return the absolute value of
x. That is, returnxif it is positive or-xif it is negative.
-
static inline viskores::Int64 viskores::Abs(viskores::Int64 x)
Return the absolute value of
x. That is, returnxif it is positive or-xif it is negative.
-
static inline viskores::Float32 viskores::Abs(viskores::Float32 x)
Return the absolute value of
x. That is, returnxif it is positive or-xif it is negative.
-
static inline viskores::Float64 viskores::Abs(viskores::Float64 x)
Return the absolute value of
x. That is, returnxif it is positive or-xif it is negative.
-
template<typename T>
static inline detail::FloatingPointReturnType<T>::Type viskores::Abs(T x) Return the absolute value of
x. That is, returnxif it is positive or-xif it is negative.
-
template<typename T, viskores::IdComponent N>
static inline viskores::Vec<T, N> viskores::Abs(const viskores::Vec<T, N> &x) Return the absolute value of
x. That is, returnxif it is positive or-xif it is negative.
-
inline viskores::Float32 viskores::Floor(viskores::Float32 x)
Round
xto the largest integer value not greater than x.
-
inline viskores::Float64 viskores::Floor(viskores::Float64 x)
Round
xto the largest integer value not greater than x.
-
template<typename T>
static inline detail::FloatingPointReturnType<T>::Type viskores::Floor(const T &x) Round
xto the largest integer value not greater than x.
-
template<typename T, viskores::IdComponent N>
static inline viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, N> viskores::Floor(const viskores::Vec<T, N> &x) Round
xto the largest integer value not greater than x.
4.6.1.8. Trigonometry
-
template<typename T>
static inline detail::FloatingPointReturnType<T>::Type viskores::ACos(const T &x) Compute the arc cosine of
x.
-
template<typename T, viskores::IdComponent N>
static inline viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, N> viskores::ACos(const viskores::Vec<T, N> &x) Compute the arc cosine of
x.
-
inline viskores::Float32 viskores::ACosH(viskores::Float32 x)
Compute the hyperbolic arc cosine of
x.
-
inline viskores::Float64 viskores::ACosH(viskores::Float64 x)
Compute the hyperbolic arc cosine of
x.
-
template<typename T>
static inline detail::FloatingPointReturnType<T>::Type viskores::ACosH(const T &x) Compute the hyperbolic arc cosine of
x.
-
template<typename T, viskores::IdComponent N>
static inline viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, N> viskores::ACosH(const viskores::Vec<T, N> &x) Compute the hyperbolic arc cosine of
x.
-
template<typename T>
static inline detail::FloatingPointReturnType<T>::Type viskores::ASin(const T &x) Compute the arc sine of
x.
-
template<typename T, viskores::IdComponent N>
static inline viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, N> viskores::ASin(const viskores::Vec<T, N> &x) Compute the arc sine of
x.
-
inline viskores::Float32 viskores::ASinH(viskores::Float32 x)
Compute the hyperbolic arc sine of
x.
-
inline viskores::Float64 viskores::ASinH(viskores::Float64 x)
Compute the hyperbolic arc sine of
x.
-
template<typename T>
static inline detail::FloatingPointReturnType<T>::Type viskores::ASinH(const T &x) Compute the hyperbolic arc sine of
x.
-
template<typename T, viskores::IdComponent N>
static inline viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, N> viskores::ASinH(const viskores::Vec<T, N> &x) Compute the hyperbolic arc sine of
x.
-
template<typename T>
static inline detail::FloatingPointReturnType<T>::Type viskores::ATan(const T &x) Compute the arc tangent of
x.
-
template<typename T, viskores::IdComponent N>
static inline viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, N> viskores::ATan(const viskores::Vec<T, N> &x) Compute the arc tangent of
x.
-
static inline viskores::Float32 viskores::ATan2(viskores::Float32 x, viskores::Float32 y)
Compute the arc tangent of
x/yusing the signs of both arguments to determine the quadrant of the return value.
-
static inline viskores::Float64 viskores::ATan2(viskores::Float64 x, viskores::Float64 y)
Compute the arc tangent of
x/yusing the signs of both arguments to determine the quadrant of the return value.
-
inline viskores::Float32 viskores::ATanH(viskores::Float32 x)
Compute the hyperbolic arc tangent of
x.
-
inline viskores::Float64 viskores::ATanH(viskores::Float64 x)
Compute the hyperbolic arc tangent of
x.
-
template<typename T>
static inline detail::FloatingPointReturnType<T>::Type viskores::ATanH(const T &x) Compute the hyperbolic arc tangent of
x.
-
template<typename T, viskores::IdComponent N>
static inline viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, N> viskores::ATanH(const viskores::Vec<T, N> &x) Compute the hyperbolic arc tangent of
x.
-
template<typename T>
static inline detail::FloatingPointReturnType<T>::Type viskores::Cos(const T &x) Compute the cosine of
x.
-
template<typename T, viskores::IdComponent N>
static inline viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, N> viskores::Cos(const viskores::Vec<T, N> &x) Compute the cosine of
x.
-
template<typename T>
static inline detail::FloatingPointReturnType<T>::Type viskores::CosH(const T &x) Compute the hyperbolic cosine of
x.
-
template<typename T, viskores::IdComponent N>
static inline viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, N> viskores::CosH(const viskores::Vec<T, N> &x) Compute the hyperbolic cosine of
x.
-
template<typename T = viskores::Float64>
static inline constexpr detail::FloatingPointReturnType<T>::Type viskores::Pi() Returns the constant Pi.
-
template<typename T = viskores::Float64>
static inline constexpr detail::FloatingPointReturnType<T>::Type viskores::Pi_2() Returns the constant Pi halves.
-
template<typename T = viskores::Float64>
static inline constexpr detail::FloatingPointReturnType<T>::Type viskores::Pi_3() Returns the constant Pi thirds.
-
template<typename T = viskores::Float64>
static inline constexpr detail::FloatingPointReturnType<T>::Type viskores::Pi_4() Returns the constant Pi fourths.
-
template<typename T = viskores::Float64>
static inline constexpr detail::FloatingPointReturnType<T>::Type viskores::Pi_180() Returns the constant Pi one hundred and eightieth.
-
template<typename T>
static inline detail::FloatingPointReturnType<T>::Type viskores::Sin(const T &x) Compute the sine of
x.
-
template<typename T, viskores::IdComponent N>
static inline viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, N> viskores::Sin(const viskores::Vec<T, N> &x) Compute the sine of
x.
-
template<typename T>
static inline detail::FloatingPointReturnType<T>::Type viskores::SinH(const T &x) Compute the hyperbolic sine of
x.
-
template<typename T, viskores::IdComponent N>
static inline viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, N> viskores::SinH(const viskores::Vec<T, N> &x) Compute the hyperbolic sine of
x.
-
template<typename T>
static inline detail::FloatingPointReturnType<T>::Type viskores::Tan(const T &x) Compute the tangent of
x.
-
template<typename T, viskores::IdComponent N>
static inline viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, N> viskores::Tan(const viskores::Vec<T, N> &x) Compute the tangent of
x.
-
template<typename T>
static inline detail::FloatingPointReturnType<T>::Type viskores::TanH(const T &x) Compute the hyperbolic tangent of
x.
4.6.2. Vector Analysis
Visualization and computational geometry algorithms often perform vector analysis operations.
The viskores/VectorAnalysis.h header file provides functions that perform the basic common vector analysis operations.
-
template<typename T>
viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, 3> viskores::Cross(const viskores::Vec<T, 3> &x, const viskores::Vec<T, 3> &y) Find the cross product of two vectors.
If Viskores is compiled with FMA support, it uses Kahan’s difference of products algorithm to achieve a maximum error of 1.5 ulps in each component.
-
template<typename ValueType, typename WeightType>
inline ValueType viskores::Lerp(const ValueType &value0, const ValueType &value1, const WeightType &weight) Returns the linear interpolation of two values based on weight.
Lerpreturns the linear interpolation of two values based on a weight. Ifweightis outside [0,1] thenLerpextrapolates. Ifweight=0 thenvalue0is returned. Ifweight=1 thenvalue1is returned.
-
template<typename T>
detail::FloatingPointReturnType<T>::Type viskores::Magnitude(const T &x) Returns the magnitude of a vector.
It is usually much faster to compute MagnitudeSquared, so that should be substituted when possible (unless you are just going to take the square root, which would be besides the point). On some hardware it is also faster to find the reciprocal magnitude, so RMagnitude should be used if you actually plan to divide by the magnitude.
-
template<typename T>
detail::FloatingPointReturnType<T>::Type viskores::MagnitudeSquared(const T &x) Returns the square of the magnitude of a vector.
It is usually much faster to compute the square of the magnitude than the magnitude, so you should use this function in place of Magnitude or RMagnitude when possible.
-
template<typename T>
T viskores::Normal(const T &x) Returns a normalized version of the given vector.
The resulting vector points in the same direction but has unit length.
-
template<typename T>
void viskores::Normalize(T &x) Changes a vector to be normal.
The given vector is scaled to be unit length.
-
template<typename T, int N>
int viskores::Orthonormalize(const viskores::Vec<viskores::Vec<T, N>, N> &inputs, viskores::Vec<viskores::Vec<T, N>, N> &outputs, T tol = static_cast<T>(1e-6)) Convert a set of vectors to an orthonormal basis.
This function performs Gram-Schmidt orthonormalization for 3-D vectors. The first output vector will always be parallel to the first input vector. The remaining output vectors will be orthogonal and unit length and have the same handedness as their corresponding input vectors.
This method is geometric. It does not require a matrix solver. However, unlike the algebraic eigensolver techniques which do use matrix inversion, this method may return zero-length output vectors if some input vectors are collinear. The number of non-zero (to within the specified tolerance,
tol) output vectors is the return value.See https://en.wikipedia.org/wiki/Gram%E2%80%93Schmidt_process for details.
-
template<typename T, int N>
viskores::Vec<T, N> viskores::Project(const viskores::Vec<T, N> &v, const viskores::Vec<T, N> &u) Project a vector onto another vector.
This method computes the orthogonal projection of the vector v onto u; that is, it projects its first argument onto its second.
Note that if the vector
uhas zero length, the output vector will have all its entries equal to NaN.
-
template<typename T, int N>
T viskores::ProjectedDistance(const viskores::Vec<T, N> &v, const viskores::Vec<T, N> &u) Project a vector onto another vector, returning only the projected distance.
This method computes the orthogonal projection of the vector v onto u; that is, it projects its first argument onto its second.
Note that if the vector
uhas zero length, the output will be NaN.
-
template<typename T>
detail::FloatingPointReturnType<T>::Type viskores::RMagnitude(const T &x) Returns the reciprocal magnitude of a vector.
On some hardware
RMagnitudeis faster thanMagnitude, but neither is as fast asMagnitudeSquared. This function works on scalars as well as vectors, in which case it just returns the reciprocal of the scalar.
-
template<typename T>
viskores::Vec<typename detail::FloatingPointReturnType<T>::Type, 3> viskores::TriangleNormal(const viskores::Vec<T, 3> &a, const viskores::Vec<T, 3> &b, const viskores::Vec<T, 3> &c) Find the normal of a triangle.
Given three coordinates in space, which, unless degenerate, uniquely define a triangle and the plane the triangle is on, returns a vector perpendicular to that triangle/plane.
Note that the returned vector might not be a unit vector. In fact, the length is equal to twice the area of the triangle. If you want a unit vector, send the result through the
viskores::Normal()orviskores::Normalize()function.
4.6.3. Matrices
Linear algebra operations on small matrices that are done on a single thread are located in viskores/Matrix.h.
This header defines the viskores::Matrix templated class.
The template parameters are first the type of component, then the number of rows, then the number of columns.
The overloaded parentheses operator can be used to retrieve values based on row and column indices.
Likewise, the bracket operators can be used to reference the viskores::Matrix as a 2D array (indexed by row first).
-
template<typename T, viskores::IdComponent NumRow, viskores::IdComponent NumCol>
class Matrix Basic Matrix type.
The Matrix class holds a small two dimensional array for simple linear algebra and vector operations. Viskores provides several Matrix-based operations to assist in visualization computations.
A Matrix is not intended to hold very large arrays. Rather, they are a per-thread data structure to hold information like geometric transforms and tensors.
Public Functions
-
inline Matrix()
Creates an uninitialized matrix. The values in the matrix are not determined.
-
inline explicit Matrix(const ComponentType &value)
Creates a matrix initialized with all values set to the provided
value.
-
inline const viskores::Vec<ComponentType, NUM_COLUMNS> &operator[](viskores::IdComponent rowIndex) const
Brackets are used to reference a matrix like a 2D array (i.e.
matrix[row][column]).
-
inline viskores::Vec<ComponentType, NUM_COLUMNS> &operator[](viskores::IdComponent rowIndex)
Brackets are used to referens a matrix like a 2D array i.e.
matrix[row][column].
-
inline const ComponentType &operator()(viskores::IdComponent rowIndex, viskores::IdComponent colIndex) const
Parentheses are used to reference a matrix using mathematical tuple notation i.e.
matrix(row,column).
-
inline ComponentType &operator()(viskores::IdComponent rowIndex, viskores::IdComponent colIndex)
Parentheses are used to reference a matrix using mathematical tuple notation i.e.
matrix(row,column).
-
inline Matrix()
The following example builds a viskores::Matrix that contains the values
1 viskores::Matrix<viskores::Float32, 2, 3> matrix;
2
3 // Using parenthesis notation.
4 matrix(0, 0) = 0.0f;
5 matrix(0, 1) = 1.0f;
6 matrix(0, 2) = 2.0f;
7
8 // Using bracket notation.
9 matrix[1][0] = 10.0f;
10 matrix[1][1] = 11.0f;
11 matrix[1][2] = 12.0f;
The viskores/Matrix.h header also defines the following functions
that operate on matrices.
-
template<typename T, viskores::IdComponent Size>
T viskores::MatrixDeterminant(const viskores::Matrix<T, Size, Size> &A) Compute the determinant of a matrix.
-
template<typename T, viskores::IdComponent NumRow, viskores::IdComponent NumCol>
viskores::Vec<T, NumRow> viskores::MatrixGetColumn(const viskores::Matrix<T, NumRow, NumCol> &matrix, viskores::IdComponent columnIndex) Returns a tuple containing the given column (indexed from 0) of the given matrix.
Might not be as efficient as the
MatrixGetRow()function.
-
template<typename T, viskores::IdComponent NumRow, viskores::IdComponent NumCol>
const viskores::Vec<T, NumCol> &viskores::MatrixGetRow(const viskores::Matrix<T, NumRow, NumCol> &matrix, viskores::IdComponent rowIndex) Returns a tuple containing the given row (indexed from 0) of the given matrix.
-
template<typename T, viskores::IdComponent Size>
viskores::Matrix<T, Size, Size> viskores::MatrixIdentity() Returns the identity matrix.
-
template<typename T, viskores::IdComponent Size>
void viskores::MatrixIdentity(viskores::Matrix<T, Size, Size> &matrix) Fills the given matrix with the identity matrix.
-
template<typename T, viskores::IdComponent Size>
viskores::Matrix<T, Size, Size> viskores::MatrixInverse(const viskores::Matrix<T, Size, Size> &A, bool &valid) Find and return the inverse of the given matrix.
If the matrix is singular, the inverse will not be correct and valid will be set to false.
-
template<typename T, viskores::IdComponent NumRow, viskores::IdComponent NumCol, viskores::IdComponent NumInternal>
viskores::Matrix<T, NumRow, NumCol> viskores::MatrixMultiply(const viskores::Matrix<T, NumRow, NumInternal> &leftFactor, const viskores::Matrix<T, NumInternal, NumCol> &rightFactor) Standard matrix multiplication.
-
template<typename T, viskores::IdComponent NumRow, viskores::IdComponent NumCol>
viskores::Vec<T, NumRow> viskores::MatrixMultiply(const viskores::Matrix<T, NumRow, NumCol> &leftFactor, const viskores::Vec<T, NumCol> &rightFactor) Standard matrix-vector multiplication.
-
template<typename T, viskores::IdComponent NumRow, viskores::IdComponent NumCol>
viskores::Vec<T, NumCol> viskores::MatrixMultiply(const viskores::Vec<T, NumRow> &leftFactor, const viskores::Matrix<T, NumRow, NumCol> &rightFactor) Standard vector-matrix multiplication.
-
template<typename T, viskores::IdComponent NumRow, viskores::IdComponent NumCol>
void viskores::MatrixSetColumn(viskores::Matrix<T, NumRow, NumCol> &matrix, viskores::IdComponent columnIndex, const viskores::Vec<T, NumRow> &columnValues) Convenience function for setting a column of a matrix.
-
template<typename T, viskores::IdComponent NumRow, viskores::IdComponent NumCol>
void viskores::MatrixSetRow(viskores::Matrix<T, NumRow, NumCol> &matrix, viskores::IdComponent rowIndex, const viskores::Vec<T, NumCol> &rowValues) Convenience function for setting a row of a matrix.
4.6.4. Newton’s Method
Viskores’s matrix methods (documented in Section 4.6.3 (Matrices))
provide a method to solve a small linear system of equations. However,
sometimes it is necessary to solve a small nonlinear system of equations.
This can be done with the viskores::NewtonsMethod() function defined in the
viskores/NewtonsMethod.h header.
The viskores::NewtonsMethod() function assumes that the number of
variables equals the number of equations. Newton’s method operates on an
iterative evaluate and search. Evaluations are performed using the functors
passed into the viskores::NewtonsMethod().
-
template<typename ScalarType, viskores::IdComponent Size, typename JacobianFunctor, typename FunctionFunctor>
NewtonsMethodResult<ScalarType, Size> viskores::NewtonsMethod(JacobianFunctor jacobianEvaluator, FunctionFunctor functionEvaluator, viskores::Vec<ScalarType, Size> desiredFunctionOutput, viskores::Vec<ScalarType, Size> initialGuess = viskores::Vec<ScalarType, Size>(ScalarType(0)), ScalarType convergeDifference = ScalarType(1e-3), viskores::IdComponent maxIterations = 10) Uses Newton’s method (a.k.a.
Newton-Raphson method) to solve a nonlinear system of equations. This function assumes that the number of variables equals the number of equations. Newton’s method operates on an iterative evaluate and search. Evaluations are performed using the functors passed into the NewtonsMethod. The first functor returns the NxN matrix of the Jacobian at a given input point. The second functor returns the N tuple that is the function evaluation at the given input point. The input point that evaluates to the desired output, or the closest point found, is returned.
- Parameters:
jacobianEvaluator – [in] A functor whose operation takes a
viskores::Vecand returns aviskores::Matrixcontaining the math function’s Jacobian vector at that point.functionEvaluator – [in] A functor whose operation takes a
viskores::Vecand returns the evaluation of the math function at that point as anotherviskores::Vec.desiredFunctionOutput – [in] The desired output of the function.
initialGuess – [in] The initial guess to search from. If not specified, the origin is used.
convergeDifference – [in] The convergence distance. If the iterative method changes all values less than this amount. Once all values change less, it considers the solution found. If not specified, set to 0.001.
maxIterations – [in] The maximum amount of iterations to run before giving up and returning the best solution found. If not specified, set to 10.
- Returns:
A
viskores::NewtonsMethodResultcontaining the best found result and state about its validity.
The viskores::NewtonsMethod() function returns a viskores{NewtonsMethodResult} object.
textidentifier{NewtonsMethodResult} is a textcode{struct} templated on the type and number of input values of the nonlinear system.
textidentifier{NewtonsMethodResult} contains the following items.
-
template<typename ScalarType, viskores::IdComponent Size>
struct NewtonsMethodResult An object returned from
NewtonsMethod()that contains the result and other information about the final state.Public Members
-
bool Valid
True if Newton’s method ran into a singularity.
-
bool Converged
True if Newton’s method converted to below the convergence value.
-
viskores::Vec<ScalarType, Size> Solution
The solution found by Newton’s method.
If
Convergedis false, then this value is likely inaccurate. IfValidis false, then this value is undefined.
-
bool Valid
1// A functor for the mathematical function f(x) = [dot(x,x),x[0]*x[1]]
2struct FunctionFunctor
3{
4 template<typename T>
5 VISKORES_EXEC_CONT viskores::Vec<T, 2> operator()(const viskores::Vec<T, 2>& x) const
6 {
7 return viskores::make_Vec(viskores::Dot(x, x), x[0] * x[1]);
8 }
9};
10
11// A functor for the Jacobian of the mathematical function
12// f(x) = [dot(x,x),x[0]*x[1]], which is
13// | 2*x[0] 2*x[1] |
14// | x[1] x[0] |
15struct JacobianFunctor
16{
17 template<typename T>
18 VISKORES_EXEC_CONT viskores::Matrix<T, 2, 2> operator()(
19 const viskores::Vec<T, 2>& x) const
20 {
21 viskores::Matrix<T, 2, 2> jacobian;
22 jacobian(0, 0) = 2 * x[0];
23 jacobian(0, 1) = 2 * x[1];
24 jacobian(1, 0) = x[1];
25 jacobian(1, 1) = x[0];
26
27 return jacobian;
28 }
29};
30
31VISKORES_EXEC
32void SolveNonlinear()
33{
34 // Use Newton's method to solve the nonlinear system of equations:
35 //
36 // x^2 + y^2 = 2
37 // x*y = 1
38 //
39 // There are two possible solutions, which are (x=1,y=1) and (x=-1,y=-1).
40 // The one found depends on the starting value.
41 viskores::NewtonsMethodResult<viskores::Float32, 2> answer1 =
42 viskores::NewtonsMethod(JacobianFunctor(),
43 FunctionFunctor(),
44 viskores::make_Vec(2.0f, 1.0f),
45 viskores::make_Vec(1.0f, 0.0f));
46 if (!answer1.Valid || !answer1.Converged)
47 {
48 // Failed to find solution
49 }
50 // answer1.Solution is [1,1]
51
52 viskores::NewtonsMethodResult<viskores::Float32, 2> answer2 =
53 viskores::NewtonsMethod(JacobianFunctor(),
54 FunctionFunctor(),
55 viskores::make_Vec(2.0f, 1.0f),
56 viskores::make_Vec(0.0f, -2.0f));
57 if (!answer2.Valid || !answer2.Converged)
58 {
59 // Failed to find solution
60 }
61 // answer2 is [-1,-1]
62}