-
-
Save typeofweb/5521750 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <vector> | |
using std::cout; | |
using std::cin; | |
template <class T> | |
struct Fun { | |
const T operator()(T x) { // funkcja | |
//return -5*x*x*x+8*x*x+3*x-1; | |
//return x*x*x-2*x+2; | |
return std::log(x+2) - 2*x*x + 1; | |
} | |
const T d1(T x) { // jej pierwsza pochodna | |
//return -15*x*x+16*x+3; | |
//return 3*x*x-2; | |
return 1.0 / (x+2) - 4*x; | |
} | |
const T d2(T x) { // jej druga pochodna | |
//return -30*x+16; | |
//return 6*x; | |
return - 1.0 / ((x+2.0)*(x+2.0)) - 4.0; | |
} | |
}; | |
template <class T> | |
std::pair<T, unsigned> bisection (T a, T b, T eps = 1e-6, unsigned it_bnd = 10000) { | |
if (a > b) { | |
std::swap(a, b); // a i b zawsze w odpowiedniej kolejności | |
} | |
Fun<T> f; | |
if (f(a) * f(b) > 0) { // warunek różnych znaków na krańcach przedziału | |
throw std::runtime_error("Brak rozwiazan w tym przedziale!"); | |
} | |
unsigned it_cnt = 0; | |
for (; std::abs(b - a) >= eps && it_bnd > it_cnt; ++it_cnt) { | |
T c = (a + b) / 2.0; // kolejny krok iteracji | |
if (f(a) * f(c) <= 0.0) { | |
b = c; | |
} else { | |
a = c; | |
} | |
} | |
T fa = f(a), fx = f((a + b) / 2.0), fb = f(b); // sprawdzenie warunku na asymptotę | |
if ( (fa > fx && fx > fb) || (fa < fx && fx < fb) ) { // jeśli krańce oraz środek przedziału z ostatniej iteracji nie są monotoniczne to mamy asymptotę | |
return std::make_pair((a + b) / 2.0, it_cnt); | |
} else { | |
std::runtime_error("Znaleziono asymptote pionowa!"); | |
} | |
} | |
template <class T> | |
std::pair<T, unsigned> tangents (T a, T b, T eps = 1e-6, unsigned it_bnd = 10000) { | |
if (a > b) { | |
std::swap(a, b); // a i b zawsze w odpowiedniej kolejności | |
} | |
Fun<T> f; | |
if (f(a) * f(b) > 0) { // warunek różnych znaków na krańcach przedziału | |
throw std::runtime_error("Brak rozwiazan w tym przedziale!"); | |
} | |
T xk; | |
if (f(a) * f.d2(a) > 0) { // znalezienie wartości x0 zgodnie ze skryptem Ratajczaka | |
xk = a; | |
} else if (f(b) * f.d2(b) > 0) { | |
xk = b; | |
} else { | |
throw std::runtime_error("Przedzial nie spelnia zalozen!"); | |
} | |
T m = std::min(std::abs(f.d1(a)), std::abs(f.d1(b))); | |
unsigned it_cnt = 1; | |
for (; std::abs(f(xk)) / m >= eps && it_bnd > it_cnt; ++it_cnt) { | |
xk = xk - (f(xk) / f.d1(xk)); // kolejny krok iteracji | |
} | |
if (xk >= a && xk <= b) { | |
return std::make_pair(xk, it_cnt); | |
} else { | |
std::runtime_error("Znaleziono asymptote pionowa!"); | |
} | |
} | |
template<class T> | |
void start (T a, T b, T eps = 1e-11, T step = 0.1) { | |
if (a > b) { | |
std::swap(a, b); | |
} | |
std::vector<std::pair<T,T>> intervals; | |
Fun<T> f; | |
for (T ia = a, ib = (a + step); ib <= b; ib += step) { | |
if (f(ia) * f(ib) < 0.0) { | |
if (std::abs(ib) < eps) { | |
ib = step; | |
} | |
intervals.push_back(std::make_pair(ia, ib)); | |
} | |
ia = ib; | |
} | |
for (auto it = intervals.begin(); it != intervals.end(); ++it) { | |
try { | |
std::pair<T, unsigned> sol = bisection<T>((*it).first, (*it).second, eps); | |
cout << "Bisekcje:\t" << ((std::abs(sol.first) < eps) ? 0.0 : sol.first) << "\n"; | |
cout << "Ilosc iteracji:\t" << sol.second << "\n\n"; | |
} catch (std::runtime_error e) { | |
cout << e.what() << "\n\n"; | |
} | |
try { | |
std::pair<T, unsigned> sol = tangents<T>((*it).first, (*it).second, eps); | |
cout << "Styczne:\t" << ((std::abs(sol.first) < eps) ? 0.0 : sol.first) << "\n"; | |
cout << "Ilosc iteracji:\t" << sol.second << "\n\n"; | |
} catch (std::runtime_error e) { | |
cout << e.what() << "\n\n"; | |
} | |
} | |
} | |
int main () { | |
cout.setf(std::ios::adjustfield); | |
//cout.setf(ios::fixed); | |
cout.precision(10); | |
start<double>(-3.0, 3.0, 1e-11, 0.1); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment