Skip to content

Commit 0e8a341

Browse files
authored
Merge pull request #75 from JohnCremona/bigcomplex
Implementation of bigcomplex class
2 parents 6639c6b + 7558e4a commit 0e8a341

File tree

20 files changed

+220
-170
lines changed

20 files changed

+220
-170
lines changed

configure.ac

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ AC_PREREQ([2.65])
77
# The version is the concatenation of 'v' and the year, month, date: vyyyymmdd
88
# To access this as a string or integer triple, see libsrc/eclib/version.h
99

10-
AC_INIT([eclib], [20221012], [[email protected]])
10+
AC_INIT([eclib], [20230424], [[email protected]])
1111

1212
AM_INIT_AUTOMAKE([-Wall])
1313
AC_MSG_NOTICE([Configuring eclib...])
@@ -40,9 +40,10 @@ LT_INIT
4040
#
4141
# NB The suffix of the library name (libec.so here) is (c-a).a.r
4242

43-
LT_CURRENT=11
43+
LT_CURRENT=12
4444
LT_REVISION=0
45-
LT_AGE=1
45+
LT_AGE=2
46+
4647
AC_SUBST(LT_CURRENT)
4748
AC_SUBST(LT_REVISION)
4849
AC_SUBST(LT_AGE)

libsrc/Makefile.am

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ LIBS = $(FLINT_LIBS) $(NTL_LIBS) $(PARI_LIBS) $(BOOST_LIBS) $(PTHREAD_LIB
1515

1616
lib_LTLIBRARIES = libec.la
1717

18-
PROCS_DOTHS = eclib/interface.h eclib/templates.h eclib/arith.h eclib/xmod.h eclib/marith.h eclib/compproc.h eclib/vec.h eclib/vector.h eclib/mat.h eclib/matrix.h eclib/sub.h eclib/subspace.h eclib/rat.h eclib/bigrat.h eclib/kbessel.h eclib/svec.h eclib/svector.h eclib/smat.h eclib/smatrix.h eclib/smat_elim.h eclib/smatrix_elim.h eclib/mvector.h eclib/mmatrix.h eclib/msubspace.h eclib/method.h eclib/splitbase.h eclib/xsplit.h eclib/conic.h eclib/legendre.h eclib/quadratic.h eclib/unimod.h eclib/illl.h eclib/hilbert.h eclib/timer.h eclib/cubic.h eclib/gf.h eclib/polys.h eclib/realroots.h eclib/parifact.h eclib/p2points.h eclib/xsplit_data.h eclib/threadpool.h eclib/logger.h eclib/types.h
18+
PROCS_DOTHS = eclib/interface.h eclib/templates.h eclib/arith.h eclib/xmod.h eclib/marith.h eclib/bigcomplex.h eclib/compproc.h eclib/vec.h eclib/vector.h eclib/mat.h eclib/matrix.h eclib/sub.h eclib/subspace.h eclib/rat.h eclib/bigrat.h eclib/kbessel.h eclib/svec.h eclib/svector.h eclib/smat.h eclib/smatrix.h eclib/smat_elim.h eclib/smatrix_elim.h eclib/mvector.h eclib/mmatrix.h eclib/msubspace.h eclib/method.h eclib/splitbase.h eclib/xsplit.h eclib/conic.h eclib/legendre.h eclib/quadratic.h eclib/unimod.h eclib/illl.h eclib/hilbert.h eclib/timer.h eclib/cubic.h eclib/gf.h eclib/polys.h eclib/realroots.h eclib/parifact.h eclib/p2points.h eclib/xsplit_data.h eclib/threadpool.h eclib/logger.h eclib/types.h
1919

2020
QCURVES_DOTHS = eclib/curve.h eclib/points.h eclib/cperiods.h eclib/isogs.h eclib/reader.h eclib/mwprocs.h eclib/lambda.h eclib/sifter.h eclib/sieve_search.h eclib/htconst.h eclib/egr.h eclib/saturate.h eclib/divpol.h eclib/pointsmod.h eclib/curvemod.h eclib/ffmod.h eclib/tlss.h eclib/elog.h eclib/getcurve.h
2121

libsrc/cperiods.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ void Cperiods::store_sums()
329329
}
330330
w1squared = w1*w1;
331331
w1cubed = w1*w1squared;
332-
bigcomplex term = one, qtm = qtau;
332+
bigcomplex term(one), qtm(qtau);
333333
sum3=to_bigfloat(0);
334334
for (bigfloat m=to_bigfloat(1); ! SMALL(term); m+=1)
335335
{

libsrc/cubic.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ bigcomplex cubic::hess_root() const
362362
if(!is_positive(disc()))
363363
{
364364
cout<<"Error: hess_root called with negative dicriminant!\n";
365-
return to_bigfloat(0);
365+
return bigcomplex(); // 0
366366
}
367367
bigfloat P = I2bigfloat(p_semi());
368368
bigfloat Q = I2bigfloat(q_semi());

libsrc/curvedata.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -321,9 +321,9 @@ Curvedata opt_x_shift(const Curvedata& C, bigint& k)
321321
C.getbi(b2,b4,b6,b8);
322322
cubic b_cubic(four,b2,2*b4,b6);
323323
k = b_cubic.shift_reduce();
324-
Curvedata CC(C);
325-
CC.transform(k,zero,zero);
326-
return CC;
324+
Curvedata CD(C);
325+
CD.transform(k,zero,zero);
326+
return CD;
327327
}
328328

