File: quadratic.cc

package info (click to toggle)
eclib 20250122-2
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 5,916 kB
  • sloc: cpp: 45,414; makefile: 272; sh: 127
file content (89 lines) | stat: -rw-r--r-- 2,654 bytes parent folder | download | duplicates (2)
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
// quadratic.cc: implementation of class for handling integer quadratics
//////////////////////////////////////////////////////////////////////////
//
// Copyright 1990-2023 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/quadratic.h>

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)
{
  const bigint&
    a1=q1.coeffs[0], b1=q1.coeffs[1], c1=q1.coeffs[2],
    a2=q2.coeffs[0], b2=q2.coeffs[1], c2=q2.coeffs[2];
  return
    sqr(c2*a1) -a1*c2*b2*b1 + (-2*c2*a2 + sqr(b2))*c1*a1 + c2*a2*sqr(b1) - b2*a2*c1*b1 + sqr(a2*c1);
}