57{
58 (void) unique;
59 const Ring *R =
p->get_ring();
62 if (P == nullptr) {
63 ERROR(
"expected a polynomial ring");
64 return nullptr;
65 }
67 ERROR(
"expected a univariate polynomial ring");
68 return nullptr;
69 }
71 ERROR(
"expected a nonzero polynomial");
72 return nullptr;
73 }
75 int lodeg,hideg;
77 if (prec == -1)
79
80 mps_context *
s = mps_context_new ();
81 mps_monomial_poly *mps_p = mps_monomial_poly_new (
s, hideg);
82 mps_context_select_algorithm(
s, MPS_ALGORITHM_SECULAR_GA);
83
84 const auto ID = K->
ringID();
85 for (
Nterm *t =
p->get_value(); t !=
nullptr; t = t->next) {
86 int deg;
91 cc.
re = t->coeff.get_double();
93 } else cc = *t->coeff.get_cc_doubles();
94 mps_monomial_poly_set_coefficient_d (
s, mps_p, deg, cc.
re, cc.
im);
96 mpc_t mpc_cc;
99 mpfr_get_f(mpc_cc->r,t->coeff.get_mpfr(),MPFR_RNDN);
100 } else {
101 mpfr_get_f(mpc_cc->r,&t->coeff.get_cc()->re,MPFR_RNDN);
102 mpfr_get_f(mpc_cc->i,&t->coeff.get_cc()->im,MPFR_RNDN);
103 }
104 mps_monomial_poly_set_coefficient_f (
s, mps_p, deg, mpc_cc);
105 mpc_clear(mpc_cc);
109 mpq_init(q);
111 mpq_set(q, t->coeff.get_mpq());
112 else mpq_set_z(q, t->coeff.get_mpz());
113 mps_monomial_poly_set_coefficient_q(
s, mps_p, deg, q,
zero);
114 mpq_clear(q);
116 } else {
117 ERROR(
"'roots' expects coefficients in ZZ, QQ, RR or CC");
118 return nullptr;
119 }
120 }
121
122
123 mps_context_set_input_poly (
s, MPS_POLYNOMIAL (mps_p));
124 mps_context_set_output_prec (
s, prec);
125 mps_context_set_output_goal (
s, MPS_OUTPUT_GOAL_APPROXIMATE);
126
127
129
130
133 result->len =
static_cast<int>(hideg);
134
136 if (prec <= 53) {
137
138 cplx_t *result_mps = cplx_valloc (hideg);
139
140
141 mps_context_get_roots_d (
s, &result_mps,
nullptr);
142
143
144
145
146
147
148
150
151
153 for (int i = 0; i < hideg; i++) {
154 auto& mps_root = result_mps[i];
157 m2_root);
159 }
160
161 free (result_mps);
162 } else {
163 mpc_t *roots = nullptr;
164 rdpe_t *radii = nullptr;
165
166 mps_context_get_roots_m (
s, &roots, &radii);
167
168
169
170
171
172
173
176
177 M2::ARingCCC::Element cc (C0);
178 for (int i = 0; i < hideg; i++) {
179 auto& mps_root = roots[i];
180 mpfr_set_f(&cc.value().
re,mpc_Re(mps_root),MPFR_RNDN);
181 mpfr_set_f(&cc.value().
im,mpc_Im(mps_root),MPFR_RNDN);
183 C0.to_ring_elem(m2_root, cc);
185 }
186
187 free(roots);
188 free(radii);
189 }
190
191 mps_monomial_poly_free(
s, (mps_polynomial *)mps_p);
194}
aring-style adapter for arbitrary-precision complex numbers, stored as (MPFR, MPFR) pairs.
void to_expvector(const_monomial m, exponents_t result_exp) const
Engine-side commutative monomial monoid: variable names, ordering, multidegree machinery,...
virtual const Monoid * getMonoid() const
virtual const Ring * getCoefficients() const
virtual void degree_of_var(int n, const ring_elem a, int &lo, int &hi) const =0
Abstract base for the engine's polynomial-ring hierarchy.
virtual bool is_ZZ() const
virtual M2::RingID ringID() const
virtual unsigned long get_precision() const
virtual const PolynomialRing * cast_to_PolynomialRing() const
virtual bool from_complex_double(double re, double im, ring_elem &result) const
static RingElement * make_raw(const Ring *R, ring_elem f)
@ ring_old
refers to all rings which are not ConcreteRing's.
const Ring * IM2_Ring_CCC(unsigned long prec)
VALGRIND_MAKE_MEM_DEFINED & result(result)
#define getmemarraytype(S, len)
engine_RawRingElementArray engine_RawRingElementArrayOrNull
Singly linked-list node carrying one term of a polynomial-ring element.