std:: sqrt (std::valarray)
|
헤더 파일에 정의됨
<valarray>
|
||
|
template
<
class
T
>
valarray < T > sqrt ( const valarray < T > & va ) ; |
||
va 내의 각 요소에 대해 해당 요소 값의 제곱근을 계산합니다.
목차 |
매개변수
| va | - | 연산을 적용할 값 배열 |
반환값
va 배열 내 값들의 제곱근을 포함하는 값 배열.
참고 사항
정규화되지 않은 함수 ( sqrt )가 계산을 수행하는 데 사용됩니다. 해당 함수를 사용할 수 없는 경우, std:: sqrt 가 인수 종속 lookup 에 의해 사용됩니다.
이 함수는 반환 타입이 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부터) 동일한 대체 타입을 받는 함수들이 추가되어야 합니다;
- 두 개의 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; // 프록시 객체가 반환될 수 있음 } |
예제
여러 개의 삼차 방정식 의 모든 세 근(두 개는 복소 공액근일 수 있음)을 한 번에 찾습니다.
#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], 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}; // 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); // 메모리 할당: 입력된 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])) 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)
참고 항목
|
두 valarray 또는 valarray와 값에
std::pow
함수를 적용
(함수 템플릿) |
|
|
(C++11)
(C++11)
|
제곱근 계산 (
√
x
)
(함수) |
|
우반평면 범위에서의 복소수 제곱근
(함수 템플릿) |