|
|
@ -47,27 +47,20 @@ namespace cln { |
|
|
|
// the memory consumption but it also bears a potential for rounding errors. |
|
|
|
// A minimum trunclen that guarantees correctness must be evaluated on a |
|
|
|
// case-by-case basis. |
|
|
|
// |
|
|
|
// As a variation, it is sometimes advantageous to factor out from q[0..N-1] |
|
|
|
// powers of two and put them back in again at the end of the computation by |
|
|
|
// left-shifting. These are distinguished by a boolean template parameter. |
|
|
|
// (Some combinations might not be implemented yet.) |
|
|
|
|
|
|
|
|
|
|
|
struct cl_rational_series { |
|
|
|
// To be set explicitly. |
|
|
|
const cl_I* pv; |
|
|
|
cl_I* qv; |
|
|
|
const cl_I* av; |
|
|
|
const cl_I* bv; |
|
|
|
uintC* qsv; |
|
|
|
}; |
|
|
|
extern const cl_LF eval_rational_series (uintC N, const cl_rational_series& args, uintC len); |
|
|
|
|
|
|
|
// In each the special cases below, none of (a,b,p,q) can be NULL. But qs can |
|
|
|
// still be given or NULL. |
|
|
|
// In each of the special cases below, none of (a,b,p,q) can be NULL. |
|
|
|
|
|
|
|
struct cl_pqab_series { |
|
|
|
const cl_I* pv; |
|
|
|
cl_I* qv; |
|
|
|
const cl_I* av; |
|
|
|
const cl_I* bv; |
|
|
|
uintC* qsv; |
|
|
|
}; |
|
|
|
struct cl_pqab_series_term { |
|
|
|
cl_I p; |
|
|
@ -81,15 +74,14 @@ struct cl_pqab_series_stream { |
|
|
|
// Constructor. |
|
|
|
cl_pqab_series_stream (cl_pqab_series_term (*n)(cl_pqab_series_stream&)) : nextfn (n) {} |
|
|
|
}; |
|
|
|
extern const cl_LF eval_rational_series (uintC N, const cl_pqab_series& args, uintC len); |
|
|
|
extern const cl_LF eval_rational_series (uintC N, cl_pqab_series_stream& args, uintC len); |
|
|
|
extern const cl_LF eval_rational_series (uintC N, cl_pqab_series_stream& args, uintC len, uintC trunclen); |
|
|
|
template<bool shift_q> const cl_LF eval_rational_series (uintC N, const cl_pqab_series& args, uintC len); |
|
|
|
template<bool shift_q> const cl_LF eval_rational_series (uintC N, cl_pqab_series_stream& args, uintC len); |
|
|
|
template<bool shift_q> const cl_LF eval_rational_series (uintC N, cl_pqab_series_stream& args, uintC len, uintC trunclen); |
|
|
|
|
|
|
|
struct cl_pqb_series { |
|
|
|
const cl_I* pv; |
|
|
|
cl_I* qv; |
|
|
|
const cl_I* bv; |
|
|
|
uintC* qsv; |
|
|
|
}; |
|
|
|
struct cl_pqb_series_term { |
|
|
|
cl_I p; |
|
|
@ -102,15 +94,14 @@ struct cl_pqb_series_stream { |
|
|
|
// Constructor. |
|
|
|
cl_pqb_series_stream (cl_pqb_series_term (*n)(cl_pqb_series_stream&)) : nextfn (n) {} |
|
|
|
}; |
|
|
|
extern const cl_LF eval_rational_series (uintC N, const cl_pqb_series& args, uintC len); |
|
|
|
extern const cl_LF eval_rational_series (uintC N, cl_pqb_series_stream& args, uintC len); |
|
|
|
extern const cl_LF eval_rational_series (uintC N, cl_pqb_series_stream& args, uintC len, uintC trunclen); |
|
|
|
template<bool shift_q> const cl_LF eval_rational_series (uintC N, const cl_pqb_series& args, uintC len); |
|
|
|
template<bool shift_q> const cl_LF eval_rational_series (uintC N, cl_pqb_series_stream& args, uintC len); |
|
|
|
template<bool shift_q> const cl_LF eval_rational_series (uintC N, cl_pqb_series_stream& args, uintC len, uintC trunclen); |
|
|
|
|
|
|
|
struct cl_pqa_series { |
|
|
|
const cl_I* pv; |
|
|
|
cl_I* qv; |
|
|
|
const cl_I* av; |
|
|
|
uintC* qsv; |
|
|
|
}; |
|
|
|
struct cl_pqa_series_term { |
|
|
|
cl_I p; |
|
|
@ -123,14 +114,13 @@ struct cl_pqa_series_stream { |
|
|
|
// Constructor. |
|
|
|
cl_pqa_series_stream (cl_pqa_series_term (*n)(cl_pqa_series_stream&)) : nextfn (n) {} |
|
|
|
}; |
|
|
|
extern const cl_LF eval_rational_series (uintC N, const cl_pqa_series& args, uintC len); |
|
|
|
extern const cl_LF eval_rational_series (uintC N, cl_pqa_series_stream& args, uintC len); |
|
|
|
extern const cl_LF eval_rational_series (uintC N, cl_pqa_series_stream& args, uintC len, uintC trunclen); |
|
|
|
template<bool shift_q> const cl_LF eval_rational_series (uintC N, const cl_pqa_series& args, uintC len); |
|
|
|
template<bool shift_q> const cl_LF eval_rational_series (uintC N, cl_pqa_series_stream& args, uintC len); |
|
|
|
template<bool shift_q> const cl_LF eval_rational_series (uintC N, cl_pqa_series_stream& args, uintC len, uintC trunclen); |
|
|
|
|
|
|
|
struct cl_pq_series { |
|
|
|
const cl_I* pv; |
|
|
|
cl_I* qv; |
|
|
|
uintC* qsv; |
|
|
|
}; |
|
|
|
struct cl_pq_series_term { |
|
|
|
cl_I p; |
|
|
@ -142,81 +132,98 @@ struct cl_pq_series_stream { |
|
|
|
// Constructor. |
|
|
|
cl_pq_series_stream (cl_pq_series_term (*n)(cl_pq_series_stream&)) : nextfn (n) {} |
|
|
|
}; |
|
|
|
extern const cl_LF eval_rational_series (uintC N, const cl_pq_series& args, uintC len); |
|
|
|
extern const cl_LF eval_rational_series (uintC N, cl_pq_series_stream& args, uintC len); |
|
|
|
extern const cl_LF eval_rational_series (uintC N, cl_pq_series_stream& args, uintC len, uintC trunclen); |
|
|
|
template<bool shift_q> const cl_LF eval_rational_series (uintC N, const cl_pq_series& args, uintC len); |
|
|
|
template<bool shift_q> const cl_LF eval_rational_series (uintC N, cl_pq_series_stream& args, uintC len); |
|
|
|
template<bool shift_q> const cl_LF eval_rational_series (uintC N, cl_pq_series_stream& args, uintC len, uintC trunclen); |
|
|
|
|
|
|
|
struct cl_pab_series { |
|
|
|
const cl_I* pv; |
|
|
|
const cl_I* av; |
|
|
|
const cl_I* bv; |
|
|
|
}; |
|
|
|
extern const cl_LF eval_rational_series (uintC N, const cl_pab_series& args, uintC len); |
|
|
|
const cl_LF eval_rational_series (uintC N, const cl_pab_series& args, uintC len); |
|
|
|
|
|
|
|
struct cl_pb_series { |
|
|
|
const cl_I* pv; |
|
|
|
const cl_I* bv; |
|
|
|
}; |
|
|
|
extern const cl_LF eval_rational_series (uintC N, const cl_pb_series& args, uintC len); |
|
|
|
const cl_LF eval_rational_series (uintC N, const cl_pb_series& args, uintC len); |
|
|
|
|
|
|
|
struct cl_pa_series { |
|
|
|
const cl_I* pv; |
|
|
|
const cl_I* av; |
|
|
|
}; |
|
|
|
extern const cl_LF eval_rational_series (uintC N, const cl_pa_series& args, uintC len); |
|
|
|
const cl_LF eval_rational_series (uintC N, const cl_pa_series& args, uintC len); |
|
|
|
|
|
|
|
struct cl_p_series { |
|
|
|
const cl_I* pv; |
|
|
|
}; |
|
|
|
extern const cl_LF eval_rational_series (uintC N, const cl_p_series& args, uintC len); |
|
|
|
const cl_LF eval_rational_series (uintC N, const cl_p_series& args, uintC len); |
|
|
|
|
|
|
|
struct cl_qab_series { |
|
|
|
cl_I* qv; |
|
|
|
const cl_I* av; |
|
|
|
const cl_I* bv; |
|
|
|
uintC* qsv; |
|
|
|
}; |
|
|
|
extern const cl_LF eval_rational_series (uintC N, const cl_qab_series& args, uintC len); |
|
|
|
template<bool shift_q> const cl_LF eval_rational_series (uintC N, const cl_qab_series& args, uintC len); |
|
|
|
|
|
|
|
struct cl_qb_series { |
|
|
|
cl_I* qv; |
|
|
|
const cl_I* bv; |
|
|
|
uintC* qsv; |
|
|
|
}; |
|
|
|
extern const cl_LF eval_rational_series (uintC N, const cl_qb_series& args, uintC len); |
|
|
|
struct cl_qb_series_term { |
|
|
|
cl_I q; |
|
|
|
cl_I b; |
|
|
|
}; |
|
|
|
struct cl_qb_series_stream { |
|
|
|
cl_qb_series_term (*nextfn)(cl_qb_series_stream&); |
|
|
|
cl_qb_series_term next () { return nextfn(*this); } |
|
|
|
// Constructor. |
|
|
|
cl_qb_series_stream (cl_qb_series_term (*n)(cl_qb_series_stream&)) : nextfn (n) {} |
|
|
|
}; |
|
|
|
template<bool shift_q> const cl_LF eval_rational_series (uintC N, const cl_qb_series& args, uintC len); |
|
|
|
template<bool shift_q> const cl_LF eval_rational_series (uintC N, cl_qb_series_stream& args, uintC len); |
|
|
|
|
|
|
|
struct cl_qa_series { |
|
|
|
cl_I* qv; |
|
|
|
const cl_I* av; |
|
|
|
uintC* qsv; |
|
|
|
}; |
|
|
|
extern const cl_LF eval_rational_series (uintC N, const cl_qa_series& args, uintC len); |
|
|
|
template<bool shift_q> const cl_LF eval_rational_series (uintC N, const cl_qa_series& args, uintC len); |
|
|
|
|
|
|
|
struct cl_q_series { |
|
|
|
cl_I* qv; |
|
|
|
uintC* qsv; |
|
|
|
}; |
|
|
|
extern const cl_LF eval_rational_series (uintC N, const cl_q_series& args, uintC len); |
|
|
|
struct cl_q_series_term { |
|
|
|
cl_I q; |
|
|
|
}; |
|
|
|
struct cl_q_series_stream { |
|
|
|
cl_q_series_term (*nextfn)(cl_q_series_stream&); |
|
|
|
cl_q_series_term next () { return nextfn(*this); } |
|
|
|
// Constructor. |
|
|
|
cl_q_series_stream (cl_q_series_term (*n)(cl_q_series_stream&)) : nextfn (n) {} |
|
|
|
}; |
|
|
|
template<bool shift_q> const cl_LF eval_rational_series (uintC N, const cl_q_series& args, uintC len); |
|
|
|
template<bool shift_q> const cl_LF eval_rational_series (uintC N, cl_q_series_stream& args, uintC len); |
|
|
|
|
|
|
|
struct cl_ab_series { |
|
|
|
const cl_I* av; |
|
|
|
const cl_I* bv; |
|
|
|
}; |
|
|
|
extern const cl_LF eval_rational_series (uintC N, const cl_ab_series& args, uintC len); |
|
|
|
const cl_LF eval_rational_series (uintC N, const cl_ab_series& args, uintC len); |
|
|
|
|
|
|
|
struct cl_b_series { |
|
|
|
const cl_I* bv; |
|
|
|
}; |
|
|
|
extern const cl_LF eval_rational_series (uintC N, const cl_b_series& args, uintC len); |
|
|
|
const cl_LF eval_rational_series (uintC N, const cl_b_series& args, uintC len); |
|
|
|
|
|
|
|
struct cl_a_series { |
|
|
|
const cl_I* av; |
|
|
|
}; |
|
|
|
extern const cl_LF eval_rational_series (uintC N, const cl_a_series& args, uintC len); |
|
|
|
const cl_LF eval_rational_series (uintC N, const cl_a_series& args, uintC len); |
|
|
|
|
|
|
|
struct cl__series { |
|
|
|
}; |
|
|
|
extern const cl_LF eval_rational_series (uintC N, const cl__series& args, uintC len); |
|
|
|
const cl_LF eval_rational_series (uintC N, const cl__series& args, uintC len); |
|
|
|
|
|
|
|
|
|
|
|
// [Generalization.] |
|
|
@ -252,13 +259,13 @@ struct cl_pqcd_series_stream { |
|
|
|
// Constructor. |
|
|
|
cl_pqcd_series_stream( cl_pqcd_series_term (*n)(cl_pqcd_series_stream&)) : nextfn (n) {} |
|
|
|
}; |
|
|
|
extern void eval_pqcd_series_aux (uintC N, cl_pqcd_series_term* args, cl_pqcd_series_result<cl_I>& Z, bool rightmost = true); |
|
|
|
extern void eval_pqcd_series_aux (uintC N, cl_pqcd_series_stream& args, cl_pqcd_series_result<cl_I>& Z, bool rightmost = true); |
|
|
|
extern void eval_pqcd_series_aux (uintC N, cl_pqcd_series_stream& args, cl_pqcd_series_result<cl_R>& Z, uintC trunclen, bool rightmost = true); |
|
|
|
void eval_pqcd_series_aux (uintC N, cl_pqcd_series_term* args, cl_pqcd_series_result<cl_I>& Z, bool rightmost = true); |
|
|
|
void eval_pqcd_series_aux (uintC N, cl_pqcd_series_stream& args, cl_pqcd_series_result<cl_I>& Z, bool rightmost = true); |
|
|
|
void eval_pqcd_series_aux (uintC N, cl_pqcd_series_stream& args, cl_pqcd_series_result<cl_R>& Z, uintC trunclen, bool rightmost = true); |
|
|
|
// Ditto, but returns U/S. |
|
|
|
extern const cl_LF eval_pqcd_series (uintC N, cl_pqcd_series_term* args, uintC len); |
|
|
|
extern const cl_LF eval_pqcd_series (uintC N, cl_pqcd_series_stream& args, uintC len); |
|
|
|
extern const cl_LF eval_pqcd_series (uintC N, cl_pqcd_series_stream& args, uintC len, uintC trunclen); |
|
|
|
const cl_LF eval_pqcd_series (uintC N, cl_pqcd_series_term* args, uintC len); |
|
|
|
const cl_LF eval_pqcd_series (uintC N, cl_pqcd_series_stream& args, uintC len); |
|
|
|
const cl_LF eval_pqcd_series (uintC N, cl_pqcd_series_stream& args, uintC len, uintC trunclen); |
|
|
|
|
|
|
|
// [Special case c(n)=1.] |
|
|
|
// Subroutine: |
|
|
@ -291,13 +298,26 @@ struct cl_pqd_series_stream { |
|
|
|
// Constructor. |
|
|
|
cl_pqd_series_stream( cl_pqd_series_term (*n)(cl_pqd_series_stream&)) : nextfn (n) {} |
|
|
|
}; |
|
|
|
extern void eval_pqd_series_aux (uintC N, cl_pqd_series_term* args, cl_pqd_series_result<cl_I>& Z, bool rightmost = true); |
|
|
|
extern void eval_pqd_series_aux (uintC N, cl_pqd_series_stream& args, cl_pqd_series_result<cl_I>& Z, bool rightmost = true); |
|
|
|
extern void eval_pqd_series_aux (uintC N, cl_pqd_series_stream& args, cl_pqd_series_result<cl_R>& Z, uintC trunclen, bool rightmost = true); |
|
|
|
void eval_pqd_series_aux (uintC N, cl_pqd_series_term* args, cl_pqd_series_result<cl_I>& Z, bool rightmost = true); |
|
|
|
void eval_pqd_series_aux (uintC N, cl_pqd_series_stream& args, cl_pqd_series_result<cl_I>& Z, bool rightmost = true); |
|
|
|
void eval_pqd_series_aux (uintC N, cl_pqd_series_stream& args, cl_pqd_series_result<cl_R>& Z, uintC trunclen, bool rightmost = true); |
|
|
|
// Ditto, but returns U/S. |
|
|
|
extern const cl_LF eval_pqd_series (uintC N, cl_pqd_series_term* args, uintC len); |
|
|
|
extern const cl_LF eval_pqd_series (uintC N, cl_pqd_series_stream& args, uintC len); |
|
|
|
extern const cl_LF eval_pqd_series (uintC N, cl_pqd_series_stream& args, uintC len, uintC trunclen); |
|
|
|
const cl_LF eval_pqd_series (uintC N, cl_pqd_series_term* args, uintC len); |
|
|
|
const cl_LF eval_pqd_series (uintC N, cl_pqd_series_stream& args, uintC len); |
|
|
|
const cl_LF eval_pqd_series (uintC N, cl_pqd_series_stream& args, uintC len, uintC trunclen); |
|
|
|
|
|
|
|
// Helper function to divide q by the largest s such that 2^s divides q, returns s. |
|
|
|
inline uintC |
|
|
|
pullout_shiftcount(cl_I& q) |
|
|
|
{ |
|
|
|
var uintC qs = 0; |
|
|
|
if (!zerop(q)) { |
|
|
|
qs = ord2(q); |
|
|
|
if (qs > 0) |
|
|
|
q = q >> qs; |
|
|
|
} |
|
|
|
return qs; |
|
|
|
} |
|
|
|
|
|
|
|
// Helper function to convert integer of length > trunclen to long float of |
|
|
|
// length = trunclen. |
|
|
|