1st c++ draft
This commit is contained in:
parent
7b2a9a6d4a
commit
d83a997804
15 changed files with 3276 additions and 142 deletions
46
.gitignore
vendored
46
.gitignore
vendored
|
|
@ -1,2 +1,48 @@
|
||||||
|
# executable
|
||||||
|
run
|
||||||
|
|
||||||
*.pdf
|
*.pdf
|
||||||
|
|
||||||
|
# gcov files
|
||||||
|
*.gcov
|
||||||
|
*.gcda
|
||||||
|
*.gcno
|
||||||
|
|
||||||
|
# python cache
|
||||||
__pycache__
|
__pycache__
|
||||||
|
|
||||||
|
# generated documentation
|
||||||
|
html/
|
||||||
|
|
||||||
|
# Prerequisites
|
||||||
|
*.d
|
||||||
|
|
||||||
|
# Compiled Object files
|
||||||
|
*.slo
|
||||||
|
*.lo
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
|
||||||
|
# Precompiled Headers
|
||||||
|
*.gch
|
||||||
|
*.pch
|
||||||
|
|
||||||
|
# Compiled Dynamic libraries
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
*.dll
|
||||||
|
|
||||||
|
# Fortran module files
|
||||||
|
*.mod
|
||||||
|
*.smod
|
||||||
|
|
||||||
|
# Compiled Static libraries
|
||||||
|
*.lai
|
||||||
|
*.la
|
||||||
|
*.a
|
||||||
|
*.lib
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.app
|
||||||
|
|
|
||||||
2482
cpp/Doxyfile
Normal file
2482
cpp/Doxyfile
Normal file
File diff suppressed because it is too large
Load diff
41
cpp/Makefile
Normal file
41
cpp/Makefile
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
# Declaration of variables
|
||||||
|
C = clang
|
||||||
|
COMMON_FLAGS = -Wall -MMD
|
||||||
|
C_FLAGS = $(COMMON_FLAGS)
|
||||||
|
CC = clang++
|
||||||
|
CC_FLAGS = $(COMMON_FLAGS) -std=c++17
|
||||||
|
LD_FLAGS =
|
||||||
|
INCLUDES =
|
||||||
|
|
||||||
|
# File names
|
||||||
|
EXEC = run
|
||||||
|
CSOURCES = $(wildcard *.c)
|
||||||
|
COBJECTS = $(CSOURCES:.c=.o)
|
||||||
|
SOURCES = $(wildcard *.cpp)
|
||||||
|
OBJECTS = $(SOURCES:.cpp=.o)
|
||||||
|
|
||||||
|
# Main target
|
||||||
|
$(EXEC): $(COBJECTS) $(OBJECTS)
|
||||||
|
$(CC) $(COBJECTS) $(OBJECTS) -o $(EXEC) $(LD_FLAGS)
|
||||||
|
|
||||||
|
# To obtain object files
|
||||||
|
%.o: %.cpp
|
||||||
|
$(CC) $(INCLUDES) $(CC_FLAGS) -o $@ -c $<
|
||||||
|
|
||||||
|
# To obtain object files
|
||||||
|
%.o: %.c
|
||||||
|
$(C) $(INCLUDES) $(C_FLAGS) -o $@ -c $<
|
||||||
|
|
||||||
|
-include $(SOURCES:%.cpp=%.d)
|
||||||
|
-include $(CSOURCES:%.c=%.d)
|
||||||
|
|
||||||
|
# To generate the documentation
|
||||||
|
doc:
|
||||||
|
doxygen Doxyfile
|
||||||
|
|
||||||
|
# To remove generated files
|
||||||
|
clean:
|
||||||
|
rm -f $(COBJECTS) $(OBJECTS) $(SOURCES:%.cpp=%.d) $(CSOURCES:%.c=%.d)
|
||||||
|
|
||||||
|
cleaner: clean
|
||||||
|
rm -f $(EXEC)
|
||||||
3
cpp/README.md
Normal file
3
cpp/README.md
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
CppQuickStart
|
||||||
|
=============
|
||||||
|
"Empty" project for a quicker start writing something in c++.
|
||||||
167
cpp/TOMS748.hpp
Normal file
167
cpp/TOMS748.hpp
Normal file
|
|
@ -0,0 +1,167 @@
|
||||||
|
#ifndef DEF_TOMS748
|
||||||
|
#define DEF_TOMS748
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
namespace TOMS748
|
||||||
|
{
|
||||||
|
namespace internal
|
||||||
|
{
|
||||||
|
// checks that none of the values are the same
|
||||||
|
// returns true if at least two values are identical
|
||||||
|
template<typename T> bool checkTwoValuesIdentical(T fa, T fb, T fc, T fd)
|
||||||
|
{
|
||||||
|
bool same = false;
|
||||||
|
same |= fa == fb;
|
||||||
|
same |= fa == fc;
|
||||||
|
same |= fa == fd;
|
||||||
|
|
||||||
|
same |= fb == fc;
|
||||||
|
same |= fb == fd;
|
||||||
|
|
||||||
|
same |= fc == fd;
|
||||||
|
return same;
|
||||||
|
}
|
||||||
|
|
||||||
|
// finite differences 1st derivative given a, b, fa, fb
|
||||||
|
template<typename T> T fbracket1(T a, T b, T fa, T fb) { return (fb-fa)/(b-a); }
|
||||||
|
|
||||||
|
// finite differences 2nd derivative given a, b, d, fa, fb, fd
|
||||||
|
template<typename T> T fbracket2(T a, T b, T d, T fa, T fb, T fd) { return (fbracket1(b, d, fb, fd) - fbracket1(a, b, fa, fb))/(d-a); }
|
||||||
|
|
||||||
|
// standard bracketing routine
|
||||||
|
// returns ahat, bhat, d
|
||||||
|
// d is a point outside the new interval
|
||||||
|
template<typename T> std::tuple<T,T,T,T,T,T> bracket(T a, T b, T c, T fa, T fb, T fc)
|
||||||
|
{
|
||||||
|
if(fa*fc < T(0))
|
||||||
|
return std::make_tuple(a, c, b, fa, fc, fb);
|
||||||
|
else
|
||||||
|
return std::make_tuple(c, b, a, fc, fb, fa);
|
||||||
|
}
|
||||||
|
|
||||||
|
// standard bracketing routine
|
||||||
|
// checks if f(c) is close enough to 0 and returns ok = true if it is the case
|
||||||
|
// returns ahat, bhat, d
|
||||||
|
// d is a point outside the new interval
|
||||||
|
template<typename T> std::tuple<T,T,T,T,T,T,bool> bracketAndCheckConvergence(T a, T b, T c, T fa, T fb, T fc, T tol)
|
||||||
|
{
|
||||||
|
bool ok = false;
|
||||||
|
if(sureAbs(fc) < tol)
|
||||||
|
ok = true;
|
||||||
|
if(fa*fc < T(0))
|
||||||
|
return std::make_tuple(a, c, b, fa, fc, fb, ok);
|
||||||
|
else
|
||||||
|
return std::make_tuple(c, b, a, fc, fb, fa, ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
// finds an approximate solution to the quadratic P(x) = fa + f[a,b]*(x-a) + f[a,b,d]*(x-a)(x-b)
|
||||||
|
// with f[a,b] = fbracket1(a,b) and f[a,b,d] = fbracket2(a,b,d)
|
||||||
|
template<typename T, int k> T NewtonQuadratic(T a, T b, T d, T fa, T fb, T fd)
|
||||||
|
{
|
||||||
|
T r;
|
||||||
|
T A = fbracket2(a,b,d,fa,fb,fd);
|
||||||
|
T B = fbracket1(a,b,fa,fb);
|
||||||
|
if(A == T(0))
|
||||||
|
return a - fa/B;
|
||||||
|
if(A*fa > T(0))
|
||||||
|
r = a;
|
||||||
|
else
|
||||||
|
r = b;
|
||||||
|
|
||||||
|
for(int i = 0 ; i < k ; i++)
|
||||||
|
r = r - B*r/(B + A*(T(2)*r - a - b));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inverse cubic interpolation evaluated at 0 (modified Aitken-Neville interpolation)
|
||||||
|
template<typename T> T ipzero(T a, T b, T c, T d, T fa, T fb, T fc, T fd)
|
||||||
|
{
|
||||||
|
T Q11 = (c-d)*fc/(fd-fc);
|
||||||
|
T Q21 = (b-c)*fb/(fc-fb);
|
||||||
|
T Q31 = (a-b)*fa/(fb-fa);
|
||||||
|
T D21 = (b-c)*fc/(fc-fb);
|
||||||
|
T D31 = (a-b)*fb/(fb-fa);
|
||||||
|
T Q22 = (D21-Q11)*fb/(fd-fb);
|
||||||
|
T Q32 = (D31-Q21)*fa/(fc-fa);
|
||||||
|
T D32 = (D31-Q21)*fc/(fc-fa);
|
||||||
|
T Q33 = (D32-Q22)*fa/(fd-fa);
|
||||||
|
return a + Q31 + Q32 + Q33;
|
||||||
|
}
|
||||||
|
}// namespace internal
|
||||||
|
|
||||||
|
/// Algorithm 4.1 from TOMS748 of robust root-solving.
|
||||||
|
/// Use this version if f(a) and f(b) have already been computed.
|
||||||
|
template<typename Func, typename T> std::tuple<T,T,bool> TOMS748_solve1(Func f, T a, T b, T fa, T fb, T tol, int Nmax = 1000)
|
||||||
|
{
|
||||||
|
using namespace internal;
|
||||||
|
T c, d, e, u, dbar, dhat, fc, fd, fe, fu, fdbar, fdhat;
|
||||||
|
T mu = 0.5;
|
||||||
|
bool ok;
|
||||||
|
c = a - fa/fbracket1(a, b, fa, fb); // 4.1.1 secant method
|
||||||
|
fc = f(c);
|
||||||
|
std::tie(a, b, d, fa, fb, fd, ok) = bracketAndCheckConvergence(a, b, c, fa, fb, fc, tol); // 4.1.2
|
||||||
|
if(ok) { return std::make_tuple(c, fc, true); }
|
||||||
|
e = d;
|
||||||
|
fe = fd;
|
||||||
|
// ---
|
||||||
|
for(int n = 2 ; n < Nmax ; n++) // 4.1.3
|
||||||
|
{
|
||||||
|
if(n == 2 || checkTwoValuesIdentical(fa, fb, fd, fe))
|
||||||
|
c = NewtonQuadratic<T,2>(a, b, d, fa, fb, fd);
|
||||||
|
else
|
||||||
|
c = ipzero(a, b, d, e, fa, fb, fd, fe);
|
||||||
|
if((c-a)*(c-b) >= T(0))
|
||||||
|
c = NewtonQuadratic<T,2>(a, b, d, fa, fb, fd);
|
||||||
|
// ---
|
||||||
|
fc = f(c);
|
||||||
|
std::tie(a, b, dbar, fa, fb, fdbar, ok) = bracketAndCheckConvergence(a, b, c, fa, fb, fc, tol); // 4.1.4
|
||||||
|
if(ok) { return std::make_tuple(c, fc, true); }
|
||||||
|
// ---
|
||||||
|
if(fabs(fa) < fabs(fb)) // 4.1.5
|
||||||
|
{
|
||||||
|
u = a;
|
||||||
|
fu = fa;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
u = b;
|
||||||
|
fu = fb;
|
||||||
|
}
|
||||||
|
// ---
|
||||||
|
c = u - 2*fu/fbracket1(a, b, fa, fb); // 4.1.6
|
||||||
|
// ---
|
||||||
|
if(fabs(c - u) > 0.5*(b - a)) // 4.1.7
|
||||||
|
c = 0.5*(b + a);
|
||||||
|
// ---
|
||||||
|
fc = f(c);
|
||||||
|
std::tie(a, b, dhat, fa, fb, fdhat, ok) = bracketAndCheckConvergence(a, b, c, fa, fb, fc, tol); // 4.1.8
|
||||||
|
if(ok) { return std::make_tuple(c, fc, true); }
|
||||||
|
// ---
|
||||||
|
if(b - a < mu*(b - a)) // 4.1.9
|
||||||
|
{
|
||||||
|
d = dhat;
|
||||||
|
e = dbar;
|
||||||
|
fd = fdhat;
|
||||||
|
fe = fdbar;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
e = dhat;
|
||||||
|
fe = fdhat;
|
||||||
|
}
|
||||||
|
c = 0.5*(a+b);
|
||||||
|
fc = f(c);
|
||||||
|
std::tie(a, b, d, fa, fb, fd, ok) = bracketAndCheckConvergence(a, b, c, fa, fb, fc, tol);
|
||||||
|
if(ok) { return std::make_tuple(c, fc, true); }
|
||||||
|
}
|
||||||
|
return std::make_tuple(c, fc, false);// no solution found, return last estimate
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Func, typename T> std::tuple<T,T,bool> TOMS748_solve1(Func f, T a, T b, T tol, int Nmax = 1000)
|
||||||
|
{
|
||||||
|
return TOMS748_solve1(f, a, b, f(a), f(b), tol, Nmax);
|
||||||
|
}
|
||||||
|
}// namespace TOMS748
|
||||||
|
|
||||||
|
#endif
|
||||||
49
cpp/main.cpp
Normal file
49
cpp/main.cpp
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
#include "utils.hpp"
|
||||||
|
#include "TOMS748.hpp"
|
||||||
|
|
||||||
|
using std::cout;
|
||||||
|
using std::endl;
|
||||||
|
|
||||||
|
using namespace TOMS748;
|
||||||
|
using namespace TOMS748::internal;
|
||||||
|
|
||||||
|
template<typename T> T f(T E) { PRINT_VAR(E); return E - 0.5*sin(E) - 0.3; }
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
cout.precision(16);
|
||||||
|
{
|
||||||
|
double a = 0, b = 1, c = 0.3, d = 1.2;
|
||||||
|
double fa = f(a), fb = f(b), fc = f(c), fd = f(d);
|
||||||
|
double tol = 1e-12;
|
||||||
|
|
||||||
|
PRINT_VAR(fbracket1(a, b, fa, fb));
|
||||||
|
PRINT_VAR(fbracket2(a, b, d, fa, fb, fd));
|
||||||
|
std::tie(a, b, d, fa, fb, fd) = bracket(a, b, c, fa, fb, fc);
|
||||||
|
PRINT_VAR(a);
|
||||||
|
PRINT_VAR(b);
|
||||||
|
PRINT_VAR(d);
|
||||||
|
PRINT_VAR(fa);
|
||||||
|
PRINT_VAR(fb);
|
||||||
|
PRINT_VAR(fd);
|
||||||
|
|
||||||
|
PRINT_VAR(checkTwoValuesIdentical(1,2,3,4));
|
||||||
|
PRINT_VAR(checkTwoValuesIdentical(1,2,3,1));
|
||||||
|
PRINT_VAR(checkTwoValuesIdentical(1,1,3,4));
|
||||||
|
PRINT_VAR(checkTwoValuesIdentical(1,2,2,4));
|
||||||
|
PRINT_VAR(checkTwoValuesIdentical(1,2,3,3));
|
||||||
|
PRINT_VAR(checkTwoValuesIdentical(1,2,1,4));
|
||||||
|
PRINT_VAR(checkTwoValuesIdentical(1,2,3,2));
|
||||||
|
|
||||||
|
a = 0; b = 1;
|
||||||
|
auto res = TOMS748_solve1(f<double>, a, b, tol);
|
||||||
|
PRINT_VAR(std::get<0>(res));
|
||||||
|
PRINT_VAR(std::get<1>(res));
|
||||||
|
PRINT_VAR(std::get<2>(res));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
34
cpp/test/1_test.cpp
Normal file
34
cpp/test/1_test.cpp
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
#include <catch2/catch.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "../utils.hpp"
|
||||||
|
#include "utils_test.hpp"
|
||||||
|
|
||||||
|
#define print(x) PRINT_VAR(x);
|
||||||
|
#define printvec(x) PRINT_VEC(x);
|
||||||
|
#define printstr(x) PRINT_STR(x);
|
||||||
|
|
||||||
|
TEST_CASE( "Test case 1", "[test1]" )
|
||||||
|
{
|
||||||
|
std::cout.precision(16);
|
||||||
|
|
||||||
|
SECTION( "Check almost equal" ) {
|
||||||
|
CHECK(check_almost_equal(1.00, 1.01, 0.1));
|
||||||
|
CHECK(check_almost_equal(1.00, 3.01, 0.01));
|
||||||
|
CHECK(check_almost_equal(1.00, 1.01, 0.001));
|
||||||
|
REQUIRE(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION( "Check almost equal on vectors" ) {
|
||||||
|
unsigned int N = 5;
|
||||||
|
std::vector<double> v1(N), v2(N);
|
||||||
|
for (size_t i = 0; i < N; i++) {
|
||||||
|
v1[i] = double(i);
|
||||||
|
v2[i] = v1[i] + 0.0001;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK(check_almost_equalV(v1, v2, 0.001));
|
||||||
|
CHECK(check_almost_equalV(v1, v2, 0.0001));
|
||||||
|
CHECK(check_almost_equalV(v1, v2, 0.00001));
|
||||||
|
}
|
||||||
|
}
|
||||||
49
cpp/test/Makefile
Normal file
49
cpp/test/Makefile
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
# Declaration of variables
|
||||||
|
C = gcc
|
||||||
|
COMMON_FLAGS = -Wall -MMD -fprofile-arcs -ftest-coverage
|
||||||
|
C_FLAGS = $(COMMON_FLAGS)
|
||||||
|
CC = g++
|
||||||
|
CC_FLAGS = $(COMMON_FLAGS) -std=c++17 -O0
|
||||||
|
LD_FLAGS = -lgcov
|
||||||
|
INCLUDES =
|
||||||
|
|
||||||
|
# File names
|
||||||
|
EXEC = run
|
||||||
|
CSOURCES = $(wildcard *.c)
|
||||||
|
COBJECTS = $(CSOURCES:.c=.o)
|
||||||
|
SOURCES = $(wildcard *.cpp)
|
||||||
|
OBJECTS = $(SOURCES:.cpp=.o)
|
||||||
|
|
||||||
|
# Main target
|
||||||
|
$(EXEC): $(COBJECTS) $(OBJECTS)
|
||||||
|
$(CC) $(COBJECTS) $(OBJECTS) -o $(EXEC) $(LD_FLAGS)
|
||||||
|
|
||||||
|
# To obtain object files
|
||||||
|
%.o: %.cpp
|
||||||
|
$(CC) $(INCLUDES) $(CC_FLAGS) -o $@ -c $<
|
||||||
|
|
||||||
|
# To obtain object files
|
||||||
|
%.o: %.c
|
||||||
|
$(C) $(INCLUDES) $(C_FLAGS) -o $@ -c $<
|
||||||
|
|
||||||
|
-include $(SOURCES:%.cpp=%.d)
|
||||||
|
-include $(CSOURCES:%.c=%.d)
|
||||||
|
|
||||||
|
# To generate the documentation
|
||||||
|
doc:
|
||||||
|
doxygen Doxyfile
|
||||||
|
|
||||||
|
# To generate human-readable coverage data
|
||||||
|
cov:
|
||||||
|
gcov *.gcda
|
||||||
|
|
||||||
|
# To remove all the files generated by gcov
|
||||||
|
cleancov:
|
||||||
|
rm -f *.gcov *.gcda
|
||||||
|
|
||||||
|
# To remove generated files
|
||||||
|
clean: cleancov
|
||||||
|
rm -f $(COBJECTS) $(OBJECTS) $(SOURCES:%.cpp=%.d) $(CSOURCES:%.c=%.d) *.gcno
|
||||||
|
|
||||||
|
cleaner: clean
|
||||||
|
rm -f $(EXEC)
|
||||||
4
cpp/test/main_test.cpp
Normal file
4
cpp/test/main_test.cpp
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
// Let Catch provide main()
|
||||||
|
#define CATCH_CONFIG_MAIN
|
||||||
|
|
||||||
|
#include <catch2/catch.hpp>
|
||||||
BIN
cpp/test/run
Normal file
BIN
cpp/test/run
Normal file
Binary file not shown.
30
cpp/test/utils_test.hpp
Normal file
30
cpp/test/utils_test.hpp
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
#ifndef DEF_utils_test
|
||||||
|
#define DEF_utils_test
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
template<typename T, typename T2>
|
||||||
|
bool check_almost_equal(const T & a, const T & b, const T2 & tol)
|
||||||
|
{
|
||||||
|
T a_b = a - b;
|
||||||
|
return ((a_b < T(0)) ? -a_b : a_b) <= tol;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Vector, typename T>
|
||||||
|
bool check_almost_equalV(const Vector & v1, const Vector & v2, T tol)
|
||||||
|
{
|
||||||
|
assert(v1.size() == v2.size());
|
||||||
|
bool ok = true;
|
||||||
|
for(size_t i = 0 ; i < v1.size() ; i++)
|
||||||
|
{
|
||||||
|
auto v1_v2_i = v1[i] - v2[i];
|
||||||
|
if(((v1_v2_i < 0) ? -v1_v2_i : v1_v2_i) > tol)
|
||||||
|
{
|
||||||
|
ok = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
39
cpp/utils.hpp
Normal file
39
cpp/utils.hpp
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
#ifndef DEF_utils
|
||||||
|
#define DEF_utils
|
||||||
|
|
||||||
|
#include <ostream>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#define PRINT_VAR(x) std::cout << #x << "\t= " << (x) << "\n"
|
||||||
|
#define PRINT_VEC(x); {std::cout << #x << "\t= "; \
|
||||||
|
for(unsigned int i_print_vec = 0 ; i_print_vec < (x).size() ; i_print_vec++) \
|
||||||
|
std::cout << (x)[i_print_vec] << "\t"; \
|
||||||
|
std::cout << "\n";}
|
||||||
|
#define PRINT_STR(x) std::cout << (x) << "\n"
|
||||||
|
|
||||||
|
template<typename T, typename T2> auto min(const T & a, const T2 & b) -> decltype(a | b) { return (a < b) ? T(a) : T(b); }
|
||||||
|
template<typename T, typename T2> auto max(const T & a, const T2 & b) -> decltype(a | b) { return (a < b) ? T(b) : T(a); }
|
||||||
|
|
||||||
|
/// To be sure that floating point numbers won't be casted to integers in ::abs()...
|
||||||
|
template<typename T> T sureAbs(const T & x) { return (x < T(0)) ? -x : x; }
|
||||||
|
|
||||||
|
template<typename T, template<class,class...> class C, class... Args>
|
||||||
|
std::ostream& operator<<(std::ostream& os, const C<T,Args...>& objs)
|
||||||
|
{
|
||||||
|
for (auto const& obj : objs)
|
||||||
|
os << obj << ' ';
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convenience template class to do StdPairValueCatcher(a, b) = someFunctionThatReturnsAnStdPair<A,B>()
|
||||||
|
/// Instead of doing a = std::get<0>(result_from_function), b = std::get<1>(result_from_function)
|
||||||
|
template<typename A, typename B>
|
||||||
|
struct StdPairValueCatcher
|
||||||
|
{
|
||||||
|
A & a;
|
||||||
|
B & b;
|
||||||
|
StdPairValueCatcher(A & a_, B & b_) : a(a_), b(b_) {}
|
||||||
|
std::pair<A, B> const& operator=(std::pair<A, B> const& p) {a = std::get<0>(p); b = std::get<1>(p); return p; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -9,10 +9,19 @@ def findEnclosingBracket(f, x, factor):
|
||||||
If the bracket returned by the function is too wide, try reducing the factor (while always keeping it > 1).
|
If the bracket returned by the function is too wide, try reducing the factor (while always keeping it > 1).
|
||||||
"""
|
"""
|
||||||
a = x
|
a = x
|
||||||
b = x*factor # try higher
|
b = x*factor # try searching in the positive direction
|
||||||
fa = f(a)
|
fa = f(a)
|
||||||
fb = f(b)
|
fb = f(b)
|
||||||
|
|
||||||
|
if fa*fb < 0: # if the original bracket is already enclosing the solution
|
||||||
|
return (a, b, fa, fb)
|
||||||
|
|
||||||
|
if fabs(fa) < fabs(fb): # if fa is closer, search in the other direction
|
||||||
|
a = x/factor
|
||||||
|
b = x
|
||||||
|
fb = fa # f(b) = f(x)
|
||||||
|
fa = f(a)
|
||||||
|
|
||||||
i = 0
|
i = 0
|
||||||
while i in range(100) and fa*fb > 0:
|
while i in range(100) and fa*fb > 0:
|
||||||
if fabs(fa) < fabs(fb): # fa is closer to 0 than fb, extend the interval in the a direction (reducing it)
|
if fabs(fa) < fabs(fb): # fa is closer to 0 than fb, extend the interval in the a direction (reducing it)
|
||||||
|
|
@ -43,6 +52,16 @@ f = lambda x : x**(1/3)-1000
|
||||||
a, b, fa, fb = findEnclosingBracket(f, 1e-10, 2)
|
a, b, fa, fb = findEnclosingBracket(f, 1e-10, 2)
|
||||||
print((a,b)); print((fa, fb))
|
print((a,b)); print((fa, fb))
|
||||||
|
|
||||||
|
print('exp(x)-2')
|
||||||
|
|
||||||
|
def f(x):
|
||||||
|
fx = exp(x)-2
|
||||||
|
print((x, fx))
|
||||||
|
return fx
|
||||||
|
|
||||||
|
a, b, fa, fb = findEnclosingBracket(f, .1, 2); print((a,b)); print((fa, fb))
|
||||||
|
a, b, fa, fb = findEnclosingBracket(f, 4, 2); print((a,b)); print((fa, fb))
|
||||||
|
|
||||||
# from toms748 import TOMS748_solve1
|
# from toms748 import TOMS748_solve1
|
||||||
# def f(x):
|
# def f(x):
|
||||||
# print(x)
|
# print(x)
|
||||||
312
python/toms748.py
Normal file
312
python/toms748.py
Normal file
|
|
@ -0,0 +1,312 @@
|
||||||
|
# Implementation of TOMS748
|
||||||
|
# https://na.math.kit.edu/alefeld/download/1995_Algorithm_748_Enclosing_Zeros_of_Continuous_Functions.pdf
|
||||||
|
|
||||||
|
# from math import sin, fabs, cos
|
||||||
|
from math import *
|
||||||
|
|
||||||
|
# checks that none of the values are the same
|
||||||
|
# returns true if at least two values are identical
|
||||||
|
def checkTwoValuesIdentical(fa, fb, fc, fd):
|
||||||
|
same = False
|
||||||
|
same |= fa == fb
|
||||||
|
same |= fa == fc
|
||||||
|
same |= fa == fd
|
||||||
|
|
||||||
|
same |= fb == fc
|
||||||
|
same |= fb == fd
|
||||||
|
|
||||||
|
same |= fc == fd
|
||||||
|
return same
|
||||||
|
|
||||||
|
# finite differences 1st derivative given a, b, fa, fb
|
||||||
|
def fbracket1(a, b, fa, fb):
|
||||||
|
return (fb-fa)/(b-a)
|
||||||
|
|
||||||
|
# finite differences 2nd derivative given a, b, d, fa, fb, fd
|
||||||
|
def fbracket2(a, b, d, fa, fb, fd):
|
||||||
|
return (fbracket1(b, d, fb, fd) - fbracket1(a, b, fa, fb))/(d-a)
|
||||||
|
|
||||||
|
# standard bracketing routine
|
||||||
|
# returns ahat, bhat, d
|
||||||
|
# d is a point outside the new interval
|
||||||
|
def bracket(a, b, c, fa, fb, fc):
|
||||||
|
if fa*fc < 0:
|
||||||
|
return (a, c, b, fa, fc, fb)
|
||||||
|
else:
|
||||||
|
return (c, b, a, fc, fb, fa)
|
||||||
|
|
||||||
|
# standard bracketing routine
|
||||||
|
# returns ahat, bhat, d
|
||||||
|
# d is a point outside the new interval
|
||||||
|
def bracketAndCheckConvergence(a, b, c, fa, fb, fc, tol):
|
||||||
|
ok = False
|
||||||
|
if fabs(fc) < tol:
|
||||||
|
ok = True
|
||||||
|
if fa*fc < 0:
|
||||||
|
return (a, c, b, fa, fc, fb, ok)
|
||||||
|
else:
|
||||||
|
return (c, b, a, fc, fb, fa, ok)
|
||||||
|
|
||||||
|
# finds an approximate solution to the quadratic P(x) = fa + f[a,b]*(x-a) + f[a,b,d]*(x-a)(x-b)
|
||||||
|
# with f[a,b] = fbracket1(a,b) and f[a,b,d] = fbracket2(a,b,d)
|
||||||
|
def NewtonQuadratic(a, b, d, fa, fb, fd, k):
|
||||||
|
A = fbracket2(a,b,d,fa,fb,fd)
|
||||||
|
B = fbracket1(a,b,fa,fb)
|
||||||
|
if A == 0:
|
||||||
|
return a - fa/B
|
||||||
|
if A*fa > 0:
|
||||||
|
r = a
|
||||||
|
else:
|
||||||
|
r = b
|
||||||
|
|
||||||
|
for i in range(k):
|
||||||
|
r = r - B*r/(B + A*(2*r - a - b))
|
||||||
|
return r
|
||||||
|
|
||||||
|
# Inverse cubic interpolation evaluated at 0 (modified Aitken-Neville interpolation)
|
||||||
|
def ipzero(a, b, c, d, fa, fb, fc, fd):
|
||||||
|
Q11 = (c-d)*fc/(fd-fc)
|
||||||
|
Q21 = (b-c)*fb/(fc-fb)
|
||||||
|
Q31 = (a-b)*fa/(fb-fa)
|
||||||
|
D21 = (b-c)*fc/(fc-fb)
|
||||||
|
D31 = (a-b)*fb/(fb-fa)
|
||||||
|
Q22 = (D21-Q11)*fb/(fd-fb)
|
||||||
|
Q32 = (D31-Q21)*fa/(fc-fa)
|
||||||
|
D32 = (D31-Q21)*fc/(fc-fa)
|
||||||
|
Q33 = (D32-Q22)*fa/(fd-fa)
|
||||||
|
return a + Q31 + Q32 + Q33
|
||||||
|
|
||||||
|
def TOMS748_solve1(f, a, b, tol, Nmax = 1000):
|
||||||
|
mu = 0.5
|
||||||
|
fa, fb = f(a), f(b)
|
||||||
|
c = a - fa/fbracket1(a, b, fa, fb) # 4.1.1 secant method
|
||||||
|
fc = f(c)
|
||||||
|
a, b, d, fa, fb, fd, ok = bracketAndCheckConvergence(a, b, c, fa, fb, fc, tol) # 4.1.2
|
||||||
|
if(ok): return (c, fc)
|
||||||
|
e = d
|
||||||
|
fe = fd
|
||||||
|
# ---
|
||||||
|
for n in range(2,Nmax): # 4.1.3
|
||||||
|
if n == 2 or checkTwoValuesIdentical(fa, fb, fd, fe):
|
||||||
|
c = NewtonQuadratic(a, b, d, fa, fb, fd, 2)
|
||||||
|
else:
|
||||||
|
c = ipzero(a, b, d, e, fa, fb, fd, fe)
|
||||||
|
if (c-a)*(c-b) >= 0:
|
||||||
|
c = NewtonQuadratic(a, b, d, fa, fb, fd, 2)
|
||||||
|
# ---
|
||||||
|
fc = f(c)
|
||||||
|
a, b, dbar, fa, fb, fdbar, ok = bracketAndCheckConvergence(a, b, c, fa, fb, fc, tol) # 4.1.4
|
||||||
|
if(ok): return (c, fc)
|
||||||
|
# ---
|
||||||
|
if fabs(fa) < fabs(fb): # 4.1.5
|
||||||
|
u = a
|
||||||
|
fu = fa
|
||||||
|
else:
|
||||||
|
u = b
|
||||||
|
fu = fb
|
||||||
|
# ---
|
||||||
|
c = u - 2*fu/fbracket1(a, b, fa, fb) # 4.1.6
|
||||||
|
# ---
|
||||||
|
if fabs(c - u) > 0.5*(b - a): # 4.1.7
|
||||||
|
c = 0.5*(b + a)
|
||||||
|
# ---
|
||||||
|
fc = f(c)
|
||||||
|
a, b, dhat, fa, fb, fdhat, ok = bracketAndCheckConvergence(a, b, c, fa, fb, fc, tol) # 4.1.8
|
||||||
|
if(ok): return (c, fc)
|
||||||
|
# ---
|
||||||
|
if b - a < mu*(b - a): # 4.1.9
|
||||||
|
d = dhat
|
||||||
|
e = dbar
|
||||||
|
fd = fdhat
|
||||||
|
fe = fdbar
|
||||||
|
else:
|
||||||
|
e = dhat
|
||||||
|
fe = fdhat
|
||||||
|
c = 0.5*(a+b)
|
||||||
|
fc = f(c)
|
||||||
|
a, b, d, fa, fb, fd, ok = bracketAndCheckConvergence(a, b, c, fa, fb, fc, tol)
|
||||||
|
if(ok): return (c, fc)
|
||||||
|
return (c, fc)# no solution found, return last estimate
|
||||||
|
|
||||||
|
def TOMS748_solve2(f, a, b, tol, Nmax = 1000):
|
||||||
|
mu = 0.5
|
||||||
|
fa, fb = f(a), f(b)
|
||||||
|
c = a - fa/fbracket1(a, b, fa, fb) # 4.2.1 secant method
|
||||||
|
fc = f(c)
|
||||||
|
a, b, d, fa, fb, fd, ok = bracketAndCheckConvergence(a, b, c, fa, fb, fc, tol) # 4.2.2
|
||||||
|
if(ok): return (c, fc)
|
||||||
|
e = d
|
||||||
|
fe = fd
|
||||||
|
# ---
|
||||||
|
for n in range(2,Nmax): # 4.2.3
|
||||||
|
if n == 2 or checkTwoValuesIdentical(fa, fb, fd, fe):
|
||||||
|
c = NewtonQuadratic(a, b, d, fa, fb, fd, 2)
|
||||||
|
else:
|
||||||
|
c = ipzero(a, b, d, e, fa, fb, fd, fe)
|
||||||
|
if (c-a)*(c-b) >= 0:
|
||||||
|
c = NewtonQuadratic(a, b, d, fa, fb, fd, 2)
|
||||||
|
# ---
|
||||||
|
e = d
|
||||||
|
fe = fd
|
||||||
|
fc = f(c)
|
||||||
|
a, b, d, fa, fb, fd, ok = bracketAndCheckConvergence(a, b, c, fa, fb, fc, tol) # 4.2.4
|
||||||
|
if(ok): return (c, fc)
|
||||||
|
# ---
|
||||||
|
if checkTwoValuesIdentical(fa, fb, fd, fe): # 4.2.5
|
||||||
|
c = NewtonQuadratic(a, b, d, fa, fb, fd, 3)
|
||||||
|
else:
|
||||||
|
c = ipzero(a, b, d, e, fa, fb, fd, fe)
|
||||||
|
if (c-a)*(c-b) >= 0:
|
||||||
|
c = NewtonQuadratic(a, b, d, fa, fb, fd, 3)
|
||||||
|
# ---
|
||||||
|
fc = f(c)
|
||||||
|
a, b, dbar, fa, fb, fdbar, ok = bracketAndCheckConvergence(a, b, c, fa, fb, fc, tol) # 4.2.6
|
||||||
|
if(ok): return (c, fc)
|
||||||
|
# ---
|
||||||
|
if fabs(fa) < fabs(fb): # 4.2.7
|
||||||
|
u = a
|
||||||
|
fu = fa
|
||||||
|
else:
|
||||||
|
u = b
|
||||||
|
fu = fb
|
||||||
|
# ---
|
||||||
|
c = u - 2*fu/fbracket1(a, b, fa, fb) # 4.2.8
|
||||||
|
# ---
|
||||||
|
if fabs(c - u) > 0.5*(b - a): # 4.2.9
|
||||||
|
c = 0.5*(b + a)
|
||||||
|
# ---
|
||||||
|
fc = f(c)
|
||||||
|
a, b, dhat, fa, fb, fdhat, ok = bracketAndCheckConvergence(a, b, c, fa, fb, fc, tol) # 4.2.10
|
||||||
|
if(ok): return (c, fc)
|
||||||
|
# ---
|
||||||
|
if b - a < mu*(b - a): # 4.2.11
|
||||||
|
d = dhat
|
||||||
|
e = dbar
|
||||||
|
fd = fdhat
|
||||||
|
fe = fdbar
|
||||||
|
else:
|
||||||
|
e = dhat
|
||||||
|
fe = fdhat
|
||||||
|
c = 0.5*(a+b)
|
||||||
|
fc = f(c)
|
||||||
|
a, b, d, fa, fb, fd, ok = bracketAndCheckConvergence(a, b, c, fa, fb, fc, tol)
|
||||||
|
if(ok): return (c, fc)
|
||||||
|
return (c, fc)# no solution found, return last estimate
|
||||||
|
|
||||||
|
# TEST
|
||||||
|
f = lambda E : E - 0.5*sin(E) - 0.3
|
||||||
|
a, b, c, d = 0, 1, 0.3, 1.2
|
||||||
|
fa, fb, fc, fd = f(a), f(b), f(c), f(d)
|
||||||
|
tol = 1e-12
|
||||||
|
|
||||||
|
print(fbracket1(a, b, fa, fb))
|
||||||
|
print(fbracket2(a, b, d, fa, fb, fd))
|
||||||
|
print(bracket(a, b, c, fa, fb, fc))
|
||||||
|
print(NewtonQuadratic(a, b, d, fa, fb, fd, 2))
|
||||||
|
print(ipzero(a, b, c, d, fa, fb, fc, fd))
|
||||||
|
|
||||||
|
# TTTEST
|
||||||
|
print(checkTwoValuesIdentical(1,2,3,4))
|
||||||
|
print(checkTwoValuesIdentical(1,2,3,1))
|
||||||
|
print(checkTwoValuesIdentical(1,1,3,4))
|
||||||
|
print(checkTwoValuesIdentical(1,2,2,4))
|
||||||
|
print(checkTwoValuesIdentical(1,2,3,3))
|
||||||
|
print(checkTwoValuesIdentical(1,2,1,4))
|
||||||
|
print(checkTwoValuesIdentical(1,2,3,2))
|
||||||
|
# TTTEST
|
||||||
|
|
||||||
|
# solution using bracket only :
|
||||||
|
print('bracket only')
|
||||||
|
for i in range(50):
|
||||||
|
c = (a+b)/2
|
||||||
|
fc = f(c)
|
||||||
|
a, b, d, fa, fb, fd = bracket(a, b, c, fa, fb, fc)
|
||||||
|
if fabs(b-a) < tol:
|
||||||
|
break
|
||||||
|
print(i)
|
||||||
|
|
||||||
|
print((a,b), (a+b)/2, b-a)
|
||||||
|
|
||||||
|
print('Newton with derivative')
|
||||||
|
df = lambda E : 1 - 0.5*cos(E)
|
||||||
|
x = 0.5
|
||||||
|
for i in range(50):
|
||||||
|
delta = f(x)/df(x)
|
||||||
|
x = x - delta
|
||||||
|
if fabs(delta) < tol:
|
||||||
|
break
|
||||||
|
print(i)
|
||||||
|
print(x)
|
||||||
|
|
||||||
|
print('TOMS748_solve1 only')
|
||||||
|
def fct1(E):
|
||||||
|
print("x = %20.15f" % E)
|
||||||
|
return E - 0.5*sin(E) - 0.3
|
||||||
|
|
||||||
|
c, fc = TOMS748_solve1(fct1, 0, 1, tol)
|
||||||
|
print("Root found :")
|
||||||
|
print((c, fc))
|
||||||
|
|
||||||
|
print('TOMS748_solve2 only')
|
||||||
|
c, fc = TOMS748_solve2(fct1, 0, 1, tol)
|
||||||
|
print("Root found :")
|
||||||
|
print((c, fc))
|
||||||
|
|
||||||
|
# ---
|
||||||
|
|
||||||
|
print('TOMS748_solve1 only')
|
||||||
|
def fct2(x):
|
||||||
|
print("x = %20.15f" % x)
|
||||||
|
n = 20
|
||||||
|
return x**2 - (1-x)**n
|
||||||
|
|
||||||
|
c, fc = TOMS748_solve1(fct2, 0, 1, tol)
|
||||||
|
print("Root found :")
|
||||||
|
print((c, fc))
|
||||||
|
|
||||||
|
print('TOMS748_solve2 only')
|
||||||
|
c, fc = TOMS748_solve2(fct2, 1e-100, 1, tol)# if a is 0 the algorithm does not work (division by zero, because newton step a = 0 finds d = 0). It seems to be just this one case...
|
||||||
|
print("Root found :")
|
||||||
|
print((c, fc))
|
||||||
|
|
||||||
|
print('Newton with derivative')
|
||||||
|
dfct2 = lambda x : 2*x + 20*(-x + 1)**19
|
||||||
|
x = 0.5
|
||||||
|
for i in range(50):
|
||||||
|
delta = fct2(x)/dfct2(x)
|
||||||
|
x = x - delta
|
||||||
|
if fabs(delta) < tol:
|
||||||
|
break
|
||||||
|
print(i)
|
||||||
|
print(x)
|
||||||
|
|
||||||
|
# ---
|
||||||
|
|
||||||
|
print('--------------------------')
|
||||||
|
print('fct3')
|
||||||
|
print('TOMS748_solve1 only')
|
||||||
|
def fct3(x):
|
||||||
|
print("x = %20.15f" % x)
|
||||||
|
return x*exp(-x**2)
|
||||||
|
# a, b = -.5, 1.5
|
||||||
|
a, b = -1/sqrt(2), 2/sqrt(2)
|
||||||
|
|
||||||
|
c, fc = TOMS748_solve1(fct3, a, b, tol)
|
||||||
|
print("Root found :")
|
||||||
|
print((c, fc))
|
||||||
|
|
||||||
|
print('TOMS748_solve2 only')
|
||||||
|
c, fc = TOMS748_solve2(fct3, a, b, tol)# if a is 0 the algorithm does not work (division by zero, because newton step a = 0 finds d = 0). It seems to be just this one case...
|
||||||
|
print("Root found :")
|
||||||
|
print((c, fc))
|
||||||
|
|
||||||
|
print('Newton with derivative')
|
||||||
|
dfct3 = lambda x : (-2*x**2 + 1)*exp(-x**2)
|
||||||
|
x = (a+b)/2
|
||||||
|
for i in range(50):
|
||||||
|
delta = fct3(x)/dfct3(x)
|
||||||
|
x = x - delta
|
||||||
|
if fabs(delta) < tol:
|
||||||
|
break
|
||||||
|
print(i)
|
||||||
|
print(x)
|
||||||
141
toms748.py
141
toms748.py
|
|
@ -1,141 +0,0 @@
|
||||||
# Implementation of TOMS748
|
|
||||||
# https://na.math.kit.edu/alefeld/download/1995_Algorithm_748_Enclosing_Zeros_of_Continuous_Functions.pdf
|
|
||||||
|
|
||||||
from math import sin, fabs, cos
|
|
||||||
|
|
||||||
# finite differences 1st derivative given a, b, fa, fb
|
|
||||||
def fbracket1(a, b, fa, fb):
|
|
||||||
return (fb-fa)/(b-a)
|
|
||||||
|
|
||||||
# finite differences 2nd derivative given a, b, d, fa, fb, fd
|
|
||||||
def fbracket2(a, b, d, fa, fb, fd):
|
|
||||||
return (fbracket1(b, d, fb, fd) - fbracket1(a, b, fa, fb))/(d-a)
|
|
||||||
|
|
||||||
# standard bracketing routine
|
|
||||||
# returns ahat, bhat, d
|
|
||||||
# d is a point outside the new interval
|
|
||||||
def bracket(a, b, c, fa, fb, fc):
|
|
||||||
# print('bracket')
|
|
||||||
if fabs(fc) < 1e-12:
|
|
||||||
print("root found : %f ; f(root) = %f" % (c, fc))
|
|
||||||
if fa*fc < 0:
|
|
||||||
return (a, c, b, fa, fc, fb)
|
|
||||||
else:
|
|
||||||
return (c, b, a, fc, fb, fa)
|
|
||||||
|
|
||||||
# finds an approximate solution to the quadratic P(x) = fa + f[a,b]*(x-a) + f[a,b,d]*(x-a)(x-b)
|
|
||||||
# with f[a,b] = fbracket1(a,b) and f[a,b,d] = fbracket2(a,b,d)
|
|
||||||
def NewtonQuadratic(a, b, d, fa, fb, fd, k):
|
|
||||||
A = fbracket2(a,b,d,fa,fb,fd)
|
|
||||||
B = fbracket1(a,b,fa,fb)
|
|
||||||
if A == 0:
|
|
||||||
return a - fa/B
|
|
||||||
if A*fa > 0:
|
|
||||||
r = a
|
|
||||||
else:
|
|
||||||
r = b
|
|
||||||
|
|
||||||
for i in range(k):
|
|
||||||
r = r - B*r/(B + A*(2*r - a - b))
|
|
||||||
return r
|
|
||||||
|
|
||||||
# Inverse cubic interpolation evaluated at 0 (modified Aitken-Neville interpolation)
|
|
||||||
def ipzero(a, b, c, d, fa, fb, fc, fd):
|
|
||||||
Q11 = (c-d)*fc/(fd-fc)
|
|
||||||
Q21 = (b-c)*fb/(fc-fb)
|
|
||||||
Q31 = (a-b)*fa/(fb-fa)
|
|
||||||
D21 = (b-c)*fc/(fc-fb)
|
|
||||||
D31 = (a-b)*fb/(fb-fa)
|
|
||||||
Q22 = (D21-Q11)*fb/(fd-fb)
|
|
||||||
Q32 = (D31-Q21)*fa/(fc-fa)
|
|
||||||
D32 = (D31-Q21)*fc/(fc-fa)
|
|
||||||
Q33 = (D32-Q22)*fa/(fd-fa)
|
|
||||||
return a + Q31 + Q32 + Q33
|
|
||||||
|
|
||||||
def TOMS748_solve1(f, a, b):
|
|
||||||
mu = 0.5
|
|
||||||
fa, fb = f(a), f(b)
|
|
||||||
c = a - fa/fbracket1(a, b, fa, fb) # 4.1.1 secant method
|
|
||||||
fc = f(c)
|
|
||||||
a, b, d, fa, fb, fd = bracket(a, b, c, fa, fb, fc) # 4.1.2
|
|
||||||
e = d
|
|
||||||
fe = fd
|
|
||||||
# ---
|
|
||||||
for n in range(2,10): # 4.1.3
|
|
||||||
if n == 2 or (fa == fb or fb == fd or fd == fe):
|
|
||||||
c = NewtonQuadratic(a, b, d, fa, fb, fd, 2)
|
|
||||||
else:
|
|
||||||
c = ipzero(a, b, d, e, fa, fb, fd, fe)
|
|
||||||
if (c-a)*(c-b) >= 0:
|
|
||||||
c = NewtonQuadratic(a, b, d, fa, fb, fd, 2)
|
|
||||||
# ---
|
|
||||||
fc = f(c)
|
|
||||||
a, b, dbar, fa, fb, fdbar = bracket(a, b, c, fa, fb, fc) # 4.1.4
|
|
||||||
# ---
|
|
||||||
if fabs(fa) < fabs(fb): # 4.1.5
|
|
||||||
u = a
|
|
||||||
fu = fa
|
|
||||||
else:
|
|
||||||
u = b
|
|
||||||
fu = fb
|
|
||||||
# ---
|
|
||||||
c = u - 2*fu/fbracket1(a, b, fa, fb) # 4.1.6
|
|
||||||
# ---
|
|
||||||
if fabs(c - u) > 0.5*(b - a): # 4.1.7
|
|
||||||
c = 0.5*(b + a)
|
|
||||||
# ---
|
|
||||||
fc = f(c)
|
|
||||||
a, b, dhat, fa, fb, fdhat = bracket(a, b, c, fa, fb, fc) # 4.1.8
|
|
||||||
# ---
|
|
||||||
if b - a < mu*(b - a): # 4.1.9
|
|
||||||
d = dhat
|
|
||||||
e = dbar
|
|
||||||
fd = fdhat
|
|
||||||
fe = fdbar
|
|
||||||
else:
|
|
||||||
e = dhat
|
|
||||||
fe = fdhat
|
|
||||||
c = 0.5*(a+b)
|
|
||||||
fc = f(c)
|
|
||||||
a, b, d, fa, fb, fd = bracket(a, b, c, fa, fb, fc)
|
|
||||||
|
|
||||||
# TEST
|
|
||||||
f = lambda E : E - 0.5*sin(E) - 0.3
|
|
||||||
a, b, c, d = 0, 1, 0.3, 1.2
|
|
||||||
fa, fb, fc, fd = f(a), f(b), f(c), f(d)
|
|
||||||
|
|
||||||
print(fbracket1(a, b, fa, fb))
|
|
||||||
print(fbracket2(a, b, d, fa, fb, fd))
|
|
||||||
print(bracket(a, b, c, fa, fb, fc))
|
|
||||||
print(NewtonQuadratic(a, b, d, fa, fb, fd, 2))
|
|
||||||
print(ipzero(a, b, c, d, fa, fb, fc, fd))
|
|
||||||
|
|
||||||
# solution using bracket only :
|
|
||||||
print('bracket only')
|
|
||||||
for i in range(50):
|
|
||||||
c = (a+b)/2
|
|
||||||
fc = f(c)
|
|
||||||
a, b, d, fa, fb, fd = bracket(a, b, c, fa, fb, fc)
|
|
||||||
if fabs(b-a) < 1e-12:
|
|
||||||
break
|
|
||||||
print(i)
|
|
||||||
|
|
||||||
print((a,b), (a+b)/2, b-a)
|
|
||||||
|
|
||||||
print('Newton with derivative')
|
|
||||||
df = lambda E : 1 - 0.5*cos(E)
|
|
||||||
x = 0.5
|
|
||||||
for i in range(50):
|
|
||||||
delta = f(x)/df(x)
|
|
||||||
x = x - delta
|
|
||||||
if fabs(delta) < 1e-12:
|
|
||||||
break
|
|
||||||
print(i)
|
|
||||||
print(x)
|
|
||||||
|
|
||||||
print('TOMS748_solve1 only')
|
|
||||||
def fct1(E):
|
|
||||||
print("x = %20.15f" % E)
|
|
||||||
return E - 0.5*sin(E) - 0.3
|
|
||||||
|
|
||||||
TOMS748_solve1(fct1, 0, 1)
|
|
||||||
Loading…
Add table
Reference in a new issue