LMCAS
Lamina Computer Algebra System
Toggle main menu visibility
载入中...
搜索中...
未找到
mixed_transcendental_refinement.cpp
浏览该文件的文档.
1
#include "
internal/mixed_transcendental_support.hpp
"
2
#include "
internal/solver_support.hpp
"
3
4
#include <cmath>
5
#include <limits>
6
7
namespace
LMCAS::detail
{
8
namespace
{
9
10
class
RootRefinement
{
11
public
:
12
RootRefinement
(
const
std::shared_ptr<SymbolicExpr>& expr,
13
const
std::shared_ptr<SymbolicExpr>& derivative,
14
const
std::string& var,
const
IsolatedInterval
&
interval
,
15
const
SolveOptions
& opts,
RewriteBudget
&
budget
)
16
:
expr_
(expr),
derivative_
(derivative),
var_
(var),
opts_
(opts),
budget_
(
budget
),
17
lo_
(
interval
.lo),
hi_
(
interval
.hi),
x_
(
midpoint
()),
18
f_lo_
(
evaluate
(
lo_
)),
f_hi_
(
evaluate
(
hi_
)),
19
best_
{
x_
, std::numeric_limits<lmmc_real_t>::max(), 0} {}
20
21
std::optional<NumericRoot>
endpoint_root
()
const
{
22
auto
lower
=
root_at
(
lo_
,
f_lo_
, 0);
23
if
(
lower
) {
24
return
lower
;
25
}
26
return
root_at
(
hi_
,
f_hi_
, 0);
27
}
28
29
std::optional<NumericRoot>
bisect
(
30
std::optional<CasError>* failure,
31
bool
* complete) {
32
if
(std::isnan(
f_lo_
) || std::isnan(
f_hi_
) ||
f_lo_
*
f_hi_
> 0.0) {
33
return
root_at
(
x_
,
evaluate
(
x_
), 1);
34
}
35
for
(
int
i = 1; i <=
opts_
.max_newton_iterations; ++i) {
36
if
(!
consume_mixed_step
(
budget_
.context(), failure, complete)) {
37
return
std::nullopt;
38
}
39
const
auto
mid =
midpoint
();
40
const
auto
f_mid =
evaluate
(mid);
41
if
(std::isnan(f_mid)) {
42
hi_
= mid;
43
continue
;
44
}
45
remember
(mid, f_mid, i);
46
auto
root =
root_at
(mid, f_mid, i);
47
if
(root) {
48
return
root;
49
}
50
if
(
f_lo_
* f_mid < 0.0) {
51
hi_
= mid;
52
}
else
{
53
lo_
= mid;
54
f_lo_
= f_mid;
55
}
56
if
(
hi_
-
lo_
<
opts_
.tolerance) {
57
const
auto
final_x =
midpoint
();
58
remember
(final_x,
evaluate
(final_x), i);
59
break
;
60
}
61
}
62
return
best_root
();
63
}
64
65
std::optional<NumericRoot>
newton
(
66
std::optional<CasError>* failure,
67
bool
* complete) {
68
if
(!
resample_endpoints
()) {
69
return
std::nullopt;
70
}
71
for
(
int
i = 1; i <=
opts_
.max_newton_iterations; ++i) {
72
if
(!
consume_mixed_step
(
budget_
.context(), failure, complete)) {
73
return
std::nullopt;
74
}
75
const
auto
fx =
evaluate
(
x_
);
76
if
(std::isnan(fx)) {
77
x_
=
midpoint
();
78
continue
;
79
}
80
remember
(
x_
, fx, i);
81
auto
root =
root_at
(
x_
, fx, i);
82
if
(root) {
83
return
root;
84
}
85
const
auto
dfx =
mixed_evaluate_at
(
derivative_
,
var_
,
x_
,
budget_
);
86
if
(std::isnan(dfx) || std::fabs(dfx) < 1
e
-15) {
87
bisection_step
();
88
continue
;
89
}
90
if
(
accept_newton_step
(fx, dfx)) {
91
continue
;
92
}
93
bisection_step
();
94
if
(
hi_
-
lo_
<
opts_
.tolerance) {
95
const
auto
final_x =
midpoint
();
96
root =
root_at
(final_x,
evaluate
(final_x), i);
97
if
(root) {
98
return
root;
99
}
100
break
;
101
}
102
}
103
return
best_root
();
104
}
105
106
private
:
107
lmmc_real_t
midpoint
()
const
{
108
return
solver_detail::finite_midpoint
(
lo_
,
hi_
);
109
}
110
111
lmmc_real_t
evaluate
(lmmc_real_t x)
const
{
112
return
mixed_evaluate_at
(
expr_
,
var_
, x,
budget_
);
113
}
114
115
std::optional<NumericRoot>
root_at
(
116
lmmc_real_t x, lmmc_real_t fx,
int
iterations)
const
{
117
if
(!std::isnan(fx) && std::fabs(fx) <
opts_
.tolerance) {
118
return
NumericRoot
{x, std::fabs(fx), iterations};
119
}
120
return
std::nullopt;
121
}
122
123
void
remember
(lmmc_real_t x, lmmc_real_t fx,
int
iterations) {
124
const
auto
residual = std::fabs(fx);
125
if
(!std::isnan(residual) && residual <
best_
.residual) {
126
best_
= {x, residual, iterations};
127
}
128
}
129
130
std::optional<NumericRoot>
best_root
()
const
{
131
if
(
best_
.residual <
opts_
.tolerance) {
132
return
best_
;
133
}
134
return
std::nullopt;
135
}
136
137
bool
resample_endpoints
() {
138
if
(std::isnan(
f_lo_
)) {
139
f_lo_
=
evaluate
(
lo_
+ (
hi_
-
lo_
) * 0.01);
140
lo_
=
lo_
+ (
hi_
-
lo_
) * 0.01;
141
}
142
if
(std::isnan(
f_hi_
)) {
143
f_hi_
=
evaluate
(
hi_
- (
hi_
-
lo_
) * 0.01);
144
hi_
=
hi_
- (
hi_
-
lo_
) * 0.01;
145
}
146
return
!std::isnan(
f_lo_
) && !std::isnan(
f_hi_
);
147
}
148
149
void
bisection_step
() {
150
const
auto
mid =
midpoint
();
151
const
auto
f_mid =
evaluate
(mid);
152
if
(!std::isnan(f_mid)) {
153
if
(!std::isnan(
f_lo_
) &&
f_lo_
* f_mid < 0.0) {
154
hi_
= mid;
155
f_hi_
= f_mid;
156
}
else
{
157
lo_
= mid;
158
f_lo_
= f_mid;
159
}
160
}
161
x_
=
midpoint
();
162
}
163
164
bool
accept_newton_step
(lmmc_real_t fx, lmmc_real_t dfx) {
165
const
auto
next =
x_
- fx / dfx;
166
if
(next < lo_ || next >
hi_
) {
167
return
false
;
168
}
169
const
auto
f_next =
evaluate
(next);
170
if
(std::isnan(f_next) || std::fabs(f_next) > std::fabs(fx)) {
171
return
false
;
172
}
173
if
(!std::isnan(
f_lo_
) && fx *
f_lo_
< 0.0) {
174
hi_
=
x_
;
175
f_hi_
= fx;
176
}
else
if
(!std::isnan(
f_hi_
) && fx *
f_hi_
< 0.0) {
177
lo_
=
x_
;
178
f_lo_
= fx;
179
}
180
x_
= next;
181
return
true
;
182
}
183
184
const
std::shared_ptr<SymbolicExpr>&
expr_
;
185
const
std::shared_ptr<SymbolicExpr>&
derivative_
;
186
const
std::string&
var_
;
187
const
SolveOptions
&
opts_
;
188
RewriteBudget
&
budget_
;
189
lmmc_real_t
lo_
;
190
lmmc_real_t
hi_
;
191
lmmc_real_t
x_
;
192
lmmc_real_t
f_lo_
;
193
lmmc_real_t
f_hi_
;
194
NumericRoot
best_
;
195
};
196
197
}
198
199
std::optional<NumericRoot>
refine_root_with_context
(
200
const
std::shared_ptr<SymbolicExpr>& expr,
201
const
std::shared_ptr<SymbolicExpr>& derivative,
202
const
std::string& var,
const
IsolatedInterval
&
interval
,
203
const
SolveOptions
& opts,
RewriteBudget
&
budget
,
204
std::optional<CasError>* failure,
bool
* complete) {
205
RootRefinement refinement(expr, derivative, var,
interval
, opts,
budget
);
206
auto
endpoint = refinement.endpoint_root();
207
if
(endpoint) {
208
return
endpoint;
209
}
210
if
(!derivative) {
211
return
refinement.bisect(failure, complete);
212
}
213
return
refinement.newton(failure, complete);
214
}
215
216
}
217
218
namespace
LMCAS
{
219
220
std::optional<NumericRoot>
refine_root
(
221
const
std::shared_ptr<SymbolicExpr>& expr,
222
const
std::shared_ptr<SymbolicExpr>& derivative,
223
const
std::string& var,
const
IsolatedInterval
&
interval
,
224
const
SolveOptions
& opts) {
225
ComputationContext
context
;
226
detail::RewriteBudget
budget(
context
,
context
.limits().max_recursion_depth,
227
context
.limits().max_ast_nodes,
"refine_root"
);
228
std::optional<CasError> failure;
229
auto
result =
detail::refine_root_with_context
(
230
expr, derivative, var,
interval
, opts, budget, &failure,
nullptr
);
231
if
(failure)
throw
*failure;
232
return
result;
233
}
234
235
}
LMCAS::ComputationContext
定义
computation_context.hpp:99
LMCAS::detail::RewriteBudget
定义
rewrite_budget.hpp:15
LMCAS::detail::anonymous_namespace{mixed_transcendental_refinement.cpp}::RootRefinement::endpoint_root
std::optional< NumericRoot > endpoint_root() const
定义
mixed_transcendental_refinement.cpp:21
LMCAS::detail::anonymous_namespace{mixed_transcendental_refinement.cpp}::RootRefinement::bisection_step
void bisection_step()
定义
mixed_transcendental_refinement.cpp:149
LMCAS::detail::anonymous_namespace{mixed_transcendental_refinement.cpp}::RootRefinement::budget_
RewriteBudget & budget_
定义
mixed_transcendental_refinement.cpp:188
LMCAS::detail::anonymous_namespace{mixed_transcendental_refinement.cpp}::RootRefinement::midpoint
lmmc_real_t midpoint() const
定义
mixed_transcendental_refinement.cpp:107
LMCAS::detail::anonymous_namespace{mixed_transcendental_refinement.cpp}::RootRefinement::lo_
lmmc_real_t lo_
定义
mixed_transcendental_refinement.cpp:189
LMCAS::detail::anonymous_namespace{mixed_transcendental_refinement.cpp}::RootRefinement::best_root
std::optional< NumericRoot > best_root() const
定义
mixed_transcendental_refinement.cpp:130
LMCAS::detail::anonymous_namespace{mixed_transcendental_refinement.cpp}::RootRefinement::evaluate
lmmc_real_t evaluate(lmmc_real_t x) const
定义
mixed_transcendental_refinement.cpp:111
LMCAS::detail::anonymous_namespace{mixed_transcendental_refinement.cpp}::RootRefinement::derivative_
const std::shared_ptr< SymbolicExpr > & derivative_
定义
mixed_transcendental_refinement.cpp:185
LMCAS::detail::anonymous_namespace{mixed_transcendental_refinement.cpp}::RootRefinement::x_
lmmc_real_t x_
定义
mixed_transcendental_refinement.cpp:191
LMCAS::detail::anonymous_namespace{mixed_transcendental_refinement.cpp}::RootRefinement::f_hi_
lmmc_real_t f_hi_
定义
mixed_transcendental_refinement.cpp:193
LMCAS::detail::anonymous_namespace{mixed_transcendental_refinement.cpp}::RootRefinement::hi_
lmmc_real_t hi_
定义
mixed_transcendental_refinement.cpp:190
LMCAS::detail::anonymous_namespace{mixed_transcendental_refinement.cpp}::RootRefinement::opts_
const SolveOptions & opts_
定义
mixed_transcendental_refinement.cpp:187
LMCAS::detail::anonymous_namespace{mixed_transcendental_refinement.cpp}::RootRefinement::f_lo_
lmmc_real_t f_lo_
定义
mixed_transcendental_refinement.cpp:192
LMCAS::detail::anonymous_namespace{mixed_transcendental_refinement.cpp}::RootRefinement::resample_endpoints
bool resample_endpoints()
定义
mixed_transcendental_refinement.cpp:137
LMCAS::detail::anonymous_namespace{mixed_transcendental_refinement.cpp}::RootRefinement::root_at
std::optional< NumericRoot > root_at(lmmc_real_t x, lmmc_real_t fx, int iterations) const
定义
mixed_transcendental_refinement.cpp:115
LMCAS::detail::anonymous_namespace{mixed_transcendental_refinement.cpp}::RootRefinement::bisect
std::optional< NumericRoot > bisect(std::optional< CasError > *failure, bool *complete)
定义
mixed_transcendental_refinement.cpp:29
LMCAS::detail::anonymous_namespace{mixed_transcendental_refinement.cpp}::RootRefinement::best_
NumericRoot best_
定义
mixed_transcendental_refinement.cpp:194
LMCAS::detail::anonymous_namespace{mixed_transcendental_refinement.cpp}::RootRefinement::RootRefinement
RootRefinement(const std::shared_ptr< SymbolicExpr > &expr, const std::shared_ptr< SymbolicExpr > &derivative, const std::string &var, const IsolatedInterval &interval, const SolveOptions &opts, RewriteBudget &budget)
定义
mixed_transcendental_refinement.cpp:12
LMCAS::detail::anonymous_namespace{mixed_transcendental_refinement.cpp}::RootRefinement::accept_newton_step
bool accept_newton_step(lmmc_real_t fx, lmmc_real_t dfx)
定义
mixed_transcendental_refinement.cpp:164
LMCAS::detail::anonymous_namespace{mixed_transcendental_refinement.cpp}::RootRefinement::remember
void remember(lmmc_real_t x, lmmc_real_t fx, int iterations)
定义
mixed_transcendental_refinement.cpp:123
LMCAS::detail::anonymous_namespace{mixed_transcendental_refinement.cpp}::RootRefinement::newton
std::optional< NumericRoot > newton(std::optional< CasError > *failure, bool *complete)
定义
mixed_transcendental_refinement.cpp:65
LMCAS::detail::anonymous_namespace{mixed_transcendental_refinement.cpp}::RootRefinement::var_
const std::string & var_
定义
mixed_transcendental_refinement.cpp:186
LMCAS::detail::anonymous_namespace{mixed_transcendental_refinement.cpp}::RootRefinement::expr_
const std::shared_ptr< SymbolicExpr > & expr_
定义
mixed_transcendental_refinement.cpp:184
mixed_transcendental_support.hpp
LMCAS::detail
多元 Hensel 提升(单变量步)
定义
assumption_context.hpp:31
LMCAS::detail::consume_mixed_step
bool consume_mixed_step(ComputationContext &context, std::optional< CasError > *failure, bool *complete)
定义
mixed_transcendental_evaluation.cpp:37
LMCAS::detail::refine_root_with_context
std::optional< NumericRoot > refine_root_with_context(const std::shared_ptr< SymbolicExpr > &expr, const std::shared_ptr< SymbolicExpr > &derivative, const std::string &var, const IsolatedInterval &interval, const SolveOptions &opts, RewriteBudget &budget, std::optional< CasError > *failure, bool *complete)
定义
mixed_transcendental_refinement.cpp:199
LMCAS::detail::budget
RewriteBudget & budget
定义
expression_transform.hpp:16
LMCAS::detail::mixed_evaluate_at
lmmc_real_t mixed_evaluate_at(const std::shared_ptr< SymbolicExpr > &expr, const std::string &var, lmmc_real_t x, RewriteBudget &budget)
定义
mixed_transcendental_evaluation.cpp:10
LMCAS::solver_detail::finite_midpoint
lmmc_real_t finite_midpoint(lmmc_real_t lower, lmmc_real_t upper)
定义
solver_support.hpp:9
LMCAS
定义
assumption.hpp:11
LMCAS::e
ExprResult e()
定义
expr_values.cpp:112
LMCAS::context
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
定义
exact_factorization.hpp:65
LMCAS::interval
ExprResult interval(ExprPtr lower, ExprPtr upper, bool lower_closed, bool upper_closed)
定义
expr_facade.cpp:168
LMCAS::lower
const ExprPtr & lower
定义
expr.hpp:255
LMCAS::refine_root
std::optional< NumericRoot > refine_root(const std::shared_ptr< SymbolicExpr > &expr, const std::shared_ptr< SymbolicExpr > &derivative, const std::string &var, const IsolatedInterval &interval, const SolveOptions &opts)
定义
mixed_transcendental_refinement.cpp:220
LMCAS::IsolatedInterval
隔离子区间,包含至多一个根
定义
solve_mixed_transcendental.hpp:31
LMCAS::SolveOptions
方程求解选项,控制数值求解行为和结果形式.
定义
solve_strategies.hpp:17
LMCAS::NumericRoot
数值根结果,包含根值,残差和迭代次数.
定义
solve_strategies.hpp:32
solver_support.hpp
src
mixed_transcendental_refinement.cpp
生成于
, 为 LMCAS使用
1.18.0