std::sqrt(std::valarray)
来自 cppreference.com
定义在头文件 <valarray> 中 |
||
template< class T > valarray<T> sqrt( const valarray<T>& va ); |
||
对于 va 中的每个元素,计算元素值的平方根。
内容 |
[编辑] 参数
va | - | 要应用操作的值数组 |
[编辑] 返回值
包含 va 中值的平方根的值数组。
[编辑] 注释
使用非限定函数 (sqrt) 来执行计算。如果该函数不可用,则由于 依赖于参数的查找,将使用 std::sqrt。
该函数可以用与 std::valarray 不同的返回类型实现。在这种情况下,替换类型具有以下属性
- 提供了 std::valarray 的所有 const 成员函数。
- 可以从替换类型构造 std::valarray、std::slice_array、std::gslice_array、std::mask_array 和 std::indirect_array。
- 对于每个接受 const std::valarray<T>& 的函数 除了 begin() 和 end()(自 C++11 起),将添加接受替换类型的相同函数;
- 对于每个接受两个 const std::valarray<T>& 参数的函数,将添加接受 const std::valarray<T>& 和替换类型的每种组合的相同函数。
- 返回类型在最深嵌套的参数类型上不会添加超过两层的模板嵌套。
[编辑] 可能的实现
template<class T> valarray<T> sqrt(const valarray<T>& va) { valarray<T> other = va; for (T& i : other) i = sqrt(i); return other; // proxy object may be returned } |
[编辑] 示例
一次找到所有三个根(其中两个可以是共轭复数)三次方程。
运行此代码
#include <cassert> #include <complex> #include <cstddef> #include <iostream> #include <numbers> #include <valarray> using CD = std::complex<double>; using VA = std::valarray<CD>; // return all n complex roots out of a given complex number x VA root(CD x, unsigned n) { const double mag = std::pow(std::abs(x), 1.0 / n); const double step = 2.0 * std::numbers::pi / n; double phase = std::arg(x) / n; VA v(n); for (std::size_t i{}; i != n; ++i, phase += step) v[i] = std::polar(mag, phase); return v; } // return n complex roots of each element in v; in the output valarray first // goes the sequence of all n roots of v[0], then all n roots of v[1], etc. VA root(VA v, unsigned n) { VA o(v.size() * n); VA t(n); for (std::size_t i = 0; i != v.size(); ++i) { t = root(v[i], n); for (unsigned j = 0; j != n; ++j) o[n * i + j] = t[j]; } return o; } // floating-point numbers comparator that tolerates given rounding error inline bool is_equ(CD x, CD y, double tolerance = 0.000'000'001) { return std::abs(std::abs(x) - std::abs(y)) < tolerance; } int main() { // input coefficients for polynomial x³ + p·x + q const VA p{1, 2, 3, 4, 5, 6, 7, 8}; const VA q{1, 2, 3, 4, 5, 6, 7, 8}; // the solver const VA d = std::sqrt(std::pow(q / 2, 2) + std::pow(p / 3, 3)); const VA u = root(-q / 2 + d, 3); const VA n = root(-q / 2 - d, 3); // allocate memory for roots: 3 * number of input cubic polynomials VA x[3]; for (std::size_t t = 0; t != 3; ++t) x[t].resize(p.size()); auto is_proper_root = [](CD a, CD b, CD p) { return is_equ(a * b + p / 3.0, 0.0); }; // sieve out 6 out of 9 generated roots, leaving only 3 proper roots (per polynomial) for (std::size_t i = 0; i != p.size(); ++i) for (std::size_t j = 0, r = 0; j != 3; ++j) for (std::size_t k = 0; k != 3; ++k) if (is_proper_root(u[3 * i + j], n[3 * i + k], p[i])) x[r++][i] = u[3 * i + j] + n[3 * i + k]; std::cout << "Depressed cubic equation: Root 1: \t\t Root 2: \t\t Root 3:\n"; for (std::size_t i = 0; i != p.size(); ++i) { std::cout << "x³ + " << p[i] << "·x + " << q[i] << " = 0 " << std::fixed << x[0][i] << " " << x[1][i] << " " << x[2][i] << std::defaultfloat << '\n'; assert(is_equ(std::pow(x[0][i], 3) + x[0][i] * p[i] + q[i], 0.0)); assert(is_equ(std::pow(x[1][i], 3) + x[1][i] * p[i] + q[i], 0.0)); assert(is_equ(std::pow(x[2][i], 3) + x[2][i] * p[i] + q[i], 0.0)); } }
输出
Depressed cubic equation: Root 1: Root 2: Root 3: x³ + (1,0)·x + (1,0) = 0 (-0.682328,0.000000) (0.341164,1.161541) (0.341164,-1.161541) x³ + (2,0)·x + (2,0) = 0 (-0.770917,0.000000) (0.385458,1.563885) (0.385458,-1.563885) x³ + (3,0)·x + (3,0) = 0 (-0.817732,0.000000) (0.408866,1.871233) (0.408866,-1.871233) x³ + (4,0)·x + (4,0) = 0 (-0.847708,0.000000) (0.423854,2.130483) (0.423854,-2.130483) x³ + (5,0)·x + (5,0) = 0 (-0.868830,0.000000) (0.434415,2.359269) (0.434415,-2.359269) x³ + (6,0)·x + (6,0) = 0 (-0.884622,0.000000) (0.442311,2.566499) (0.442311,-2.566499) x³ + (7,0)·x + (7,0) = 0 (-0.896922,0.000000) (0.448461,2.757418) (0.448461,-2.757418) x³ + (8,0)·x + (8,0) = 0 (-0.906795,0.000000) (0.453398,2.935423) (0.453398,-2.935423)
[编辑] 参见
将函数 std::pow 应用于两个 valarrays 或一个 valarray 和一个值 (函数模板) | |
(C++11)(C++11) |
计算平方根 (√x) (函数) |
右半平面范围内的复数平方根 (函数模板) |