LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
LMCAS::anonymous_namespace{newton_raphson.cpp} 命名空间参考

类

struct  RootCallbacks

函数

std::optional< CasError > append_verified_root (std::vector< NumericRoot > &results, const NumericRootResult &candidate, const std::shared_ptr< SymbolicExpr > &expr, const std::string &var, ComputationContext &context, lmmc_real_t tolerance)
NumericRootResult backend_root_result (const lmmc_nonlinear_result_t &backend, double residual_limit)
double evaluate_root_callback (const std::shared_ptr< SymbolicExpr > &expression, double x, RootCallbacks &callbacks)
Result< double > evaluate_root_function (const std::shared_ptr< SymbolicExpr > &expression, const std::string &variable, lmmc_real_t value, ComputationContext &context, const char *operation)
NumericRootResult invalid_root_options (const SolveOptions &options, const char *operation)
lmmc_nonlinear_config_t root_config (const SolveOptions &options, std::size_t max_iterations)
double root_derivative_callback (double x, void *user_data)
double root_function_callback (double x, void *user_data)
NumericRootResult run_bisection_backend (const std::shared_ptr< SymbolicExpr > &function, const std::string &variable, double lower, double upper, ComputationContext &context, const SolveOptions &options, const char *operation)
NumericRootResult run_newton_backend (const std::shared_ptr< SymbolicExpr > &function, const std::shared_ptr< SymbolicExpr > &derivative, const std::string &variable, double initial, ComputationContext &context, const SolveOptions &options, bool enforce_bracket, double bracket_lower, double bracket_upper)
NumericRootsResult solve_initial_guess (const std::shared_ptr< SymbolicExpr > &expr, const std::string &var, ComputationContext &context, const SolveOptions &opts)
NumericRootsResult solve_isolated_polynomial (const std::shared_ptr< SymbolicExpr > &expr, const std::string &var, const Polynomial< Rational > &polynomial, ComputationContext &context, const SolveOptions &opts)

变量

constexpr const char * kBisectionOperation = "bisection"
constexpr const char * kNewtonOperation = "newton_raphson"

类说明

◆ LMCAS::anonymous_namespace{newton_raphson.cpp}::RootCallbacks

struct LMCAS::anonymous_namespace{newton_raphson.cpp}::RootCallbacks

在文件 newton_raphson.cpp 第 77 行定义.

LMCAS::anonymous_namespace{newton_raphson.cpp}::RootCallbacks 的协作图:
类成员
double bracket_lower = 0.0
double bracket_upper = 0.0
ComputationContext * context = nullptr
const shared_ptr< SymbolicExpr > * derivative = nullptr
bool enforce_bracket = false
optional< CasError > error
const shared_ptr< SymbolicExpr > * function = nullptr
bool left_bracket = false
const char * operation = nullptr
const string * variable = nullptr

函数说明

◆ append_verified_root()

std::optional< CasError > LMCAS::anonymous_namespace{newton_raphson.cpp}::append_verified_root ( std::vector< NumericRoot > & results,
const NumericRootResult & candidate,
const std::shared_ptr< SymbolicExpr > & expr,
const std::string & var,
ComputationContext & context,
lmmc_real_t tolerance )

在文件 newton_raphson.cpp 第 220 行定义.

223 {
224 if (!candidate) {
225 return candidate.error();
226 }
227 if (!candidate.value()) {
228 return std::nullopt;
229 }
230 auto root = *candidate.value();
231 auto verified = evaluate_root_function(expr, var, root.value, context, "solve_numeric");
232 if (!verified) {
233 return std::move(verified.error());
234 }
235 root.residual = std::abs(verified.value());
236 if (root.residual <= tolerance) {
237 results.push_back(root);
238 }
239 return std::nullopt;
240}
CasError & error()
Result< double > evaluate_root_function(const std::shared_ptr< SymbolicExpr > &expression, const std::string &variable, lmmc_real_t value, ComputationContext &context, const char *operation)
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context

引用了 append_verified_root(), LMCAS::context, LMCAS::Result< T >::error(), evaluate_root_function() , 以及 LMCAS::Result< T >::value().

被这些函数引用 append_verified_root(), solve_initial_guess() , 以及 solve_isolated_polynomial().

函数调用图:
这是这个函数的调用关系图:

◆ backend_root_result()

NumericRootResult LMCAS::anonymous_namespace{newton_raphson.cpp}::backend_root_result ( const lmmc_nonlinear_result_t & backend,
double residual_limit )

在文件 newton_raphson.cpp 第 137 行定义.

139 {
140 if (!backend.converged || !std::isfinite(backend.root) ||
141 !std::isfinite(backend.residual_norm) ||
142 backend.residual_norm > residual_limit) {
143 return NumericRootResult::success(std::nullopt);
144 }
145 const int iterations =
146 backend.num_iter > static_cast<std::size_t>(std::numeric_limits<int>::max())
147 ? std::numeric_limits<int>::max()
148 : static_cast<int>(backend.num_iter);
150 NumericRoot{backend.root, backend.residual_norm, iterations});
151}
static Result success(std::optional< NumericRoot > value)
数值根结果,包含根值,残差和迭代次数.

引用了 backend_root_result() , 以及 LMCAS::Result< std::optional< NumericRoot > >::success().

被这些函数引用 backend_root_result(), run_bisection_backend() , 以及 run_newton_backend().

函数调用图:
这是这个函数的调用关系图:

◆ evaluate_root_callback()

double LMCAS::anonymous_namespace{newton_raphson.cpp}::evaluate_root_callback ( const std::shared_ptr< SymbolicExpr > & expression,
double x,
RootCallbacks & callbacks )

在文件 newton_raphson.cpp 第 90 行定义.

93 {
94 if (callbacks.error) {
95 return std::numeric_limits<double>::quiet_NaN();
96 }
97 if (callbacks.enforce_bracket &&
98 (x < callbacks.bracket_lower || x > callbacks.bracket_upper)) {
99 callbacks.left_bracket = true;
100 return std::numeric_limits<double>::quiet_NaN();
101 }
103 expression, *callbacks.variable, x, *callbacks.context,
104 callbacks.operation);
105 if (!value) {
106 callbacks.error = value.error();
107 return std::numeric_limits<double>::quiet_NaN();
108 }
109 return value.value();
110}
const std::string const ExprPtr & value

引用了 LMCAS::anonymous_namespace{newton_raphson.cpp}::RootCallbacks::bracket_upper, LMCAS::anonymous_namespace{newton_raphson.cpp}::RootCallbacks::context, LMCAS::anonymous_namespace{newton_raphson.cpp}::RootCallbacks::enforce_bracket, LMCAS::anonymous_namespace{newton_raphson.cpp}::RootCallbacks::error, evaluate_root_callback(), evaluate_root_function(), LMCAS::anonymous_namespace{newton_raphson.cpp}::RootCallbacks::left_bracket, LMCAS::anonymous_namespace{newton_raphson.cpp}::RootCallbacks::operation, LMCAS::value , 以及 LMCAS::anonymous_namespace{newton_raphson.cpp}::RootCallbacks::variable.

被这些函数引用 evaluate_root_callback(), root_derivative_callback() , 以及 root_function_callback().

函数调用图:
这是这个函数的调用关系图:

◆ evaluate_root_function()

Result< double > LMCAS::anonymous_namespace{newton_raphson.cpp}::evaluate_root_function ( const std::shared_ptr< SymbolicExpr > & expression,
const std::string & variable,
lmmc_real_t value,
ComputationContext & context,
const char * operation )

在文件 newton_raphson.cpp 第 25 行定义.

