File: quadratic.cc

package info (click to toggle)
eclib 2014-09-21-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 4,216 kB
  • ctags: 4,287
  • sloc: cpp: 45,827; makefile: 222; sh: 108
file content (101 lines) | stat: -rw-r--r-- 3,076 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// quadratic.cc: implementation of class for handling integer quadratics
//////////////////////////////////////////////////////////////////////////
//
// Copyright 1990-2012 John Cremona
// 
// This file is part of the eclib package.
// 
// eclib is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
// 
// eclib is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
// 
// You should have received a copy of the GNU General Public License
// along with eclib; if not, write to the Free Software Foundation,
// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
// 
//////////////////////////////////////////////////////////////////////////
 
#include <eclib/marith.h>
#include <eclib/unimod.h>
#include <eclib/quadratic.h>

quadratic::~quadratic() {delete [] coeffs;}

void quadratic::init()
{
  coeffs = new bigint[3];
}

bigint quadratic::coeff(int i) 
    {if((i>=0)&&(i<=2)) return coeffs[i]; else {bigint ans; return ans;}}

bigint quadratic::operator[](int i) const
    {if((i>=0)&&(i<=2)) return coeffs[i]; else {bigint ans; return ans;}}

void quadratic::transform(const unimod& m)
{
  bigint newq0 = eval(m.m11, m.m21);
  bigint newq2 = eval(m.m12, m.m22);
  coeffs[1] = 2 * (coeffs[0]*m.m11*m.m12 + coeffs[2]*m.m21*m.m22) 
               + coeffs[1] * (m.m11*m.m22+m.m12*m.m21);
  coeffs[0] = newq0;
  coeffs[2] = newq2;
}

void quadratic::x_shift(const bigint& a, unimod& m)
{
  const bigint& aq0=a*coeffs[0];
  coeffs[2]+= (aq0+coeffs[1])*a;
  coeffs[1]+= 2*aq0;
  m.x_shift(a);
}

void quadratic::y_shift(const bigint& a, unimod& m)
{
  const bigint& aq2=a*coeffs[2];
  coeffs[0]+= (aq2+coeffs[1])*a;
  coeffs[1]+= 2*aq2;
  m.y_shift(a);
}

void quadratic::invert(unimod& m)
{
  swap(coeffs[0],coeffs[2]);  coeffs[1]=-coeffs[1];
  m.invert();
}

void quadratic::reduce(unimod& m)
{
  //  cout<<"Reducing quadratic  "<<(*this)<<endl;
  if(coeffs[0]<0) 
    {
      coeffs[0]=-coeffs[0]; 
      coeffs[2]=-coeffs[2]; 
      coeffs[1]=-coeffs[1];
    }
  bigint a = roundover(-coeffs[1],2*coeffs[0]);
  x_shift(a,m);
  int reduced = (coeffs[0]<=coeffs[2]);
  while(!reduced)
    {
      invert(m);
      a = roundover(-coeffs[1],2*coeffs[0]);
      x_shift(a,m);
      reduced = (coeffs[0]<=coeffs[2]);
    }
  //  cout<<"Reduced quadratic = "<<(*this)<<endl;
  //  cout<<"  via matrix "<<m<<endl;
  //  cout<<"  of determinant "<<m.det()<<endl;
}

bigint resultant(const quadratic& q1, const quadratic& q2)
{return sqr(q2.coeffs[0]*q1.coeffs[2]) + sqr(q1.coeffs[0]*q2.coeffs[2]) +
   q2.coeffs[2]*q2.coeffs[0]*sqr(q1.coeffs[1]) - q2.coeffs[1]*q1.coeffs[1]*(q2.coeffs[0]*q1.coeffs[2] + q1.coeffs[0]*q2.coeffs[2]) +
   (sqr(q2.coeffs[1])-2*q2.coeffs[0]*q2.coeffs[2])*q1.coeffs[0]*q1.coeffs[2];
}