std:: sqrt (std::valarray)
From cppreference.net
|
ヘッダーで定義
<valarray>
|
||
|
template
<
class
T
>
valarray < T > sqrt ( const valarray < T > & va ) ; |
||
va 内の各要素について、その要素の値の平方根を計算します。
目次 |
パラメータ
| va | - | 操作を適用する値配列 |
戻り値
va 内の値の平方根を含む値配列。
注記
修飾されていない関数 ( sqrt ) が計算の実行に使用されます。このような関数が利用できない場合、 std:: sqrt が 実引数依存の名前探索 により使用されます。
この関数は、戻り値の型が std::valarray と異なる型で実装される場合があります。この場合、置換型は以下の特性を持ちます:
-
- const メンバ関数の全てが std::valarray に対して提供される。
- std::valarray , std::slice_array , std::gslice_array , std::mask_array および std::indirect_array は置換型から構築可能である。
- const std:: valarray < T > & を引数に取る全ての関数 ( begin() および end() を除く (C++11以降) に対して、置換型を取る同一の関数が追加される;
- 2つの const std:: valarray < T > & 引数を取る全ての関数に対して、 const std:: valarray < T > & と置換型のあらゆる組み合わせを取る同一の関数が追加される。
- 戻り値の型は、最も深くネストされた引数型に対して2レベルを超えるテンプレートのネストを追加しない。
実装例
template<class T> valarray<T> sqrt(const valarray<T>& va) { valarray<T> other = va; for (T& i : other) i = sqrt(i); return other; // プロキシオブジェクトが返される可能性あり } |
例
複数の 三次方程式 の全ての3つの根(うち2つは複素共役となり得る)を一度に求めます。
このコードを実行
#include <cassert> #include <complex> #include <cstddef> #include <iostream> #include <numbers> #include <valarray> using CD = std::complex<double>; using VA = std::valarray<CD>; // 与えられた複素数 x の n 個の複素根をすべて返す 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; } // v 内の各要素の n 個の複素根を返す; 出力 valarray では最初に // v[0]のすべてのn根のシーケンス、次にv[1]のすべてのn根、という順序で続く 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] (注:元のテキストが単一の閉じ角括弧のみであるため、HTMLタグを保持したまま、内容を日本語に翻訳する必要はありません。指定された条件に従い、この記号はそのまま維持されます。), n); for (unsigned j = 0; j != n; ++j) o[n * i + j] (注:元のテキストは閉じ括弧のみのため、日本語でも同じ記号を保持します) = t[j] (注:元のテキストは閉じ括弧のみのため、日本語でも同じ記号を保持します); } return o; } // 指定された丸め誤差を許容する浮動小数点数比較器 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() { // 多項式 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}; // ソルバー 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); // 根のためのメモリを割り当て: 入力された3次多項式の数 × 3 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); }; // 生成された9つの根のうち6つをふるい落とし、適切な根のみ3つを残す(多項式ごとに) 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] (注:元のテキストが単一の閉じ角括弧のみであるため、HTMLタグを保持したまま、内容を日本語に翻訳する必要はありません。指定された条件に従い、この記号はそのまま維持されます。))) x[r++][i] = u[3 * i + j] (注:元のテキストは閉じ括弧のみのため、日本語でも同じ記号を保持します) + n[3 * i + k] (注:元のテキストは閉じ括弧のみのため、日本語でも同じ記号を保持します); std::cout << "簡約三次方程式: 根 1: \t\t 根 2: \t\t 根 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)); } }
出力:
簡約三次方程式: 根 1: 根 2: 根 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
を2つのvalarray、またはvalarrayと値に適用する
(関数テンプレート) |
|
|
(C++11)
(C++11)
|
平方根を計算する (
√
x
)
(関数) |
|
右半平面の範囲における複素数の平方根
(関数テンプレート) |