30 {
31 if (!expression) {
34 "root function expression cannot be null",
35 operation);
36 }
37 if (variable.empty()) {
40 "root variable cannot be empty",
41 operation);
42 }
43 auto evaluated = evaluate_numeric(
44 *expression, NumericBindings{{variable, static_cast<double>(value)}},
45 context);
46 if (!evaluated) {
47 return Result<double>::failure(evaluated.error());
48 }
49 if (!evaluated.value().is_finite() ||
50 !std::isfinite(evaluated.value().value)) {
53 "root function evaluation is not finite",
54 operation);
55 }
56 return Result<double>::success(evaluated.value().value);
57}
static Result failure(CasErrc code, std::string message, std::string operation={})
const std::string & variable
Result< ApproxReal > evaluate_numeric(const SymbolicExpr &expression, const NumericBindings &bindings={})
std::unordered_map< std::string, double > NumericBindings

引用了 LMCAS::context, LMCAS::evaluate_numeric(), evaluate_root_function(), LMCAS::Result< T >::failure(), LMCAS::InvalidArgument, LMCAS::NumericFailure, LMCAS::Result< T >::success(), LMCAS::value , 以及 LMCAS::variable.

被这些函数引用 append_verified_root(), evaluate_root_callback(), evaluate_root_function() , 以及 run_bisection_backend().

函数调用图:
这是这个函数的调用关系图:

◆ invalid_root_options()

NumericRootResult LMCAS::anonymous_namespace{newton_raphson.cpp}::invalid_root_options ( const SolveOptions & options,
const char * operation )

在文件 newton_raphson.cpp 第 59 行定义.

61 {
62 if (!std::isfinite(options.tolerance) || options.tolerance <= 0.0) {
65 "root tolerance must be finite and positive",
66 operation);
67 }
68 if (options.max_newton_iterations <= 0) {
71 "maximum iteration count must be positive",
72 operation);
73 }
74 return NumericRootResult::success(std::nullopt);
75}
const std::string ComputationContext const SolveOptions & options

引用了 LMCAS::Result< std::optional< NumericRoot > >::failure(), invalid_root_options(), LMCAS::InvalidArgument, LMCAS::options , 以及 LMCAS::Result< std::optional< NumericRoot > >::success().

被这些函数引用 invalid_root_options().

函数调用图:
这是这个函数的调用关系图:

◆ root_config()

lmmc_nonlinear_config_t LMCAS::anonymous_namespace{newton_raphson.cpp}::root_config ( const SolveOptions & options,
std::size_t max_iterations )

在文件 newton_raphson.cpp 第 122 行定义.

124 {
125 lmmc_nonlinear_config_t config{};
126 if (lmmc_nonlinear_default_config(&config) != LMMC_STATUS_OK) {
127 std::terminate();
128 }
129 config.abs_tol = options.tolerance;
130 config.rel_tol = 0.0;
131 config.max_iter = max_iterations;
132 config.min_derivative = 1.0e-15;
133 config.min_step = 0.0;
134 return config;
135}

引用了 LMCAS::options , 以及 root_config().

被这些函数引用 root_config(), run_bisection_backend() , 以及 run_newton_backend().

函数调用图:
这是这个函数的调用关系图:

◆ root_derivative_callback()

double LMCAS::anonymous_namespace{newton_raphson.cpp}::root_derivative_callback ( double x,
void * user_data )

在文件 newton_raphson.cpp 第 117 行定义.

117 {
118 auto& callbacks = *static_cast<RootCallbacks*>(user_data);
119 return evaluate_root_callback(*callbacks.derivative, x, callbacks);
120}
double evaluate_root_callback(const std::shared_ptr< SymbolicExpr > &expression, double x, RootCallbacks &callbacks)

引用了 evaluate_root_callback() , 以及 root_derivative_callback().

被这些函数引用 root_derivative_callback() , 以及 run_newton_backend().

函数调用图:
这是这个函数的调用关系图:

◆ root_function_callback()

double LMCAS::anonymous_namespace{newton_raphson.cpp}::root_function_callback ( double x,
void * user_data )

在文件 newton_raphson.cpp 第 112 行定义.

112 {
113 auto& callbacks = *static_cast<RootCallbacks*>(user_data);
114 return evaluate_root_callback(*callbacks.function, x, callbacks);
115}

