Marcin Klocek, T-RTM
Biblioteka boost::math zawiera sześć funkcji operujących na liczbach zespolonych. Są to odwrotne funkcje trygonometryczne, które zostały zaprojektowane w taki sposób, aby zapewnić zgodność z funkcjami trygonometrycznymi dla liczb zespolonych dostępnymi w C++. Jednocześnie funkcje te zwracają poprawne wyniki nawet dla krańcowych wartości parametru. Maksymalny błąd względny metody zastosowanej do wyliczania tych funkcji szacowany jest na 10-9.
Plik nagłówkowy:
#include <boost/math/complex/asin.hpp>
Postać funkcji:
template<class T> std::complex<T> asin(const std::complex<T>& z);
Plik nagłówkowy:
#include <boost/math/complex/acos.hpp>
Postać funkcji:
template<class T> std::complex<T> acos(const std::complex<T>& z);
Plik nagłówkowy:
#include <boost/math/complex/atan.hpp>
Postać funkcji:
template<class T> std::complex<T> atan(const std::complex<T>& z);
Plik nagłówkowy:
#include <boost/math/complex/asinh.hpp>
Postać funkcji:
template<class T> std::complex<T> asinh(const std::complex<T>& z);
Plik nagłówkowy:
#include <boost/math/complex/acosh.hpp>
Postać funkcji:
template<class T> std::complex<T> acosh(const std::complex<T>& z);
Plik nagłówkowy:
#include <boost/math/complex/atanh.hpp>
Postać funkcji:
template<class T> std::complex<T> atanh(const std::complex<T>& z);
Poniższy program oblicza wartość funkcji trygonometrycznych dla danej liczby zespolonej korzystając z funkcji dostępnych w C++. Wynik jest następnie odwracany przy wykorzystaniu frunkcji z boost::math. Na ekranie wyświetlane są wyniki, a także względny błąd obliczenia części rzeczywistej i urojonej.
complex_boost_example.cpp:
/***************************************************************** * Program testujacy odwrotne funkcje trygonometryczne dla liczb * * zespolonych zawarte w bibliotece boost::math pod katem ich * * zgodnosci z funkcjami trygonometrycznymi w bibliotece std. * * Dodatkowo wyswietlane sa wzgledne bledy okreslenia czesci * * rzeczywistej i urojonej. * * * * Ze wzgledu na okresowosc funkcji trygonometrycznych nalezy * * uzywac wartosci z przedzialu <-pi/2; pi/2>. * *****************************************************************/ #include <complex> #include <boost/math/complex/asin.hpp> #include <boost/math/complex/acos.hpp> #include <boost/math/complex/atan.hpp> #include <boost/math/complex/asinh.hpp> #include <boost/math/complex/acosh.hpp> #include <boost/math/complex/atanh.hpp> int main() { double re; double im; char sign; std::cout << "Podaj liczbe zespolona w postaci X + jY: "; std::cin >> re; std::cin >> sign; //zebranie znaku getchar(); //zebranie spacji getchar(); //zebranie 'j' std::cin >> im; getchar(); std::cout << std::endl; if (sign == '-') im = -im; std::complex<double> c1 (re, im); //liczba pierwotna std::complex<double> cf; //wynik operacji z biblioteki std std::complex<double> cb; //wynik operacji odwrotnej z boost::math std::complex<double> dc; //blad obliczeniowy, zdefiniowany jako cb - c1 //sinus cf = std::sin(c1); cb = boost::math::asin(cf); dc = cb - c1; std::cout << "Liczba pierwotna: " << c1 << std::endl << "std::sin: " << cf << std::endl << "boost::math::asin: " << cb << std::endl; std::cout << "Blad wzgledny okreslenia czesci rzeczywistej: " << dc.real() * 100 / c1.real() << "%" << std::endl << "Blad wzgledny okreslenia czesci urojonej: " << dc.imag() * 100 / c1.imag() << "%" << std::endl; getchar(); //cosinus cf = std::cos(c1); cb = boost::math::acos(cf); dc = cb - c1; std::cout << "Liczba pierwotna: " << c1 << std::endl << "std::cos: " << cf << std::endl << "boost::math::acos: " << cb << std::endl; std::cout << "Blad wzgledny okreslenia czesci rzeczywistej: " << dc.real() * 100 / c1.real() << "%" << std::endl << "Blad wzgledny okreslenia czesci urojonej: " << dc.imag() * 100 / c1.imag() << "%" << std::endl; getchar(); //tangens cf = std::tan(c1); cb = boost::math::atan(cf); dc = cb - c1; std::cout << "Liczba pierwotna: " << c1 << std::endl << "std::tan: " << cf << std::endl << "boost::math::atan: " << cb << std::endl; std::cout << "Blad wzgledny okreslenia czesci rzeczywistej: " << dc.real() * 100 / c1.real() << "%" << std::endl << "Blad wzgledny okreslenia czesci urojonej: " << dc.imag() * 100 / c1.imag() << "%" << std::endl; getchar(); //sinus hiperboliczny cf = std::sinh(c1); cb = boost::math::asinh(cf); dc = cb - c1; std::cout << "Liczba pierwotna: " << c1 << std::endl << "std::sinh: " << cf << std::endl << "boost::math::asinh: " << cb << std::endl; std::cout << "Blad wzgledny okreslenia czesci rzeczywistej: " << dc.real() * 100 / c1.real() << "%" << std::endl << "Blad wzgledny okreslenia czesci urojonej: " << dc.imag() * 100 / c1.imag() << "%" << std::endl; getchar(); //cosinus hiperboliczny cf = std::cosh(c1); cb = boost::math::acosh(cf); dc = cb - c1; std::cout << "Liczba pierwotna: " << c1 << std::endl << "std::cosh: " << cf << std::endl << "boost::math::acosh: " << cb << std::endl; std::cout << "Blad wzgledny okreslenia czesci rzeczywistej: " << dc.real() * 100 / c1.real() << "%" << std::endl << "Blad wzgledny okreslenia czesci urojonej: " << dc.imag() * 100 / c1.imag() << "%" << std::endl; getchar(); //tangens hiperboliczny cf = std::tanh(c1); cb = boost::math::atanh(cf); dc = cb - c1; std::cout << "Liczba pierwotna: " << c1 << std::endl << "std::tanh: " << cf << std::endl << "boost::math::atanh: " << cb << std::endl; std::cout << "Blad wzgledny okreslenia czesci rzeczywistej: " << dc.real() * 100 / c1.real() << "%" << std::endl << "Blad wzgledny okreslenia czesci urojonej: " << dc.imag() * 100 / c1.imag() << "%" << std::endl; getchar(); return 0; }