329329
#if(0)

libsrc/eclib/bigcomplex.h

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
// bigcomplex.h: complex class built on NTL's RR
2+
//////////////////////////////////////////////////////////////////////////
3+
//
4+
// Copyright 1990-2023 John Cremona
5+
//
6+
// This file is part of the eclib package.
7+
//
8+
// eclib is free software; you can redistribute it and/or modify it
9+
// under the terms of the GNU General Public License as published by the
10+
// Free Software Foundation; either version 2 of the License, or (at your
11+
// option) any later version.
12+
//
13+
// eclib is distributed in the hope that it will be useful, but WITHOUT
14+
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15+
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16+
// for more details.
17+
//
18+
// You should have received a copy of the GNU General Public License
19+
// along with eclib; if not, write to the Free Software Foundation,
20+
// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21+
//
22+
//////////////////////////////////////////////////////////////////////////
23+
24+
#ifndef _ECLIB_BIGCOMPLEX_H_
25+
#define _ECLIB_BIGCOMPLEX_H_
26+
27+
class bigcomplex{
28+
public:
29+
explicit bigcomplex() : re(RR()), im(RR()) {;}
30+
explicit bigcomplex(const RR& r) : re(r), im(RR()) {;}
31+
explicit bigcomplex(const RR& r, const RR& i) : re(r), im(i) {;}
32+
bigcomplex(const bigcomplex&) = default;
33+
34+
// standard class methods
35+
RR real() const {return re;};
36+
RR imag() const {return im;};
37+
RR norm() const {return sqr(re)+sqr(im);};
38+
RR arg() const { return atan2(im, re);};
39+
RR abs() const {return ::NTL::sqrt(norm());};
40+
bigcomplex conj() const {return bigcomplex(re,-im);};
41+
bigcomplex timesI() const {return bigcomplex(-im,re);};
42+
int IsReal() const {return ::NTL::IsZero(im);}
43+
int IsImaginary() const {return ::NTL::IsZero(re);}
44+
int IsZero() const {return ::NTL::IsZero(re) && ::NTL::IsZero(im);}
45+
46+
47+
bigcomplex operator= (const RR& r) {re=r; im=RR(); return *this;}
48+
bigcomplex operator+=(const RR& r) {re+=r; return *this;};
49+
bigcomplex operator+(const RR& r) const {bigcomplex z(*this); z.re+=r; return z;};
50+
bigcomplex operator-=(const RR& r) {re -= r; return *this;};
51+
bigcomplex operator-(const RR& r) const {bigcomplex z(*this); z.re-=r; return z;};
52+
bigcomplex operator*=(const RR& r) {re*=r; im*=r; return *this;};
53+
bigcomplex operator*(const RR& r) const {bigcomplex z(*this); z.re*=r; z.im*=r; return z;};
54+
bigcomplex operator/=(const RR& r) {re/=r; im/=r; return *this;};
55+
bigcomplex operator/(const RR& r) const {bigcomplex z(*this); z.re/=r; z.im/=r; return z;};
56+
57+
bigcomplex operator=(const bigcomplex& z) {re=z.re; im=z.im; return *this;};
58+
bigcomplex operator+=(const bigcomplex& z) {re+=z.re; im+=z.im; return *this;};
59+
bigcomplex operator+(const bigcomplex& z) const {return bigcomplex(re+z.re, im+z.im);};
60+
bigcomplex operator+() {return *this;};
61+
bigcomplex operator-=(const bigcomplex& z) {re-=z.re; im-=z.im; return *this;};
62+
bigcomplex operator-(const bigcomplex& z) const {return bigcomplex(re-z.re, im-z.im);};
63+
bigcomplex operator-() const {return bigcomplex(-re,-im);};
64+
bigcomplex operator*=(const bigcomplex& z) {RR x = re; re=x*z.re-im*z.im; im = x*z.im+im*z.re; return *this;};
65+
bigcomplex operator*(const bigcomplex& z) const {bigcomplex w(*this); w*=z; return w;};
66+
bigcomplex operator/=(const bigcomplex& z) {RR r=z.norm(), x = re; re=(x*z.re+im*z.im)/r; im = (-x*z.im+im*z.re)/r; return *this;};
67+
bigcomplex operator/(const bigcomplex& z) const {bigcomplex w(*this); w/=z; return w;};
68+
69+
// standard functions as class methods:
70+
bigcomplex sqrt() const {RR r = abs(); RR u = ::NTL::sqrt((r+re)/2), v=::NTL::sqrt((r-re)/2); if (im<0) v=-v; return bigcomplex(u,v);};
71+
bigcomplex cos() const {bigcomplex z(this->timesI()); return (z+z.conj())/to_RR(2);};
72+
bigcomplex sin() const {bigcomplex z(this->timesI()); return (z-z.conj())/bigcomplex(RR(),to_RR(2));};
73+
bigcomplex exp() const {RR e = ::NTL::exp(re); return bigcomplex(e * ::NTL::cos(im), e * ::NTL::sin(im));};
74+
bigcomplex log() const {return bigcomplex(::NTL::log(abs()), arg());}
75+
76+
77+
operator string() const
78+
{
79+
ostringstream s;
80+
s << "(" << re << "," << im << ")";
81+
return s.str();
82+
}
83+
84+
string pretty_string() const
85+
{
86+
ostringstream s;
87+
if (IsReal())
88+
{
89+
s<<re;
90+
return s.str();
91+
}
92+
if (IsImaginary())
93+
{
94+
if (IsOne(im))
95+
s << "";
96+
else
97+
if (IsOne(-im))
98+
s << "-";
99+
else s << im;
100+
}
101+
else
102+
{
103+
s<<re;
104+
if(im>0)
105+
s<<"+";
106+
else
107+
s<<"-";
108+
RR abs_im(::NTL::abs(im));
109+
if (abs_im>1)
110+
s<<abs_im;
111+
}
112+
s<<"i";
113+
return s.str();
114+
}
115+
116+
friend ostream& operator<<(ostream& s, const bigcomplex& z)
117+
{
118+
s << string(z);
119+
return s;
120+
}
121+
122+
// Implementation
123+
private:
124+
RR re, im;
125+
};
126+
127+
128+
// inline functions
129+
inline RR real(const bigcomplex& z) {return z.real();};
130+
inline RR imag(const bigcomplex& z) {return z.imag();};
131+
inline RR norm(const bigcomplex& z) {return z.norm();};
132+
inline RR arg(const bigcomplex& z) { return z.arg();};
133+
inline RR abs(const bigcomplex& z) {return z.abs();};
134+
inline bigcomplex conj(const bigcomplex& z) {return z.conj();};
135+
inline int IsReal(const bigcomplex& z) {return z.IsReal();}
136+
inline int IsImaginary(const bigcomplex& z) {return z.IsImaginary();}
137+
inline int IsZero(const bigcomplex& z) {return z.IsZero();}
138+
139+
// operators with left operand RR
140+
inline bigcomplex operator+(const RR& r, const bigcomplex& z) {return bigcomplex(r)+z;};
141+
inline bigcomplex operator-(const RR& r, const bigcomplex& z) {return bigcomplex(r)-z;};
142+
inline bigcomplex operator*(const RR& r, const bigcomplex& z) {return bigcomplex(r)*z;};
143+
inline bigcomplex operator/(const RR& r, const bigcomplex& z) {return bigcomplex(r)/z;};
144+
145+
// standard method functions as functions:
146+
inline bigcomplex sqrt(const bigcomplex& z) {bigcomplex w(z); return w.sqrt();};
147+
inline bigcomplex cos(const bigcomplex& z) {bigcomplex w(z); return w.cos();};
148+
inline bigcomplex sin(const bigcomplex& z) {bigcomplex w(z); return w.sin();};
149+
inline bigcomplex exp(const bigcomplex& z) {bigcomplex w(z); return w.exp();};
150+
inline bigcomplex log(const bigcomplex& z) {bigcomplex w(z); return w.log();};
151+
152+
153+
inline void swap(bigcomplex& z1, bigcomplex& z2) {bigcomplex z3(z1); z1=z2; z2=z3;}
154+
155+
#endif

