Para promover lenguajes funcionales, muestro una función para encontrar una raíz para alguna función [math] f (x) [/ math] usando el método de bisección. El intervalo es [math] [x, y] [/ math], donde [math] \ operatorname {sgn} (f (x)) \ not = \ operatorname {sgn} (f (y)) [/ math] es condición previa. La precisión es [matemáticas] eps [/ matemáticas]. El idioma es Haskell.
bisección :: (Núm. a, Eq a, Fraccional a, Ord a) => (a-> a) -> a-> a-> a-> a
bisect fxy eps | fx == fromIntegral 0 = x
El | fy == fromIntegral 0 = y
El | sx == sy = error “mismo signo de f (x) yf (y)”
El | abs (xy) <= eps = x
El | sx / = sm = bisecto fxm eps
El | de lo contrario = bisecar fmy eps
dónde
s = signum. F
m = (x + y) / 2
En el mismo espíritu, una posible implementación de C ++ (aún no completamente probada), aplicada a la función [matemática] f (x): = x ^ 2–2 [/ matemática] y buscando una raíz entre [matemática] x = 0 [/ math] y [math] y = 3 [/ math]:
#include
#incluye
#include
#include
#include
- ¿Cuál es el valor de [math] \ int \ ln x dx [/ math]?
- ¿Qué significa la relación de mezcla 1: 2: 3?
- ¿Qué significa la proporción de mezcla 1: 2: 3?
- ¿Cuál es el camino más corto de A a B en este diagrama?
- ¿Cómo funciona la votación 3-2-1?
plantilla
int signum (T x) {
retorno (T (0) <x) – (x <T (0));
}
doble bisección (std :: function f,
doble x, doble y, doble eps) {
auto s = [& f] (doble z) -> doble {signo de retorno (f (z));};
if (f (x) == 0) {return x;}
if (f (y) == 0) {return y;}
if (s (x) == s (y)) {
throw std :: invalid_argument (“x e y tienen el mismo signo”);
}
más si (eps <= 0) {
throw std :: invalid_argument (“eps no positivo”);
}
// sabemos que los signos de f (x) yf (y) son opuestos, entonces una raíz
// se encuentra en el intervalo [x, y]. Su diferencia es
// eps menos o igual. Entonces encontramos una raíz.
if (std :: abs (xy) <= eps) {return x;}
doble m = (x + y) / 2;
if (s (x)! = s (m)) {
bisecto de retorno (f, x, m, eps);
}más{
bisecto de retorno (f, m, y, eps);
}
}
int main () {
diversión automática = [] (doble x) -> doble {return std :: pow (x, 2) -2;};
double xroot = bisect (diversión, 0, 3, 1e-15);
std :: cout << std :: setprecision (16) << "raíz:" << xroot << std :: endl;
}
Salida de la aplicación:
raíz: 1.414213562373095
Método de bisección – Wikipedia