==== boost::math, complex number algorithms ==== Marcin Klocek, T-RTM ---- === Wstęp === 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. ---- === Przegląd odwrotnych funkcji trygonometrycznych === == Sinus == Plik nagłówkowy: #include Postać funkcji: template std::complex asin(const std::complex& z); Wzór: {{boost_asin.png}} == Cosinus == Plik nagłówkowy: #include Postać funkcji: template std::complex acos(const std::complex& z); Wzór: {{boost_acos.png}} == Tangens == Plik nagłówkowy: #include Postać funkcji: template std::complex atan(const std::complex& z); Wzór: {{boost_atan.png}} == Sinus hiperboliczny == Plik nagłówkowy: #include Postać funkcji: template std::complex asinh(const std::complex& z); Wzór: {{boost_asinh.png}} == Cosinus hiperboliczny == Plik nagłówkowy: #include Postać funkcji: template std::complex acosh(const std::complex& z); Wzór: {{boost_acosh.png}} == Tangens hiperboliczny == Plik nagłówkowy: #include Postać funkcji: template std::complex atanh(const std::complex& z); Wzór: {{boost_atanh.png}} ---- === Przykładowy program === 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 #include #include #include #include #include #include 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 c1 (re, im); //liczba pierwotna std::complex cf; //wynik operacji z biblioteki std std::complex cb; //wynik operacji odwrotnej z boost::math std::complex 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; }