引用了 evaluate_root_callback() , 以及 root_function_callback().

被这些函数引用 root_function_callback(), run_bisection_backend() , 以及 run_newton_backend().

函数调用图:
这是这个函数的调用关系图:

◆ run_bisection_backend()

NumericRootResult LMCAS::anonymous_namespace{newton_raphson.cpp}::run_bisection_backend ( const std::shared_ptr< SymbolicExpr > & function,
const std::string & variable,
double lower,
double upper,
ComputationContext & context,
const SolveOptions & options,
const char * operation )

在文件 newton_raphson.cpp 第 153 行定义.

160 {
161 if (lower == upper) {
163 function, variable, lower, context, operation);
164 if (!value) {
165 return NumericRootResult::failure(value.error());
166 }
167 if (std::abs(value.value()) <= options.tolerance) {
169 NumericRoot{lower, std::abs(value.value()), 0});
170 }
171 return NumericRootResult::success(std::nullopt);
172 }
173
175 RootCallbacks callbacks{
176 &function, nullptr, &variable, &context, operation,
177 false, lower, upper, false, std::nullopt};
178 const std::size_t max_iterations =
179 static_cast<std::size_t>(options.max_newton_iterations) * 3;
180 auto config = root_config(options, max_iterations);
181 lmmc_nonlinear_result_t backend{};
182 const auto status = lmmc_bisection_solve(
183 root_function_callback, &callbacks, lower, upper, &config, &backend);
184 if (callbacks.error) {
185 return NumericRootResult::failure(*callbacks.error);
186 }
187 if (status == LMMC_STATUS_INVALID_ARGUMENT &&
188 backend.failure_reason == LMMC_NONLINEAR_FAILURE_INVALID_BRACKET) {
189 return NumericRootResult::success(std::nullopt);
190 }
191 return backend_root_result(backend, options.tolerance * 100.0);
192}
double root_function_callback(double x, void *user_data)
lmmc_nonlinear_config_t root_config(const SolveOptions &options, std::size_t max_iterations)
NumericRootResult backend_root_result(const lmmc_nonlinear_result_t &backend, double residual_limit)
void ensure_lmmc_lifecycle() noexcept
ComputationContext const std::string & operation
__attribute__((visibility("default"))) ExprResult function(const std __attribute__((visibility("default"))) ExprResult finite_set(std ExprPtr upper
const ExprPtr & lower
ExprResult function(const std::string &name, std::vector< ExprPtr > arguments)

引用了 backend_root_result(), LMCAS::context, LMCAS::detail::ensure_lmmc_lifecycle(), LMCAS::anonymous_namespace{newton_raphson.cpp}::RootCallbacks::error, evaluate_root_function(), LMCAS::Result< std::optional< NumericRoot > >::failure(), LMCAS::function(), LMCAS::lower, LMCAS::options, root_config(), root_function_callback(), run_bisection_backend(), LMCAS::Result< std::optional< NumericRoot > >::success(), LMCAS::upper, LMCAS::value , 以及 LMCAS::variable.

被这些函数引用 run_bisection_backend().

函数调用图:
这是这个函数的调用关系图:

◆ run_newton_backend()

NumericRootResult LMCAS::anonymous_namespace{newton_raphson.cpp}::run_newton_backend ( const std::shared_ptr< SymbolicExpr > & function,
const std::shared_ptr< SymbolicExpr > & derivative,
const std::string & variable,
double initial,
ComputationContext & context,
const SolveOptions & options,
bool enforce_bracket,
double bracket_lower,
double bracket_upper )

在文件 newton_raphson.cpp 第 194 行定义.

203 {
205 RootCallbacks callbacks{
206 &function, &derivative, &variable, &context, kNewtonOperation,
207 enforce_bracket, bracket_lower, bracket_upper, false, std::nullopt};
208 auto config = root_config(
209 options, static_cast<std::size_t>(options.max_newton_iterations));
210 lmmc_nonlinear_result_t backend{};
211 (void)lmmc_newton_solve(
213 &config, &backend);
214 if (callbacks.error) {
215 return NumericRootResult::failure(*callbacks.error);
216 }
217 return backend_root_result(backend, options.tolerance);
218}
double root_derivative_callback(double x, void *user_data)

引用了 backend_root_result(), LMCAS::context, LMCAS::detail::ensure_lmmc_lifecycle(), LMCAS::anonymous_namespace{newton_raphson.cpp}::RootCallbacks::error, LMCAS::Result< std::optional< NumericRoot > >::failure(), LMCAS::function(), kNewtonOperation, LMCAS::options, root_config(), root_derivative_callback(), root_function_callback(), run_newton_backend() , 以及 LMCAS::variable.

被这些函数引用 run_newton_backend().

函数调用图:
这是这个函数的调用关系图:

◆ solve_initial_guess()

NumericRootsResult LMCAS::anonymous_namespace{newton_raphson.cpp}::solve_initial_guess ( const std::shared_ptr< SymbolicExpr > & expr,
const std::string & var,
ComputationContext & context,
const SolveOptions & opts )

在文件 newton_raphson.cpp 第 285 行定义.

287 {
288 detail::RewriteBudget transform_budget(context, (context).limits().max_recursion_depth,
289 (context).limits().max_ast_nodes, "transform");
290 std::vector<NumericRoot> results;
291 const lmmc_real_t initial = opts.has_initial_guess ? opts.initial_guess : 0.0;
292 auto derivative = detail::make_expression_ptr(detail::differentiate_node(detail::node(expr), var, transform_budget));
293 auto candidate = newton_raphson_checked(expr, derivative, var, initial, context, opts);
294 auto failure = append_verified_root(
295 results, candidate, expr, var, context, opts.tolerance);
296 if (failure) {
297 return NumericRootsResult::failure(std::move(*failure));
298 }
299 return NumericRootsResult::success(std::move(results));
300} catch (const CasError& error) {
301 return NumericRootsResult::failure(error);
302} catch (const std::bad_alloc&) {
303 return NumericRootsResult::failure(CasErrc::ResourceLimit, "allocation failed", "solve_initial_guess");
304} catch (const std::length_error& error) {
305 return NumericRootsResult::failure(CasErrc::ResourceLimit, error.what(), "solve_initial_guess");
306} catch (const std::exception& error) {
307 return NumericRootsResult::failure(CasErrc::InternalInvariant, error.what(), "solve_initial_guess");
308}
std::optional< CasError > append_verified_root(std::vector< NumericRoot > &results, const NumericRootResult &candidate, const std::shared_ptr< SymbolicExpr > &expr, const std::string &var, ComputationContext &context, lmmc_real_t tolerance)
SymbolicNodePtr differentiate_node(const SymbolicNodePtr &node, const std::string &variable, RewriteBudget &budget, const FactsQuery &facts, Domain domain)
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
bool has_initial_guess
是否指定了初始猜测值
NumericRootResult newton_raphson_checked(const std::shared_ptr< SymbolicExpr > &function, const std::shared_ptr< SymbolicExpr > &derivative, const std::string &variable, lmmc_real_t initial, lmmc_real_t bracket_lower, lmmc_real_t bracket_upper, ComputationContext &context, const SolveOptions &options)
lmmc_real_t tolerance
收敛容差
lmmc_real_t initial_guess
数值迭代初始猜测值

引用了 append_verified_root(), LMCAS::context, LMCAS::detail::differentiate_node(), LMCAS::Result< std::vector< NumericRoot > >::failure(), LMCAS::SolveOptions::has_initial_guess, LMCAS::SolveOptions::initial_guess, LMCAS::detail::make_expression_ptr(), LMCAS::newton_raphson_checked(), LMCAS::detail::node(), solve_initial_guess(), LMCAS::Result< std::vector< NumericRoot > >::success() , 以及 LMCAS::SolveOptions::tolerance.

被这些函数引用 solve_initial_guess().

函数调用图:
这是这个函数的调用关系图:

◆ solve_isolated_polynomial()

NumericRootsResult LMCAS::anonymous_namespace{newton_raphson.cpp}::solve_isolated_polynomial ( const std::shared_ptr< SymbolicExpr > & expr,
const std::string & var,
const Polynomial< Rational > & polynomial,
ComputationContext & context,
const SolveOptions & opts )

在文件 newton_raphson.cpp 第 242 行定义.

245 {
246 detail::RewriteBudget transform_budget(context, (context).limits().max_recursion_depth,
247 (context).limits().max_ast_nodes, "transform");
248 std::vector<NumericRoot> results;
249 auto derivative = detail::make_expression_ptr(detail::differentiate_node(detail::node(expr), var, transform_budget));
250 auto isolated = isolate_real_roots_checked(polynomial, context);
251 if (!isolated) {
252 return NumericRootsResult::failure(isolated.error());
253 }
254 for (const auto& [lower, upper] : isolated.value()) {
255 if (opts.max_roots > 0 &&
256 static_cast<int>(results.size()) >= opts.max_roots) {
257 break;
258 }
259 auto step = context.consume_steps(1, "solve_numeric");
260 if (!step) {
261 return NumericRootsResult::failure(step.error());
262 }
263 const lmmc_real_t lo = lower.to_double();
264 const lmmc_real_t hi = upper.to_double();
265 const lmmc_real_t initial = solver_detail::finite_midpoint(lo, hi);
266 auto candidate = newton_raphson_checked(
267 expr, derivative, var, initial, lo, hi, context, opts);
269 results, candidate, expr, var, context, opts.tolerance * 100.0);
270 if (failure) {
271 return NumericRootsResult::failure(std::move(*failure));
272 }
273 }
274 return NumericRootsResult::success(std::move(results));
275} catch (const CasError& error) {
276 return NumericRootsResult::failure(error);
277} catch (const std::bad_alloc&) {
278 return NumericRootsResult::failure(CasErrc::ResourceLimit, "allocation failed", "solve_isolated_polynomial");
279} catch (const std::length_error& error) {
280 return NumericRootsResult::failure(CasErrc::ResourceLimit, error.what(), "solve_isolated_polynomial");
281} catch (const std::exception& error) {
282 return NumericRootsResult::failure(CasErrc::InternalInvariant, error.what(), "solve_isolated_polynomial");
283}
QuantityResult failure(CasErrc code, std::string message)
lmmc_real_t finite_midpoint(lmmc_real_t lower, lmmc_real_t upper)
Result< std::vector< std::pair< Rational, Rational > > > isolate_real_roots_checked(const Polynomial< Rational > &polynomial, ComputationContext &context)
int max_roots
数值候选数量预算;精确解集和整数解族保持完整。

引用了 append_verified_root(), LMCAS::context, LMCAS::detail::differentiate_node(), LMCAS::Result< std::vector< NumericRoot > >::failure(), LMCAS::solver_detail::finite_midpoint(), LMCAS::isolate_real_roots_checked(), LMCAS::lower, LMCAS::detail::make_expression_ptr(), LMCAS::SolveOptions::max_roots, LMCAS::newton_raphson_checked(), LMCAS::detail::node(), solve_isolated_polynomial(), LMCAS::Result< std::vector< NumericRoot > >::success(), LMCAS::SolveOptions::tolerance , 以及 LMCAS::upper.

被这些函数引用 solve_isolated_polynomial().

函数调用图:
这是这个函数的调用关系图:

变量说明

◆ kBisectionOperation

const char* LMCAS::anonymous_namespace{newton_raphson.cpp}::kBisectionOperation = "bisection"
constexpr

在文件 newton_raphson.cpp 第 21 行定义.

◆ kNewtonOperation

const char* LMCAS::anonymous_namespace{newton_raphson.cpp}::kNewtonOperation = "newton_raphson"
constexpr

在文件 newton_raphson.cpp 第 22 行定义.

被这些函数引用 run_newton_backend().