libsrc/eclib/compproc.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,13 @@ void getc4c6(const bigcomplex& w1, const bigcomplex& w2, bigcomplex& c4, bigcomp
3838
bigcomplex discriminant(const bigcomplex& b, const bigcomplex& c, const bigcomplex& d);
3939

4040
vector<bigcomplex> solvecubic(const bigcomplex& c1, const bigcomplex& c2, const bigcomplex& c3);
41+
inline vector<bigcomplex> solvecubic(const bigfloat& c1, const bigfloat& c2, const bigfloat& c3)
42+
{return solvecubic(bigcomplex(c1), bigcomplex(c2), bigcomplex(c3));}
43+
4144
vector<bigcomplex> solvequartic(const bigcomplex& a, const bigcomplex& b, const bigcomplex& c, const bigcomplex& d);
45+
inline vector<bigcomplex> solvequartic(const bigfloat& a, const bigfloat& b, const bigfloat& c, const bigfloat& d)
46+
{return solvequartic(bigcomplex(a), bigcomplex(b), bigcomplex(c), bigcomplex(d));}
47+
4248
vector<bigcomplex> solverealquartic(const bigfloat& a, const bigfloat& b, const bigfloat& c, const bigfloat& d, const bigfloat& e);
4349

4450
void quadsolve(const bigfloat& p, const bigfloat& q, bigcomplex& root1,bigcomplex& root2);

libsrc/eclib/htconst.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,9 @@ class CurveHeightConst : public CurveRed, Cperiods {
163163
bigfloat psi(const bigfloat& x);
164164
vector<bigfloat> ordinates(const bigfloat& x);
165165
vector<bigcomplex> ztopoint(const bigcomplex& z)
166-
{return ellztopoint(z,I2bigfloat(a1),I2bigfloat(a2),I2bigfloat(a3));}
166+
{return ellztopoint(z, bigcomplex(I2bigfloat(a1)), bigcomplex(I2bigfloat(a2)), bigcomplex(I2bigfloat(a3)));}
167167
bigcomplex pointtoz(const bigfloat& x, const bigfloat& y)
168-
{return ellpointtoz(*this,*this,x,y);}
168+
{return ellpointtoz(*this, *this, x, y);}
169169
public:
170170
CurveHeightConst(CurveRed& CR);
171171
void compute() {compute_phase1(); compute_phase2(); }

libsrc/eclib/interface.h

Lines changed: 6 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
// The macro NO_MPFP can optionally be set. It controls whether most
2525
// real and complex floating point functions are implemented using
2626
// doubles and complex doubles (if set) or using NTL bigfloats
27-
// (RR) and bigcomplexes (CC) (if not set, the default)
27+
// (RR) and bigcomplexes (if not set, the default)
2828

2929
#ifndef _ECLIB_INTERFACE_H_
3030
#define _ECLIB_INTERFACE_H_
@@ -162,75 +162,8 @@ inline int is_approx_zero(const RR& x)
162162
return abs(x.mantissa())<power2_ZZ(-n);
163163
}
164164
} // namespace NTL
165-
#ifdef _LIBCPP_VERSION
166-
namespace NTL {
167-
inline bool isinf(const RR& z) {
168-
return false;
169-
}
170-
inline bool isnan(const RR& z) {
171-
return false;
172-
}
173-
inline RR copysign(const RR& x, const RR& y) {
174-
if (sign(x) != sign(y)) {
175-
return -y;
176-
}
177-
return y;
178-
}
179-
inline bool signbit(const RR& x) {
180-
return sign(x) < 0;
181-
}
182-
inline RR fmax(const RR& x, const RR& y)
183-
{
184-
return x < y ? y : x;
185-
}
186-
} // namespace NTL
187-
#endif
188165

