Merge topic 'guide-math'

e9ba5bf8c Add math section to users guide

Acked-by: Kitware Robot <kwrobot@kitware.com>
Reviewed-by: Vicente Bolea <vicente.bolea@kitware.com>
Merge-request: !3198
This commit is contained in:
Kenneth Moreland 2024-02-20 20:42:54 +00:00 committed by Kitware Robot
commit d8a7a9326c
10 changed files with 932 additions and 110 deletions

@ -16,6 +16,8 @@ set(examples
GuideExampleInitialization.cxx
GuideExampleIO.cxx
GuideExampleLists.cxx
GuideExampleMatrix.cxx
GuideExampleNewtonsMethod.cxx
GuideExampleProvidedFilters.cxx
GuideExampleRendering.cxx
GuideExampleRuntimeDeviceTracker.cxx

@ -0,0 +1,62 @@
//=============================================================================
//
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
//=============================================================================
#include <vtkm/Matrix.h>
#include <vtkm/testing/Testing.h>
namespace
{
VTKM_CONT
void BuildMatrix()
{
std::cout << "Building matrix containing " << std::endl
<< "| 0 1 2 |" << std::endl
<< "| 10 11 12 |" << std::endl;
////
//// BEGIN-EXAMPLE BuildMatrix
////
vtkm::Matrix<vtkm::Float32, 2, 3> matrix;
// Using parenthesis notation.
matrix(0, 0) = 0.0f;
matrix(0, 1) = 1.0f;
matrix(0, 2) = 2.0f;
// Using bracket notation.
matrix[1][0] = 10.0f;
matrix[1][1] = 11.0f;
matrix[1][2] = 12.0f;
////
//// END-EXAMPLE BuildMatrix
////
vtkm::Vec2f_32 termVec(1.0f, 0.1f);
vtkm::Vec3f_32 multVec = vtkm::MatrixMultiply(termVec, matrix);
// std::cout << multVec << std::endl;
VTKM_TEST_ASSERT(test_equal(multVec, vtkm::make_Vec(1.0, 2.1, 3.2)),
"Unexpected product.");
}
void Run()
{
BuildMatrix();
}
} // anonymous namespace
int GuideExampleMatrix(int argc, char* argv[])
{
return vtkm::testing::Testing::Run(Run, argc, argv);
}

@ -0,0 +1,113 @@
//=============================================================================
//
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
//=============================================================================
#include <vtkm/Matrix.h>
#include <vtkm/NewtonsMethod.h>
#include <vtkm/testing/Testing.h>
namespace
{
////
//// BEGIN-EXAMPLE NewtonsMethod
////
// A functor for the mathematical function f(x) = [dot(x,x),x[0]*x[1]]
struct FunctionFunctor
{
template<typename T>
VTKM_EXEC_CONT vtkm::Vec<T, 2> operator()(const vtkm::Vec<T, 2>& x) const
{
return vtkm::make_Vec(vtkm::Dot(x, x), x[0] * x[1]);
}
};
// A functor for the Jacobian of the mathematical function
// f(x) = [dot(x,x),x[0]*x[1]], which is
// | 2*x[0] 2*x[1] |
// | x[1] x[0] |
struct JacobianFunctor
{
template<typename T>
VTKM_EXEC_CONT vtkm::Matrix<T, 2, 2> operator()(const vtkm::Vec<T, 2>& x) const
{
vtkm::Matrix<T, 2, 2> jacobian;
jacobian(0, 0) = 2 * x[0];
jacobian(0, 1) = 2 * x[1];
jacobian(1, 0) = x[1];
jacobian(1, 1) = x[0];
return jacobian;
}
};
VTKM_EXEC
void SolveNonlinear()
{
// Use Newton's method to solve the nonlinear system of equations:
//
// x^2 + y^2 = 2
// x*y = 1
//
// There are two possible solutions, which are (x=1,y=1) and (x=-1,y=-1).
// The one found depends on the starting value.
vtkm::NewtonsMethodResult<vtkm::Float32, 2> answer1 =
vtkm::NewtonsMethod(JacobianFunctor(),
FunctionFunctor(),
vtkm::make_Vec(2.0f, 1.0f),
vtkm::make_Vec(1.0f, 0.0f));
if (!answer1.Valid || !answer1.Converged)
{
// Failed to find solution
//// PAUSE-EXAMPLE
VTKM_TEST_FAIL("Could not find answer1");
//// RESUME-EXAMPLE
}
// answer1.Solution is [1,1]
vtkm::NewtonsMethodResult<vtkm::Float32, 2> answer2 =
vtkm::NewtonsMethod(JacobianFunctor(),
FunctionFunctor(),
vtkm::make_Vec(2.0f, 1.0f),
vtkm::make_Vec(0.0f, -2.0f));
if (!answer2.Valid || !answer2.Converged)
{
// Failed to find solution
//// PAUSE-EXAMPLE
VTKM_TEST_FAIL("Could not find answer2");
//// RESUME-EXAMPLE
}
// answer2 is [-1,-1]
//// PAUSE-EXAMPLE
std::cout << answer1.Solution << " " << answer2.Solution << std::endl;
VTKM_TEST_ASSERT(test_equal(answer1.Solution, vtkm::make_Vec(1, 1), 0.01),
"Bad answer 1.");
VTKM_TEST_ASSERT(test_equal(answer2.Solution, vtkm::make_Vec(-1, -1), 0.01),
"Bad answer 2.");
//// RESUME-EXAMPLE
}
////
//// END-EXAMPLE NewtonsMethod
////
void Run()
{
SolveNonlinear();
}
} // anonymous namespace
int GuideExampleNewtonsMethod(int argc, char* argv[])
{
return vtkm::testing::Testing::Run(Run, argc, argv);
}

373
docs/users-guide/math.rst Normal file

@ -0,0 +1,373 @@
==============================
Math
==============================
.. index:: math
|VTKm| 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 ``vtkm`` package.
The functions are most useful in the execution environment, but they can also be used in the control environment when needed.
------------------------------
Basic Math
------------------------------
The :file:`vtkm/Math.h` header file contains several math functions that replicate the behavior of the basic POSIX math functions as well as related functionality.
.. didyouknow::
When writing worklets, you should favor using these math functions provided by |VTKm| over the standard math functions in :file:`vtkm/Math.h`.
|VTKm|'s implementation manages several compiling and efficiency issues when porting.
Exponentials
==============================
.. doxygenfunction:: vtkm::Exp(vtkm::Float32)
.. doxygenfunction:: vtkm::Exp(vtkm::Float64)
.. doxygenfunction:: vtkm::Exp(const T&)
.. doxygenfunction:: vtkm::Exp(const vtkm::Vec<T, N>&)
.. doxygenfunction:: vtkm::Exp10(vtkm::Float32)
.. doxygenfunction:: vtkm::Exp10(vtkm::Float64)
.. doxygenfunction:: vtkm::Exp10(T)
.. doxygenfunction:: vtkm::Exp10(const vtkm::Vec<T, N>&)
.. doxygenfunction:: vtkm::Exp2(vtkm::Float32)
.. doxygenfunction:: vtkm::Exp2(vtkm::Float64)
.. doxygenfunction:: vtkm::Exp2(const T&)
.. doxygenfunction:: vtkm::Exp2(const vtkm::Vec<T, N>&)
.. doxygenfunction:: vtkm::ExpM1(vtkm::Float32)
.. doxygenfunction:: vtkm::ExpM1(vtkm::Float64)
.. doxygenfunction:: vtkm::ExpM1(const T&)
.. doxygenfunction:: vtkm::ExpM1(const vtkm::Vec<T, N>&)
.. doxygenfunction:: vtkm::Log(vtkm::Float32)
.. doxygenfunction:: vtkm::Log(vtkm::Float64)
.. doxygenfunction:: vtkm::Log(const T&)
.. doxygenfunction:: vtkm::Log(const vtkm::Vec<T, N>&)
.. doxygenfunction:: vtkm::Log10(vtkm::Float32)
.. doxygenfunction:: vtkm::Log10(vtkm::Float64)
.. doxygenfunction:: vtkm::Log10(const T&)
.. doxygenfunction:: vtkm::Log10(const vtkm::Vec<T, N>&)
.. doxygenfunction:: vtkm::Log1P(vtkm::Float32)
.. doxygenfunction:: vtkm::Log1P(vtkm::Float64)
.. doxygenfunction:: vtkm::Log1P(const T&)
.. doxygenfunction:: vtkm::Log1P(const vtkm::Vec<T, N>&)
.. doxygenfunction:: vtkm::Log2(vtkm::Float32)
.. doxygenfunction:: vtkm::Log2(vtkm::Float64)
.. doxygenfunction:: vtkm::Log2(const T&)
.. doxygenfunction:: vtkm::Log2(const vtkm::Vec<T, N>&)
.. doxygenfunction:: vtkm::Pow(vtkm::Float32, vtkm::Float32)
.. doxygenfunction:: vtkm::Pow(vtkm::Float64, vtkm::Float64)
Non-finites
==============================
.. doxygenfunction:: Infinity
.. doxygenfunction:: Infinity32
.. doxygenfunction:: Infinity64
.. doxygenfunction:: IsFinite
.. doxygenfunction:: IsInf
.. doxygenfunction:: IsNan
.. doxygenfunction:: IsNegative(vtkm::Float32)
.. doxygenfunction:: IsNegative(vtkm::Float64)
.. doxygenfunction:: Nan
.. doxygenfunction:: Nan32
.. doxygenfunction:: Nan64
.. doxygenfunction:: NegativeInfinity
.. doxygenfunction:: NegativeInfinity32
.. doxygenfunction:: NegativeInfinity64
Polynomials
==============================
.. doxygenfunction:: vtkm::Cbrt(vtkm::Float32)
.. doxygenfunction:: vtkm::Cbrt(vtkm::Float64)
.. doxygenfunction:: vtkm::Cbrt(const T&)
.. doxygenfunction:: vtkm::Cbrt(const vtkm::Vec<T, N>&)
.. doxygenfunction:: vtkm::QuadraticRoots
.. doxygenfunction:: vtkm::RCbrt(vtkm::Float32)
.. doxygenfunction:: vtkm::RCbrt(vtkm::Float64)
.. doxygenfunction:: vtkm::RCbrt(T)
.. doxygenfunction:: vtkm::RCbrt(const vtkm::Vec<T, N>&)
.. doxygenfunction:: vtkm::RSqrt(vtkm::Float32)
.. doxygenfunction:: vtkm::RSqrt(vtkm::Float64)
.. doxygenfunction:: vtkm::RSqrt(T)
.. doxygenfunction:: vtkm::RSqrt(const vtkm::Vec<T, N>&)
.. doxygenfunction:: vtkm::Sqrt(vtkm::Float32)
.. doxygenfunction:: vtkm::Sqrt(vtkm::Float64)
.. doxygenfunction:: vtkm::Sqrt(const T&)
.. doxygenfunction:: vtkm::Sqrt(const vtkm::Vec<T, N>&)
Remainders and Quotient
==============================
.. doxygenfunction:: vtkm::ModF(vtkm::Float32, vtkm::Float32&)
.. doxygenfunction:: vtkm::ModF(vtkm::Float64, vtkm::Float64&)
.. doxygenfunction:: vtkm::Remainder(vtkm::Float32, vtkm::Float32)
.. doxygenfunction:: vtkm::Remainder(vtkm::Float64, vtkm::Float64)
.. doxygenfunction:: RemainderQuotient(vtkm::Float32, vtkm::Float32, QType&)
.. doxygenfunction:: RemainderQuotient(vtkm::Float64, vtkm::Float64, QType&)
Rounding and Precision
==============================
.. doxygenfunction:: vtkm::Ceil(vtkm::Float32)
.. doxygenfunction:: vtkm::Ceil(vtkm::Float64)
.. doxygenfunction:: vtkm::Ceil(const T&)
.. doxygenfunction:: vtkm::Ceil(const vtkm::Vec<T, N>&)
.. doxygenfunction:: vtkm::CopySign(vtkm::Float32, vtkm::Float32)
.. doxygenfunction:: vtkm::CopySign(vtkm::Float64, vtkm::Float64)
.. doxygenfunction:: vtkm::CopySign(const vtkm::Vec<T, N>&, const vtkm::Vec<T, N>&)
.. doxygenfunction:: Epsilon
.. doxygenfunction:: Epsilon32
.. doxygenfunction:: Epsilon64
.. doxygenfunction:: vtkm::FMod(vtkm::Float32, vtkm::Float32)
.. doxygenfunction:: vtkm::FMod(vtkm::Float64, vtkm::Float64)
.. doxygenfunction:: vtkm::Round(vtkm::Float32)
.. doxygenfunction:: vtkm::Round(vtkm::Float64)
.. doxygenfunction:: vtkm::Round(const T&)
.. doxygenfunction:: vtkm::Round(const vtkm::Vec<T, N>&)
Sign
==============================
.. doxygenfunction:: vtkm::Abs(vtkm::Int32)
.. doxygenfunction:: vtkm::Abs(vtkm::Int64)
.. doxygenfunction:: vtkm::Abs(vtkm::Float32)
.. doxygenfunction:: vtkm::Abs(vtkm::Float64)
.. doxygenfunction:: vtkm::Abs(T)
.. doxygenfunction:: vtkm::Abs(const vtkm::Vec<T, N>&)
.. doxygenfunction:: vtkm::Floor(vtkm::Float32)
.. doxygenfunction:: vtkm::Floor(vtkm::Float64)
.. doxygenfunction:: vtkm::Floor(const T&)
.. doxygenfunction:: vtkm::Floor(const vtkm::Vec<T, N>&)
.. doxygenfunction:: vtkm::SignBit(vtkm::Float32)
.. doxygenfunction:: vtkm::SignBit(vtkm::Float64)
Trigonometry
==============================
.. doxygenfunction:: vtkm::ACos(vtkm::Float32)
.. doxygenfunction:: vtkm::ACos(vtkm::Float64)
.. doxygenfunction:: vtkm::ACos(const T&)
.. doxygenfunction:: vtkm::ACos(const vtkm::Vec<T, N>&)
.. doxygenfunction:: vtkm::ACosH(vtkm::Float32)
.. doxygenfunction:: vtkm::ACosH(vtkm::Float64)
.. doxygenfunction:: vtkm::ACosH(const T&)
.. doxygenfunction:: vtkm::ACosH(const vtkm::Vec<T, N>&)
.. doxygenfunction:: vtkm::ASin(vtkm::Float32)
.. doxygenfunction:: vtkm::ASin(vtkm::Float64)
.. doxygenfunction:: vtkm::ASin(const T&)
.. doxygenfunction:: vtkm::ASin(const vtkm::Vec<T, N>&)
.. doxygenfunction:: vtkm::ASinH(vtkm::Float32)
.. doxygenfunction:: vtkm::ASinH(vtkm::Float64)
.. doxygenfunction:: vtkm::ASinH(const T&)
.. doxygenfunction:: vtkm::ASinH(const vtkm::Vec<T, N>&)
.. doxygenfunction:: vtkm::ATan(vtkm::Float32)
.. doxygenfunction:: vtkm::ATan(vtkm::Float64)
.. doxygenfunction:: vtkm::ATan(const T&)
.. doxygenfunction:: vtkm::ATan(const vtkm::Vec<T, N>&)
.. doxygenfunction:: vtkm::ATan2(vtkm::Float32, vtkm::Float32)
.. doxygenfunction:: vtkm::ATan2(vtkm::Float64, vtkm::Float64)
.. doxygenfunction:: vtkm::ATanH(vtkm::Float32)
.. doxygenfunction:: vtkm::ATanH(vtkm::Float64)
.. doxygenfunction:: vtkm::ATanH(const T&)
.. doxygenfunction:: vtkm::ATanH(const vtkm::Vec<T, N>&)
.. doxygenfunction:: vtkm::Cos(vtkm::Float32)
.. doxygenfunction:: vtkm::Cos(vtkm::Float64)
.. doxygenfunction:: vtkm::Cos(const T&)
.. doxygenfunction:: vtkm::Cos(const vtkm::Vec<T, N>&)
.. doxygenfunction:: vtkm::CosH(vtkm::Float32)
.. doxygenfunction:: vtkm::CosH(vtkm::Float64)
.. doxygenfunction:: vtkm::CosH(const T&)
.. doxygenfunction:: vtkm::CosH(const vtkm::Vec<T, N>&)
.. doxygenfunction:: Pi
.. doxygenfunction:: Pi_2
.. doxygenfunction:: Pi_3
.. doxygenfunction:: Pi_4
.. doxygenfunction:: Pi_180
.. doxygenfunction:: vtkm::Sin(vtkm::Float32)
.. doxygenfunction:: vtkm::Sin(vtkm::Float64)
.. doxygenfunction:: vtkm::Sin(const T&)
.. doxygenfunction:: vtkm::Sin(const vtkm::Vec<T, N>&)
.. doxygenfunction:: vtkm::SinH(vtkm::Float32)
.. doxygenfunction:: vtkm::SinH(vtkm::Float64)
.. doxygenfunction:: vtkm::SinH(const T&)
.. doxygenfunction:: vtkm::SinH(const vtkm::Vec<T, N>&)
.. doxygenfunction:: vtkm::Tan(vtkm::Float32)
.. doxygenfunction:: vtkm::Tan(vtkm::Float64)
.. doxygenfunction:: vtkm::Tan(const T&)
.. doxygenfunction:: vtkm::Tan(const vtkm::Vec<T, N>&)
.. doxygenfunction:: vtkm::TanH(vtkm::Float32)
.. doxygenfunction:: vtkm::TanH(vtkm::Float64)
.. doxygenfunction:: vtkm::TanH(const T&)
.. doxygenfunction:: vtkm::TanH(const vtkm::Vec<T, N>&)
.. doxygenfunction:: TwoPi
Miscellaneous
==============================
.. doxygenfunction:: FloatDistance(vtkm::Float64, vtkm::Float64)
.. doxygenfunction:: FloatDistance(vtkm::Float32, vtkm::Float32)
.. doxygenfunction:: Max(const T&, const T&)
.. doxygenfunction:: Min(const T&, const T&)
------------------------------
Vector Analysis
------------------------------
.. index:: vector analysis
Visualization and computational geometry algorithms often perform vector analysis operations.
The :file:`vtkm/VectorAnalysis.h` header file provides functions that perform the basic common vector analysis operations.
.. doxygenfunction:: vtkm::Cross
.. doxygenfunction:: vtkm::Lerp(const ValueType&, const ValueType&, const WeightType&)
.. doxygenfunction:: vtkm::Magnitude
.. doxygenfunction:: vtkm::MagnitudeSquared
.. doxygenfunction:: vtkm::Normal
.. doxygenfunction:: vtkm::Normalize
.. doxygenfunction:: vtkm::Orthonormalize
.. doxygenfunction:: vtkm::Project
.. doxygenfunction:: vtkm::ProjectedDistance
.. doxygenfunction:: vtkm::RMagnitude
.. doxygenfunction:: vtkm::TriangleNormal
------------------------------
Matrices
------------------------------
.. index:: matrix
Linear algebra operations on small matrices that are done on a single thread are located in :file:`vtkm/Matrix.h`.
This header defines the :class:`vtkm::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 :class:`vtkm::Matrix` as a 2D array (indexed by row first).
.. doxygenclass:: vtkm::Matrix
:members:
The following example builds a :class:`vtkm::Matrix` that contains the values
.. math::
\left|
\begin{array}{ccc}
0 & 1 & 2 \\
10 & 11 & 12
\end{array}
\right|
.. load-example:: BuildMatrix
:file: GuideExampleMatrix.cxx
:caption: Creating a :class:`vtkm::Matrix`.
The :file:`vtkm/Matrix.h` header also defines the following functions
that operate on matrices.
.. index::
single: matrix; determinant
single: determinant
.. doxygenfunction:: vtkm::MatrixDeterminant(const vtkm::Matrix<T, Size, Size>&)
.. doxygenfunction:: vtkm::MatrixGetColumn
.. doxygenfunction:: vtkm::MatrixGetRow
.. index::
double: identity; matrix
.. doxygenfunction:: vtkm::MatrixIdentity()
.. doxygenfunction:: vtkm::MatrixIdentity(vtkm::Matrix<T, Size, Size>&)
.. index::
double: inverse; matrix
.. doxygenfunction:: vtkm::MatrixInverse
.. doxygenfunction:: vtkm::MatrixMultiply(const vtkm::Matrix<T, NumRow, NumInternal>&, const vtkm::Matrix<T, NumInternal, NumCol>&)
.. doxygenfunction:: vtkm::MatrixMultiply(const vtkm::Matrix<T, NumRow, NumCol>&, const vtkm::Vec<T, NumCol>&)
.. doxygenfunction:: vtkm::MatrixMultiply(const vtkm::Vec<T, NumRow>&, const vtkm::Matrix<T, NumRow, NumCol>&)
.. doxygenfunction:: vtkm::MatrixSetColumn
.. doxygenfunction:: vtkm::MatrixSetRow
.. index::
double: transpose; matrix
.. doxygenfunction:: vtkm::MatrixTranspose
.. index:: linear system
.. doxygenfunction:: vtkm::SolveLinearSystem
------------------------------
Newton's Method
------------------------------
.. index:: Newton's method
|VTKm|'s matrix methods (documented in :secref:`math: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 :func:`vtkm::NewtonsMethod` function defined in the
:file:`vtkm/NewtonsMethod.h` header.
The :func:`vtkm::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 :func:`vtkm::NewtonsMethod`.
.. doxygenfunction:: vtkm::NewtonsMethod
The :func:`vtkm::NewtonsMethod` function returns a \vtkm{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.
.. doxygenstruct:: vtkm::NewtonsMethodResult
:members:
.. load-example:: NewtonsMethod
:file: GuideExampleNewtonsMethod.cxx
:caption: Using :func:`vtkm::NewtonsMethod` to solve a small system of nonlinear equations.

@ -9,3 +9,4 @@ Advanced Development
logging.rst
worklet-types.rst
worklet-error-handling.rst
math.rst

@ -159,6 +159,7 @@ static constexpr inline VTKM_EXEC_CONT vtkm::Float32 Pi_180f()
// clang-format off
///@{
/// Compute the sine of \p x.
///
@ -217,7 +218,9 @@ static inline VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<
return vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(vtkm::Sin(x[0]),
vtkm::Sin(x[1]));
}
///@}
///@{
/// Compute the cosine of \p x.
///
@ -276,7 +279,9 @@ static inline VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<
return vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(vtkm::Cos(x[0]),
vtkm::Cos(x[1]));
}
///@}
///@{
/// Compute the tangent of \p x.
///
@ -335,7 +340,9 @@ static inline VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<
return vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(vtkm::Tan(x[0]),
vtkm::Tan(x[1]));
}
///@}
///@{
/// Compute the arc sine of \p x.
///
@ -394,7 +401,9 @@ static inline VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<
return vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(vtkm::ASin(x[0]),
vtkm::ASin(x[1]));
}
///@}
///@{
/// Compute the arc cosine of \p x.
///
@ -453,7 +462,9 @@ static inline VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<
return vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(vtkm::ACos(x[0]),
vtkm::ACos(x[1]));
}
///@}
///@{
/// Compute the arc tangent of \p x.
///
@ -512,7 +523,9 @@ static inline VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<
return vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(vtkm::ATan(x[0]),
vtkm::ATan(x[1]));
}
///@}
///@{
/// Compute the arc tangent of \p x / \p y using the signs of both arguments
/// to determine the quadrant of the return value.
///
@ -532,7 +545,9 @@ static inline VTKM_EXEC_CONT vtkm::Float64 ATan2(vtkm::Float64 x, vtkm::Float64
return std::atan2(x, y);
#endif
}
///@}
///@{
/// Compute the hyperbolic sine of \p x.
///
@ -591,7 +606,9 @@ static inline VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<
return vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(vtkm::SinH(x[0]),
vtkm::SinH(x[1]));
}
///@}
///@{
/// Compute the hyperbolic cosine of \p x.
///
@ -650,7 +667,9 @@ static inline VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<
return vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(vtkm::CosH(x[0]),
vtkm::CosH(x[1]));
}
///@}
///@{
/// Compute the hyperbolic tangent of \p x.
///
@ -709,7 +728,9 @@ static inline VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<
return vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(vtkm::TanH(x[0]),
vtkm::TanH(x[1]));
}
///@}
///@{
/// Compute the hyperbolic arc sine of \p x.
///
@ -768,7 +789,9 @@ static inline VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<
return vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(vtkm::ASinH(x[0]),
vtkm::ASinH(x[1]));
}
///@}
///@{
/// Compute the hyperbolic arc cosine of \p x.
///
@ -827,7 +850,9 @@ static inline VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<
return vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(vtkm::ACosH(x[0]),
vtkm::ACosH(x[1]));
}
///@}
///@{
/// Compute the hyperbolic arc tangent of \p x.
///
@ -886,8 +911,10 @@ static inline VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<
return vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(vtkm::ATanH(x[0]),
vtkm::ATanH(x[1]));
}
///@}
//-----------------------------------------------------------------------------
///@{
/// Computes \p x raised to the power of \p y.
///
static inline VTKM_EXEC_CONT vtkm::Float32 Pow(vtkm::Float32 x, vtkm::Float32 y)
@ -906,9 +933,12 @@ static inline VTKM_EXEC_CONT vtkm::Float64 Pow(vtkm::Float64 x, vtkm::Float64 y)
return std::pow(x, y);
#endif
}
///@}
///@{
/// Compute the square root of \p x.
///
/// On some hardware it is faster to find the reciprocal square root, so `RSqrt`
/// should be used if you actually plan to divide by the square root.
inline VTKM_EXEC_CONT vtkm::Float32 Sqrt(vtkm::Float32 x)
{
@ -965,7 +995,9 @@ static inline VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<
return vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(vtkm::Sqrt(x[0]),
vtkm::Sqrt(x[1]));
}
///@}
///@{
/// Compute the reciprocal square root of \p x. The result of this function is
/// equivalent to <tt>1/Sqrt(x)</tt>. However, on some devices it is faster to
/// compute the reciprocal square root than the regular square root. Thus, you
@ -1033,7 +1065,9 @@ static inline VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<
return vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(vtkm::RSqrt(x[0]),
vtkm::RSqrt(x[1]));
}
///@}
///@{
/// Compute the cube root of \p x.
///
@ -1092,7 +1126,9 @@ static inline VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<
return vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(vtkm::Cbrt(x[0]),
vtkm::Cbrt(x[1]));
}
///@}
///@{
/// Compute the reciprocal cube root of \p x. The result of this function is
/// equivalent to <tt>1/Cbrt(x)</tt>. However, on some devices it is faster to
/// compute the reciprocal cube root than the regular cube root. Thus, you
@ -1160,8 +1196,10 @@ static inline VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<
return vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(vtkm::RCbrt(x[0]),
vtkm::RCbrt(x[1]));
}
///@}
/// Computes e**\p x, the base-e exponential of \p x.
///@{
/// Computes e^x, the base-e exponential of `x`.
///
inline VTKM_EXEC_CONT vtkm::Float32 Exp(vtkm::Float32 x)
@ -1219,8 +1257,10 @@ static inline VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<
return vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(vtkm::Exp(x[0]),
vtkm::Exp(x[1]));
}
///@}
/// Computes 2**\p x, the base-2 exponential of \p x.
///@{
/// Computes 2^x, the base-2 exponential of `x`.
///
inline VTKM_EXEC_CONT vtkm::Float32 Exp2(vtkm::Float32 x)
@ -1278,9 +1318,11 @@ static inline VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<
return vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(vtkm::Exp2(x[0]),
vtkm::Exp2(x[1]));
}
///@}
/// Computes (e**\p x) - 1, the of base-e exponental of \p x then minus 1. The
/// accuracy of this function is good even for very small values of x.
///@{
/// Computes (e^x) - 1, the of base-e exponental of `x` then minus 1. The
/// accuracy of this function is good even for very small values of `x`.
///
inline VTKM_EXEC_CONT vtkm::Float32 ExpM1(vtkm::Float32 x)
@ -1338,8 +1380,10 @@ static inline VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<
return vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(vtkm::ExpM1(x[0]),
vtkm::ExpM1(x[1]));
}
///@}
/// Computes 10**\p x, the base-10 exponential of \p x.
///@{
/// Computes 10^x, the base-10 exponential of `x`.
///
#ifdef VTKM_CUDA
static inline VTKM_EXEC_CONT vtkm::Float32 Exp10(vtkm::Float32 x)
@ -1403,7 +1447,9 @@ static inline VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<
return vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(vtkm::Exp10(x[0]),
vtkm::Exp10(x[1]));
}
///@}
///@{
/// Computes the natural logarithm of \p x.
///
@ -1462,7 +1508,9 @@ static inline VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<
return vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(vtkm::Log(x[0]),
vtkm::Log(x[1]));
}
///@}
///@{
/// Computes the logarithm base 2 of \p x.
///
@ -1521,7 +1569,9 @@ static inline VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<
return vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(vtkm::Log2(x[0]),
vtkm::Log2(x[1]));
}
///@}
///@{
/// Computes the logarithm base 10 of \p x.
///
@ -1580,9 +1630,11 @@ static inline VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<
return vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(vtkm::Log10(x[0]),
vtkm::Log10(x[1]));
}
///@}
/// Computes the value of log(1+x) accurately for very small values of x.
///
///@{
/// Computes the value of log(1+x). This method is more accurate for very small values of x
/// than the `vtkm::Log` function.
inline VTKM_EXEC_CONT vtkm::Float32 Log1P(vtkm::Float32 x)
{
@ -1639,8 +1691,10 @@ static inline VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<
return vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(vtkm::Log1P(x[0]),
vtkm::Log1P(x[1]));
}
///@}
//-----------------------------------------------------------------------------
///@{
/// Returns \p x or \p y, whichever is larger.
///
template <typename T>
@ -1672,7 +1726,9 @@ static inline VTKM_EXEC_CONT vtkm::Float64 Max(vtkm::Float64 x, vtkm::Float64 y)
#endif
}
#endif // !VTKM_USE_STL
///@}
///@{
/// Returns \p x or \p y, whichever is smaller.
///
template <typename T>
@ -1704,6 +1760,7 @@ static inline VTKM_EXEC_CONT vtkm::Float64 Min(vtkm::Float64 x, vtkm::Float64 y)
#endif
}
#endif // !VTKM_USE_STL
///@}
namespace detail
{
@ -1764,9 +1821,9 @@ static inline VTKM_EXEC_CONT T Min(const T& x, const T& y)
return detail::Min(x, y, typename vtkm::TypeTraits<T>::DimensionalityTag());
}
///@{
/// Clamp \p x to the given range.
///
inline VTKM_EXEC_CONT vtkm::Float32 Clamp(vtkm::Float32 x, vtkm::Float32 lo, vtkm::Float32 hi)
{
return x > lo ? (x < hi ? x : hi) : lo;
@ -1776,6 +1833,8 @@ inline VTKM_EXEC_CONT vtkm::Float64 Clamp(vtkm::Float64 x, vtkm::Float64 lo, vtk
{
return x > lo ? (x < hi ? x : hi) : lo;
}
///@}
//-----------------------------------------------------------------------------
//#ifdef VTKM_CUDA
@ -1945,33 +2004,49 @@ struct FloatLimits<vtkm::Vec<vtkm::Float64, N>>
} // namespace detail
/// Returns the representation for not-a-number (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
/// `Infinity` method is templated to specify either a 32 or 64 bit floating point
/// number. The convenience methods `Infinity32` and`Infinity64` are non-templated
/// versions that return the precision for a particular precision.
template <typename T>
static inline VTKM_EXEC_CONT T Nan()
{
return detail::FloatLimits<T>::Nan();
}
/// Returns the representation for 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` method is templated to specify either a 32 or 64 bit floating point
/// number. The convenience methods `Infinity32` and`Infinity64` are non-templated
/// versions that return the precision for a particular precision.
template <typename T>
static inline VTKM_EXEC_CONT T Infinity()
{
return detail::FloatLimits<T>::Infinity();
}
/// Returns the representation for negative infinity.
///
/// 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` method is templated to
/// specify either a 32 or 64 bit floating point number. The convenience methods
/// `NegativeInfinity32` and`NegativeInfinity64` are non-templated versions that
/// return the precision for a particular precision.
template <typename T>
static inline VTKM_EXEC_CONT T NegativeInfinity()
{
return detail::FloatLimits<T>::NegativeInfinity();
}
/// Returns the difference between 1 and the least value greater than 1
/// that is representable.
///
/// 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`
/// method is templated to specify either a 32 or 64 bit floating point number. The
/// convenience methods `Epsilon32` and`Epsilon64` are non-templated versions that
/// return the precision for a particular precision.
template <typename T>
static inline VTKM_EXEC_CONT T Epsilon()
{
@ -1980,33 +2055,49 @@ static inline VTKM_EXEC_CONT T Epsilon()
#else // !VTKM_USE_IEEE_NONFINITE
/// Returns the representation for not-a-number (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
/// `Infinity` method is templated to specify either a 32 or 64 bit floating point
/// number. The convenience methods `Infinity32` and`Infinity64` are non-templated
/// versions that return the precision for a particular precision.
template <typename T>
static inline VTKM_EXEC_CONT T Nan()
{
return std::numeric_limits<T>::quiet_NaN();
}
/// Returns the representation for 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` method is templated to specify either a 32 or 64 bit floating point
/// number. The convenience methods `Infinity32` and`Infinity64` are non-templated
/// versions that return the precision for a particular precision.
template <typename T>
static inline VTKM_EXEC_CONT T Infinity()
{
return std::numeric_limits<T>::infinity();
}
/// Returns the representation for negative infinity.
///
/// 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` method is templated to
/// specify either a 32 or 64 bit floating point number. The convenience methods
/// `NegativeInfinity32` and`NegativeInfinity64` are non-templated versions that
/// return the precision for a particular precision.
template <typename T>
static inline VTKM_EXEC_CONT T NegativeInfinity()
{
return -std::numeric_limits<T>::infinity();
}
/// Returns the difference between 1 and the least value greater than 1
/// that is representable.
///
/// 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`
/// method is templated to specify either a 32 or 64 bit floating point number. The
/// convenience methods `Epsilon32` and`Epsilon64` are non-templated versions that
/// return the precision for a particular precision.
template <typename T>
static inline VTKM_EXEC_CONT T Epsilon()
{
@ -2014,46 +2105,45 @@ static inline VTKM_EXEC_CONT T Epsilon()
}
#endif // !VTKM_USE_IEEE_NONFINITE
/// Returns the representation for not-a-number (NaN).
///
/// @copydoc Nan
static inline VTKM_EXEC_CONT vtkm::Float32 Nan32()
{
return vtkm::Nan<vtkm::Float32>();
}
/// @copydoc Nan
static inline VTKM_EXEC_CONT vtkm::Float64 Nan64()
{
return vtkm::Nan<vtkm::Float64>();
}
/// Returns the representation for infinity.
///
/// @copydoc Infinity
static inline VTKM_EXEC_CONT vtkm::Float32 Infinity32()
{
return vtkm::Infinity<vtkm::Float32>();
}
/// @copydoc Infinity
static inline VTKM_EXEC_CONT vtkm::Float64 Infinity64()
{
return vtkm::Infinity<vtkm::Float64>();
}
/// Returns the representation for negative infinity.
///
/// @copydoc NegativeInfinity
static inline VTKM_EXEC_CONT vtkm::Float32 NegativeInfinity32()
{
return vtkm::NegativeInfinity<vtkm::Float32>();
}
/// @copydoc NegativeInfinity
static inline VTKM_EXEC_CONT vtkm::Float64 NegativeInfinity64()
{
return vtkm::NegativeInfinity<vtkm::Float64>();
}
/// Returns the difference between 1 and the least value greater than 1
/// that is representable.
///
/// @copydoc Epsilon
static inline VTKM_EXEC_CONT vtkm::Float32 Epsilon32()
{
return vtkm::Epsilon<vtkm::Float32>();
}
/// @copydoc Epsilon
static inline VTKM_EXEC_CONT vtkm::Float64 Epsilon64()
{
return vtkm::Epsilon<vtkm::Float64>();
@ -2094,6 +2184,7 @@ static inline VTKM_EXEC_CONT bool IsFinite(T x)
}
//-----------------------------------------------------------------------------
///@{
/// Round \p x to the smallest integer value not less than x.
///
@ -2152,7 +2243,9 @@ static inline VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<
return vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(vtkm::Ceil(x[0]),
vtkm::Ceil(x[1]));
}
///@}
///@{
/// Round \p x to the largest integer value not greater than x.
///
@ -2211,7 +2304,9 @@ static inline VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<
return vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(vtkm::Floor(x[0]),
vtkm::Floor(x[1]));
}
///@}
///@{
/// Round \p x to the nearest integral value.
///
@ -2270,8 +2365,10 @@ static inline VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<
return vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 2>(vtkm::Round(x[0]),
vtkm::Round(x[1]));
}
///@}
//-----------------------------------------------------------------------------
///@{
/// Computes the remainder on division of 2 floating point numbers. The return
/// value is \p numerator - n \p denominator, where n is the quotient of \p
/// numerator divided by \p denominator rounded towards zero to an integer. For
@ -2293,7 +2390,9 @@ static inline VTKM_EXEC_CONT vtkm::Float64 FMod(vtkm::Float64 x, vtkm::Float64 y
return std::fmod(x, y);
#endif
}
///@}
///@{
/// Computes the remainder on division of 2 floating point numbers. The return
/// value is \p numerator - n \p denominator, where n is the quotient of \p
/// numerator divided by \p denominator rounded towards the nearest integer
@ -2325,7 +2424,9 @@ static inline VTKM_EXEC_CONT vtkm::Float64 Remainder(vtkm::Float64 x, vtkm::Floa
#endif
}
#endif // !VTKM_MSVC
///@}
///@{
/// Returns the remainder on division of 2 floating point numbers just like
/// Remainder. In addition, this function also returns the \c quotient used to
/// get that remainder.
@ -2361,7 +2462,9 @@ static inline VTKM_EXEC_CONT vtkm::Float64 RemainderQuotient(vtkm::Float64 numer
quotient = static_cast<QType>(iQuotient);
return result;
}
///@}
///@{
/// Gets the integral and fractional parts of \c x. The return value is the
/// fractional part and \c integral is set to the integral part.
///
@ -2382,8 +2485,10 @@ static inline VTKM_EXEC_CONT vtkm::Float64 ModF(vtkm::Float64 x, vtkm::Float64&
return std::modf(x, &integral);
#endif
}
///@}
//-----------------------------------------------------------------------------
///@{
/// Return the absolute value of \p x. That is, return \p x if it is positive or
/// \p -x if it is negative.
///
@ -2451,7 +2556,9 @@ static inline VTKM_EXEC_CONT vtkm::Vec<T, 2> Abs(const vtkm::Vec<T, 2>& x)
{
return vtkm::Vec<T, 2>(vtkm::Abs(x[0]), vtkm::Abs(x[1]));
}
///@}
///@{
/// Returns a nonzero value if \p x is negative.
///
static inline VTKM_EXEC_CONT vtkm::Int32 SignBit(vtkm::Float32 x)
@ -2468,7 +2575,9 @@ static inline VTKM_EXEC_CONT vtkm::Int32 SignBit(vtkm::Float64 x)
#endif
return static_cast<vtkm::Int32>(signbit(x));
}
///@}
///@{
/// Returns true if \p x is less than zero, false otherwise.
///
static inline VTKM_EXEC_CONT bool IsNegative(vtkm::Float32 x)
@ -2479,7 +2588,9 @@ static inline VTKM_EXEC_CONT bool IsNegative(vtkm::Float64 x)
{
return (vtkm::SignBit(x) != 0);
}
///@}
///@{
/// Copies the sign of \p y onto \p x. If \p y is positive, returns Abs(\p x).
/// If \p y is negative, returns -Abs(\p x).
///
@ -2511,10 +2622,11 @@ static inline VTKM_EXEC_CONT vtkm::Vec<T, N> CopySign(const vtkm::Vec<T, N>& x,
}
return result;
}
///@}
///@{
/// Decompose floating poing value
///
inline VTKM_EXEC_CONT vtkm::Float32 Frexp(vtkm::Float32 x, vtkm::Int32 *exponent)
{
// See: https://github.com/ROCm-Developer-Tools/HIP/issues/2169
@ -2533,6 +2645,7 @@ inline VTKM_EXEC_CONT vtkm::Float64 Frexp(vtkm::Float64 x, vtkm::Int32 *exponent
return std::frexp(x, exponent);
#endif
}
///@}
inline VTKM_EXEC_CONT vtkm::Float32 Ldexp(vtkm::Float32 x, vtkm::Int32 exponent)
{
@ -2601,6 +2714,9 @@ inline VTKM_EXEC_CONT vtkm::UInt64 FloatDistancePositive(vtkm::Float32 x, vtkm::
} // namespace detail
/// 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 VTKM_EXEC_CONT vtkm::UInt64 FloatDistance(vtkm::Float64 x, vtkm::Float64 y)
{
static_assert(sizeof(vtkm::Float64) == sizeof(vtkm::UInt64), "vtkm::Float64 is incorrect size.");
@ -2640,6 +2756,7 @@ inline VTKM_EXEC_CONT vtkm::UInt64 FloatDistance(vtkm::Float64 x, vtkm::Float64
return detail::FloatDistancePositive(x, y);
}
/// @copydoc FloatDistance
inline VTKM_EXEC_CONT vtkm::UInt64 FloatDistance(vtkm::Float32 x, vtkm::Float32 y)
{
static_assert(sizeof(vtkm::Float32) == sizeof(vtkm::Int32), "vtkm::Float32 is incorrect size.");
@ -2688,11 +2805,14 @@ inline VTKM_EXEC_CONT T DifferenceOfProducts(T a, T b, T c, T d)
return dop + err;
}
// Solves ax² + bx + c = 0.
// Only returns the real roots.
// If there are real roots, the first element of the pair is <= the second.
// If there are no real roots, both elements are NaNs.
// The error should be at most 3 ulps.
/// @brief 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 VTK-m 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.
template<typename T>
inline VTKM_EXEC_CONT vtkm::Vec<T, 2> QuadraticRoots(T a, T b, T c)
{

@ -309,74 +309,106 @@ static constexpr inline VTKM_EXEC_CONT vtkm::Float32 Pi_180f()
// clang-format off
///@{
/// Compute the sine of \p x.
///
$unary_math_function('Sin', 'sin')\
///@}
///@{
/// Compute the cosine of \p x.
///
$unary_math_function('Cos', 'cos')\
///@}
///@{
/// Compute the tangent of \p x.
///
$unary_math_function('Tan', 'tan')\
///@}
///@{
/// Compute the arc sine of \p x.
///
$unary_math_function('ASin', 'asin')\
///@}
///@{
/// Compute the arc cosine of \p x.
///
$unary_math_function('ACos', 'acos')\
///@}
///@{
/// Compute the arc tangent of \p x.
///
$unary_math_function('ATan', 'atan')\
///@}
///@{
/// Compute the arc tangent of \p x / \p y using the signs of both arguments
/// to determine the quadrant of the return value.
///
$binary_math_function('ATan2', 'atan2')\
///@}
///@{
/// Compute the hyperbolic sine of \p x.
///
$unary_math_function('SinH', 'sinh')\
///@}
///@{
/// Compute the hyperbolic cosine of \p x.
///
$unary_math_function('CosH', 'cosh')\
///@}
///@{
/// Compute the hyperbolic tangent of \p x.
///
$unary_math_function('TanH', 'tanh')\
///@}
///@{
/// Compute the hyperbolic arc sine of \p x.
///
$unary_math_function_no_vec('ASinH', 'asinh')\
$#
$unary_Vec_function('ASinH')\
///@}
///@{
/// Compute the hyperbolic arc cosine of \p x.
///
$unary_math_function_no_vec('ACosH', 'acosh')\
$#
$unary_Vec_function('ACosH')\
///@}
///@{
/// Compute the hyperbolic arc tangent of \p x.
///
$unary_math_function_no_vec('ATanH', 'atanh')\
$#
$unary_Vec_function('ATanH')\
///@}
//-----------------------------------------------------------------------------
///@{
/// Computes \p x raised to the power of \p y.
///
$binary_math_function('Pow', 'pow')\
///@}
///@{
/// Compute the square root of \p x.
///
/// On some hardware it is faster to find the reciprocal square root, so `RSqrt`
/// should be used if you actually plan to divide by the square root.
$unary_math_function('Sqrt', 'sqrt')\
///@}
///@{
/// Compute the reciprocal square root of \p x. The result of this function is
/// equivalent to <tt>1/Sqrt(x)</tt>. However, on some devices it is faster to
/// compute the reciprocal square root than the regular square root. Thus, you
@ -413,13 +445,17 @@ static inline VTKM_EXEC_CONT vtkm::Float64 RSqrt(T x)
#endif // !VTKM_CUDA
$unary_Vec_function('RSqrt')\
///@}
///@{
/// Compute the cube root of \p x.
///
$unary_math_function_no_vec('Cbrt', 'cbrt')\
$#
$unary_Vec_function('Cbrt')\
///@}
///@{
/// Compute the reciprocal cube root of \p x. The result of this function is
/// equivalent to <tt>1/Cbrt(x)</tt>. However, on some devices it is faster to
/// compute the reciprocal cube root than the regular cube root. Thus, you
@ -456,25 +492,33 @@ static inline VTKM_EXEC_CONT vtkm::Float64 RCbrt(T x)
#endif // !VTKM_CUDA
$unary_Vec_function('RCbrt')\
///@}
/// Computes e**\p x, the base-e exponential of \p x.
///@{
/// Computes e^x, the base-e exponential of `x`.
///
$unary_math_function('Exp', 'exp')\
///@}
/// Computes 2**\p x, the base-2 exponential of \p x.
///@{
/// Computes 2^x, the base-2 exponential of `x`.
///
$unary_math_function_no_vec('Exp2', 'exp2')\
$#
$unary_Vec_function('Exp2')\
///@}
/// Computes (e**\p x) - 1, the of base-e exponental of \p x then minus 1. The
/// accuracy of this function is good even for very small values of x.
///@{
/// Computes (e^x) - 1, the of base-e exponental of `x` then minus 1. The
/// accuracy of this function is good even for very small values of `x`.
///
$unary_math_function_no_vec('ExpM1', 'expm1')\
$#
$unary_Vec_function('ExpM1')\
///@}
/// Computes 10**\p x, the base-10 exponential of \p x.
///@{
/// Computes 10^x, the base-10 exponential of `x`.
///
#ifdef VTKM_CUDA
static inline VTKM_EXEC_CONT vtkm::Float32 Exp10(vtkm::Float32 x)
@ -507,28 +551,38 @@ static inline VTKM_EXEC_CONT vtkm::Float64 Exp10(T x)
#endif // !VTKM_CUDA
$unary_Vec_function('Exp10')\
///@}
///@{
/// Computes the natural logarithm of \p x.
///
$unary_math_function('Log', 'log')\
///@}
///@{
/// Computes the logarithm base 2 of \p x.
///
$unary_math_function_no_vec('Log2', 'log2')\
$#
$unary_Vec_function('Log2')\
///@}
///@{
/// Computes the logarithm base 10 of \p x.
///
$unary_math_function('Log10', 'log10')\
///@}
/// Computes the value of log(1+x) accurately for very small values of x.
///
///@{
/// Computes the value of log(1+x). This method is more accurate for very small values of x
/// than the `vtkm::Log` function.
$unary_math_function_no_vec('Log1P', 'log1p')\
$#
$unary_Vec_function('Log1P')\
///@}
//-----------------------------------------------------------------------------
///@{
/// Returns \p x or \p y, whichever is larger.
///
template <typename T>
@ -540,7 +594,9 @@ $#
$binary_math_function('Max', 'fmax')\
$#
#endif // !VTKM_USE_STL
///@}
///@{
/// Returns \p x or \p y, whichever is smaller.
///
template <typename T>
@ -552,6 +608,7 @@ $#
$binary_math_function('Min', 'fmin')\
$#
#endif // !VTKM_USE_STL
///@}
namespace detail
{
@ -612,9 +669,9 @@ static inline VTKM_EXEC_CONT T Min(const T& x, const T& y)
return detail::Min(x, y, typename vtkm::TypeTraits<T>::DimensionalityTag());
}
///@{
/// Clamp \p x to the given range.
///
inline VTKM_EXEC_CONT vtkm::Float32 Clamp(vtkm::Float32 x, vtkm::Float32 lo, vtkm::Float32 hi)
{
return x > lo ? (x < hi ? x : hi) : lo;
@ -624,6 +681,8 @@ inline VTKM_EXEC_CONT vtkm::Float64 Clamp(vtkm::Float64 x, vtkm::Float64 lo, vtk
{
return x > lo ? (x < hi ? x : hi) : lo;
}
///@}
//-----------------------------------------------------------------------------
//#ifdef VTKM_CUDA
@ -793,33 +852,49 @@ struct FloatLimits<vtkm::Vec<vtkm::Float64, N>>
} // namespace detail
/// Returns the representation for not-a-number (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
/// `Infinity` method is templated to specify either a 32 or 64 bit floating point
/// number. The convenience methods `Infinity32` and`Infinity64` are non-templated
/// versions that return the precision for a particular precision.
template <typename T>
static inline VTKM_EXEC_CONT T Nan()
{
return detail::FloatLimits<T>::Nan();
}
/// Returns the representation for 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` method is templated to specify either a 32 or 64 bit floating point
/// number. The convenience methods `Infinity32` and`Infinity64` are non-templated
/// versions that return the precision for a particular precision.
template <typename T>
static inline VTKM_EXEC_CONT T Infinity()
{
return detail::FloatLimits<T>::Infinity();
}
/// Returns the representation for negative infinity.
///
/// 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` method is templated to
/// specify either a 32 or 64 bit floating point number. The convenience methods
/// `NegativeInfinity32` and`NegativeInfinity64` are non-templated versions that
/// return the precision for a particular precision.
template <typename T>
static inline VTKM_EXEC_CONT T NegativeInfinity()
{
return detail::FloatLimits<T>::NegativeInfinity();
}
/// Returns the difference between 1 and the least value greater than 1
/// that is representable.
///
/// 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`
/// method is templated to specify either a 32 or 64 bit floating point number. The
/// convenience methods `Epsilon32` and`Epsilon64` are non-templated versions that
/// return the precision for a particular precision.
template <typename T>
static inline VTKM_EXEC_CONT T Epsilon()
{
@ -828,33 +903,49 @@ static inline VTKM_EXEC_CONT T Epsilon()
#else // !VTKM_USE_IEEE_NONFINITE
/// Returns the representation for not-a-number (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
/// `Infinity` method is templated to specify either a 32 or 64 bit floating point
/// number. The convenience methods `Infinity32` and`Infinity64` are non-templated
/// versions that return the precision for a particular precision.
template <typename T>
static inline VTKM_EXEC_CONT T Nan()
{
return std::numeric_limits<T>::quiet_NaN();
}
/// Returns the representation for 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` method is templated to specify either a 32 or 64 bit floating point
/// number. The convenience methods `Infinity32` and`Infinity64` are non-templated
/// versions that return the precision for a particular precision.
template <typename T>
static inline VTKM_EXEC_CONT T Infinity()
{
return std::numeric_limits<T>::infinity();
}
/// Returns the representation for negative infinity.
///
/// 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` method is templated to
/// specify either a 32 or 64 bit floating point number. The convenience methods
/// `NegativeInfinity32` and`NegativeInfinity64` are non-templated versions that
/// return the precision for a particular precision.
template <typename T>
static inline VTKM_EXEC_CONT T NegativeInfinity()
{
return -std::numeric_limits<T>::infinity();
}
/// Returns the difference between 1 and the least value greater than 1
/// that is representable.
///
/// 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`
/// method is templated to specify either a 32 or 64 bit floating point number. The
/// convenience methods `Epsilon32` and`Epsilon64` are non-templated versions that
/// return the precision for a particular precision.
template <typename T>
static inline VTKM_EXEC_CONT T Epsilon()
{
@ -862,46 +953,45 @@ static inline VTKM_EXEC_CONT T Epsilon()
}
#endif // !VTKM_USE_IEEE_NONFINITE
/// Returns the representation for not-a-number (NaN).
///
/// @copydoc Nan
static inline VTKM_EXEC_CONT vtkm::Float32 Nan32()
{
return vtkm::Nan<vtkm::Float32>();
}
/// @copydoc Nan
static inline VTKM_EXEC_CONT vtkm::Float64 Nan64()
{
return vtkm::Nan<vtkm::Float64>();
}
/// Returns the representation for infinity.
///
/// @copydoc Infinity
static inline VTKM_EXEC_CONT vtkm::Float32 Infinity32()
{
return vtkm::Infinity<vtkm::Float32>();
}
/// @copydoc Infinity
static inline VTKM_EXEC_CONT vtkm::Float64 Infinity64()
{
return vtkm::Infinity<vtkm::Float64>();
}
/// Returns the representation for negative infinity.
///
/// @copydoc NegativeInfinity
static inline VTKM_EXEC_CONT vtkm::Float32 NegativeInfinity32()
{
return vtkm::NegativeInfinity<vtkm::Float32>();
}
/// @copydoc NegativeInfinity
static inline VTKM_EXEC_CONT vtkm::Float64 NegativeInfinity64()
{
return vtkm::NegativeInfinity<vtkm::Float64>();
}
/// Returns the difference between 1 and the least value greater than 1
/// that is representable.
///
/// @copydoc Epsilon
static inline VTKM_EXEC_CONT vtkm::Float32 Epsilon32()
{
return vtkm::Epsilon<vtkm::Float32>();
}
/// @copydoc Epsilon
static inline VTKM_EXEC_CONT vtkm::Float64 Epsilon64()
{
return vtkm::Epsilon<vtkm::Float64>();
@ -942,28 +1032,37 @@ static inline VTKM_EXEC_CONT bool IsFinite(T x)
}
//-----------------------------------------------------------------------------
///@{
/// Round \p x to the smallest integer value not less than x.
///
$unary_math_function('Ceil', 'ceil')\
///@}
///@{
/// Round \p x to the largest integer value not greater than x.
///
$unary_math_function('Floor', 'floor')\
///@}
///@{
/// Round \p x to the nearest integral value.
///
$unary_math_function_no_vec('Round', 'round')\
$#
$unary_Vec_function('Round')\
///@}
//-----------------------------------------------------------------------------
///@{
/// Computes the remainder on division of 2 floating point numbers. The return
/// value is \p numerator - n \p denominator, where n is the quotient of \p
/// numerator divided by \p denominator rounded towards zero to an integer. For
/// example, <tt>FMod(6.5, 2.3)</tt> returns 1.9, which is 6.5 - 2*2.3.
///
$binary_math_function('FMod', 'fmod')\
///@}
///@{
/// Computes the remainder on division of 2 floating point numbers. The return
/// value is \p numerator - n \p denominator, where n is the quotient of \p
/// numerator divided by \p denominator rounded towards the nearest integer
@ -981,7 +1080,9 @@ static inline VTKM_EXEC_CONT T Remainder(T numerator, T denominator)
$binary_math_function('Remainder', 'remainder')\
$#
#endif // !VTKM_MSVC
///@}
///@{
/// Returns the remainder on division of 2 floating point numbers just like
/// Remainder. In addition, this function also returns the \c quotient used to
/// get that remainder.
@ -1017,7 +1118,9 @@ static inline VTKM_EXEC_CONT vtkm::Float64 RemainderQuotient(vtkm::Float64 numer
quotient = static_cast<QType>(iQuotient);
return result;
}
///@}
///@{
/// Gets the integral and fractional parts of \c x. The return value is the
/// fractional part and \c integral is set to the integral part.
///
@ -1038,8 +1141,10 @@ static inline VTKM_EXEC_CONT vtkm::Float64 ModF(vtkm::Float64 x, vtkm::Float64&
return std::modf(x, &integral);
#endif
}
///@}
//-----------------------------------------------------------------------------
///@{
/// Return the absolute value of \p x. That is, return \p x if it is positive or
/// \p -x if it is negative.
///
@ -1107,7 +1212,9 @@ static inline VTKM_EXEC_CONT vtkm::Vec<T, 2> Abs(const vtkm::Vec<T, 2>& x)
{
return vtkm::Vec<T, 2>(vtkm::Abs(x[0]), vtkm::Abs(x[1]));
}
///@}
///@{
/// Returns a nonzero value if \p x is negative.
///
$unary_template_function_no_vec('SignBit',
@ -1117,11 +1224,15 @@ $unary_template_function_no_vec('SignBit',
using std::signbit;
#endif
''')\
///@}
///@{
/// Returns true if \p x is less than zero, false otherwise.
///
$unary_template_function_no_vec('IsNegative', '(vtkm::SignBit(x) != 0)', 'bool')\
///@}
///@{
/// Copies the sign of \p y onto \p x. If \p y is positive, returns Abs(\p x).
/// If \p y is negative, returns -Abs(\p x).
///
@ -1139,10 +1250,11 @@ static inline VTKM_EXEC_CONT vtkm::Vec<T, N> CopySign(const vtkm::Vec<T, N>& x,
}
return result;
}
///@}
///@{
/// Decompose floating poing value
///
inline VTKM_EXEC_CONT vtkm::Float32 Frexp(vtkm::Float32 x, vtkm::Int32 *exponent)
{
// See: https://github.com/ROCm-Developer-Tools/HIP/issues/2169
@ -1161,6 +1273,7 @@ inline VTKM_EXEC_CONT vtkm::Float64 Frexp(vtkm::Float64 x, vtkm::Int32 *exponent
return std::frexp(x, exponent);
#endif
}
///@}
inline VTKM_EXEC_CONT vtkm::Float32 Ldexp(vtkm::Float32 x, vtkm::Int32 exponent)
{
@ -1229,6 +1342,9 @@ inline VTKM_EXEC_CONT vtkm::UInt64 FloatDistancePositive(vtkm::Float32 x, vtkm::
} // namespace detail
/// 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 VTKM_EXEC_CONT vtkm::UInt64 FloatDistance(vtkm::Float64 x, vtkm::Float64 y)
{
static_assert(sizeof(vtkm::Float64) == sizeof(vtkm::UInt64), "vtkm::Float64 is incorrect size.");
@ -1268,6 +1384,7 @@ inline VTKM_EXEC_CONT vtkm::UInt64 FloatDistance(vtkm::Float64 x, vtkm::Float64
return detail::FloatDistancePositive(x, y);
}
/// @copydoc FloatDistance
inline VTKM_EXEC_CONT vtkm::UInt64 FloatDistance(vtkm::Float32 x, vtkm::Float32 y)
{
static_assert(sizeof(vtkm::Float32) == sizeof(vtkm::Int32), "vtkm::Float32 is incorrect size.");
@ -1316,11 +1433,14 @@ inline VTKM_EXEC_CONT T DifferenceOfProducts(T a, T b, T c, T d)
return dop + err;
}
// Solves ax² + bx + c = 0.
// Only returns the real roots.
// If there are real roots, the first element of the pair is <= the second.
// If there are no real roots, both elements are NaNs.
// The error should be at most 3 ulps.
/// @brief 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 VTK-m 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.
template<typename T>
inline VTKM_EXEC_CONT vtkm::Vec<T, 2> QuadraticRoots(T a, T b, T c)
{

@ -19,7 +19,7 @@
namespace vtkm
{
/// \brief Basic Matrix type.
/// @brief Basic Matrix type.
///
/// The Matrix class holds a small two dimensional array for simple linear
/// algebra and vector operations. VTK-m provides several Matrix-based
@ -37,9 +37,11 @@ public:
static constexpr vtkm::IdComponent NUM_ROWS = NumRow;
static constexpr vtkm::IdComponent NUM_COLUMNS = NumCol;
/// Creates an uninitialized matrix. The values in the matrix are not determined.
VTKM_EXEC_CONT
Matrix() {}
/// Creates a matrix initialized with all values set to the provided `value`.
VTKM_EXEC_CONT
explicit Matrix(const ComponentType& value)
: Components(vtkm::Vec<ComponentType, NUM_COLUMNS>(value))
@ -110,7 +112,7 @@ VTKM_EXEC_CONT const vtkm::Vec<T, NumCol>& MatrixGetRow(
}
/// Returns a tuple containing the given column (indexed from 0) of the given
/// matrix. Might not be as efficient as the \c MatrixGetRow function.
/// matrix. Might not be as efficient as the `MatrixGetRow()` function.
///
template <typename T, vtkm::IdComponent NumRow, vtkm::IdComponent NumCol>
VTKM_EXEC_CONT vtkm::Vec<T, NumRow> MatrixGetColumn(const vtkm::Matrix<T, NumRow, NumCol>& matrix,
@ -439,7 +441,7 @@ VTKM_EXEC_CONT vtkm::Vec<T, Size> MatrixLUPSolve(
} // namespace detail
/// Solve the linear system Ax = b for x. If a single solution is found, valid
/// Solve the linear system Ax = b for x. If a single solution is found, `valid`
/// is set to true, false otherwise.
///
template <typename T, vtkm::IdComponent Size>

@ -16,11 +16,18 @@
namespace vtkm
{
/// An object returned from `NewtonsMethod()` that contains the result and
/// other information about the final state.
template <typename ScalarType, vtkm::IdComponent Size>
struct NewtonsMethodResult
{
/// True if Newton's method ran into a singularity.
bool Valid;
/// True if Newton's method converted to below the convergence value.
bool Converged;
/// The solution found by Newton's method. If `Converged` is false,
/// then this value is likely inaccurate. If `Valid` is false, then
/// this value is undefined.
vtkm::Vec<ScalarType, Size> Solution;
};
@ -34,6 +41,23 @@ struct NewtonsMethodResult
/// that evaluates to the desired output, or the closest point found, is
/// returned.
///
/// @param[in] jacobianEvaluator A functor whose operation takes a `vtkm::Vec`
/// and returns a `vtkm::Matrix` containing the math function's
/// Jacobian vector at that point.
/// @param[in] functionEvaluator A functor whose operation takes a `vtkm::Vec`
/// and returns the evaluation of the math function at that point as
/// another `vtkm::Vec`.
/// @param[in] desiredFunctionOutput The desired output of the function.
/// @param[in] initialGuess The initial guess to search from. If not specified,
/// the origin is used.
/// @param[in] convergeDifference 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.
/// @param[in] maxIterations The maximum amount of iterations to run before giving up and
/// returning the best solution found. If not specified, set to 10.
///
/// @returns A `vtkm::NewtonsMethodResult` containing the best found result and state
/// about its validity.
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename ScalarType,
vtkm::IdComponent Size,

@ -21,12 +21,12 @@ namespace vtkm
{
// ----------------------------------------------------------------------------
/// \brief Returns the linear interpolation of two values based on weight
/// @brief Returns the linear interpolation of two values based on weight
///
/// \c Lerp interpolates return the linerar interpolation of v0 and v1 based on w. v0
/// and v1 are scalars or vectors of same length. w can either be a scalar or a
/// vector of the same length as x and y. If w is outside [0,1] then lerp
/// extrapolates. If w=0 => v0 is returned if w=1 => v1 is returned.
/// `Lerp` returns the linear interpolation of two values based on a weight. If
/// `weight` is outside [0,1] then `Lerp`
/// extrapolates. If `weight`=0 then `value0` is returned. If `weight`=1 then
/// `value1` is returned.
///
template <typename ValueType, typename WeightType>
inline VTKM_EXEC_CONT ValueType Lerp(const ValueType& value0,
@ -54,10 +54,10 @@ VTKM_EXEC_CONT vtkm::Vec<ValueType, N> Lerp(const vtkm::Vec<ValueType, N>& value
}
// ----------------------------------------------------------------------------
/// \brief Returns the square of the magnitude of a vector.
/// @brief Returns the square of the magnitude of a vector.
///
/// It is usually much faster to compute the square of the magnitude than the
/// square, so you should use this function in place of Magnitude or RMagnitude
/// magnitude, so you should use this function in place of Magnitude or RMagnitude
/// when possible.
///
template <typename T>
@ -88,7 +88,7 @@ VTKM_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type MagnitudeTempla
} // namespace detail
/// \brief Returns the magnitude of a vector.
/// @brief 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
@ -122,10 +122,11 @@ VTKM_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type RMagnitudeTempl
}
} // namespace detail
/// \brief Returns the reciprocal magnitude of a vector.
/// @brief Returns the reciprocal magnitude of a vector.
///
/// On some hardware RMagnitude is faster than Magnitude, but neither is
/// as fast as MagnitudeSquared.
/// On some hardware `RMagnitude` is faster than `Magnitude`, but neither is
/// as fast as `MagnitudeSquared`. This function works on scalars as well
/// as vectors, in which case it just returns the reciprocal of the scalar.
///
template <typename T>
VTKM_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type RMagnitude(const T& x)
@ -149,7 +150,7 @@ VTKM_EXEC_CONT T NormalTemplate(const T& x, vtkm::TypeTraitsVectorTag)
}
} // namespace detail
/// \brief Returns a normalized version of the given vector.
/// @brief Returns a normalized version of the given vector.
///
/// The resulting vector points in the same direction but has unit length.
///
@ -160,7 +161,7 @@ VTKM_EXEC_CONT T Normal(const T& x)
}
// ----------------------------------------------------------------------------
/// \brief Changes a vector to be normal.
/// @brief Changes a vector to be normal.
///
/// The given vector is scaled to be unit length.
///
@ -171,8 +172,10 @@ VTKM_EXEC_CONT void Normalize(T& x)
}
// ----------------------------------------------------------------------------
/// \brief Find the cross product of two vectors.
/// @brief Find the cross product of two vectors.
///
/// If VTK-m 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 T>
VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 3> Cross(
const vtkm::Vec<T, 3>& x,
@ -185,7 +188,7 @@ VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 3> C
}
//-----------------------------------------------------------------------------
/// \brief Find the normal of a triangle.
/// @brief 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
@ -193,7 +196,7 @@ VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 3> C
///
/// 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 \c Normal function.
/// send the result through the `vtkm::Normal()` or `vtkm::Normalize()` function.
///
template <typename T>
VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 3>
@ -203,12 +206,12 @@ TriangleNormal(const vtkm::Vec<T, 3>& a, const vtkm::Vec<T, 3>& b, const vtkm::V
}
//-----------------------------------------------------------------------------
/// \brief Project a vector onto another vector.
/// @brief 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 \a u has zero length, the output
/// Note that if the vector `u` has zero length, the output
/// vector will have all its entries equal to NaN.
template <typename T, int N>
VTKM_EXEC_CONT vtkm::Vec<T, N> Project(const vtkm::Vec<T, N>& v, const vtkm::Vec<T, N>& u)
@ -221,12 +224,12 @@ VTKM_EXEC_CONT vtkm::Vec<T, N> Project(const vtkm::Vec<T, N>& v, const vtkm::Vec
}
//-----------------------------------------------------------------------------
/// \brief Project a vector onto another vector, returning only the projected distance.
/// @brief 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 \a u has zero length, the output will be NaN.
/// Note that if the vector `u` has zero length, the output will be NaN.
template <typename T, int N>
VTKM_EXEC_CONT T ProjectedDistance(const vtkm::Vec<T, N>& v, const vtkm::Vec<T, N>& u)
{
@ -237,9 +240,9 @@ VTKM_EXEC_CONT T ProjectedDistance(const vtkm::Vec<T, N>& v, const vtkm::Vec<T,
}
//-----------------------------------------------------------------------------
/// \brief Perform Gram-Schmidt orthonormalization for 3-D vectors.
/// @brief Convert a set of vectors to an orthonormal basis.
///
/// See https://en.wikipedia.org/wiki/Gram%E2%80%93Schmidt_process for details.
/// 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.
@ -249,7 +252,9 @@ VTKM_EXEC_CONT T ProjectedDistance(const vtkm::Vec<T, N>& v, const vtkm::Vec<T,
/// 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, \a tol ) output vectors is the return value.
/// 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>
VTKM_EXEC_CONT int Orthonormalize(const vtkm::Vec<vtkm::Vec<T, N>, N>& inputs,
vtkm::Vec<vtkm::Vec<T, N>, N>& outputs,