189-
#include <complex>
190-
typedef complex<RR> CC;
191-
typedef CC bigcomplex;
192-
193-
#ifdef _LIBCPP_VERSION
194-
template <> inline RR std::abs(const CC &z)
195-
{
196-
RR re = z.real();
197-
RR im = z.imag();
198-
return sqrt(re*re + im*im);
199-
}
200-
template <> inline CC std::exp(const CC &z)
201-
{
202-
RR im = z.imag();
203-
RR e = exp(z.real());
204-
return CC(e * cos(im), e * sin(im));
205-
}
206-
inline CC operator/(const CC &a, const CC &b)
207-
{
208-
RR are = a.real();
209-
RR aim = a.imag();
210-
RR bre = b.real();
211-
RR bim = b.imag();
212-
if (abs(bre) <= abs(bim)) {
213-
RR r = bre / bim;
214-
RR den = bim + r*bre;
215-
return CC((are*r + aim)/den, (aim*r - are)/den);
216-
} else {
217-
RR r = bim / bre;
218-
RR den = bre + r*bim;
219-
return CC((are + aim*r)/den, (aim - are*r)/den);
220-
}
221-
}
222-
inline CC operator /(const RR &a, const CC &b)
223-
{
224-
CC r(a);
225-
return r/b;
226-
}
227-
inline CC &operator /=(CC &a, const CC &b)
228-
{
229-
a = a/b;
230-
return a;
231-
}
232-
233-
#endif
166+
#include "bigcomplex.h"
234167

235168
// NB Internal precision is always bit-precision. We used to use
236169
// decimal precision in the user interface with a conversion factor of
@@ -271,10 +204,10 @@ inline int is_zero(bigfloat x) {return IsZero(x);}
271204
inline int is_zero(bigcomplex z) {return IsZero(z.real()) && IsZero(z.imag());}
272205
inline void Iasb(bigint& a, bigfloat x) {RoundToZZ(a,x);}
273206
inline void Iasb(long& a, bigfloat x) {ZZ n; RoundToZZ(n,x); a=I2long(n);}
274-
istream& operator>>(istream& is, CC& z);
275-
inline CC pow(const CC& a, int e) {return exp(to_RR(e)*log(a));}
276-
inline CC pow(const CC& a, long e) {return exp(to_RR(e)*log(a));}
277-
inline CC pow(const CC& a, const RR& e) {return exp(e*log(a));}
207+
istream& operator>>(istream& is, bigcomplex& z);
208+
inline bigcomplex pow(const bigcomplex& a, int e) {return (to_RR(e)*a.log()).exp();}
209+
inline bigcomplex pow(const bigcomplex& a, long e) {return (to_RR(e)*a.log()).exp();}
210+
inline bigcomplex pow(const bigcomplex& a, const RR& e) {return (e*a.log()).exp();}
278211

279212

280213
//////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)