Renamed root finding class and methods, now class methods
This commit is contained in:
		
							parent
							
								
									ae30889bbb
								
							
						
					
					
						commit
						ab453b347d
					
				@ -37,22 +37,23 @@ type
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  TIsolatingIntervals = specialize TList<TIsolatingInterval>;
 | 
					  TIsolatingIntervals = specialize TList<TIsolatingInterval>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  { TRootIsolation }
 | 
					  { TPolynomialRoots }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  TRootIsolation = class
 | 
					  TPolynomialRoots = class
 | 
				
			||||||
  private
 | 
					  private
 | 
				
			||||||
    function CalcSimpleRootBound(constref APolynomial: TBigIntPolynomial): TBigInt;
 | 
					    class function CalcUpperRootBound(constref APolynomial: TBigIntPolynomial): TBigInt;
 | 
				
			||||||
    function GetIsolatingInterval(const AC, AK, AH: Cardinal; constref ABound: TBigInt): TIsolatingInterval;
 | 
					    class function CreateIsolatingInterval(const AC, AK, AH: Cardinal; constref ABound: TBigInt): TIsolatingInterval;
 | 
				
			||||||
  public
 | 
					  public
 | 
				
			||||||
    function Bisect(constref APolynomial: TBigIntPolynomial): TIsolatingIntervals;
 | 
					    class function BisectIsolation(constref APolynomial: TBigIntPolynomial): TIsolatingIntervals;
 | 
				
			||||||
    function Bisect(constref APolynomial: TBigIntPolynomial; constref ABound: TBigInt): TIsolatingIntervals;
 | 
					    class function BisectIsolation(constref APolynomial: TBigIntPolynomial; constref ABound: TBigInt):
 | 
				
			||||||
 | 
					      TIsolatingIntervals;
 | 
				
			||||||
  end;
 | 
					  end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
implementation
 | 
					implementation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{ TRootIsolation }
 | 
					{ TPolynomialRoots }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function TRootIsolation.CalcSimpleRootBound(constref APolynomial: TBigIntPolynomial): TBigInt;
 | 
					class function TPolynomialRoots.CalcUpperRootBound(constref APolynomial: TBigIntPolynomial): TBigInt;
 | 
				
			||||||
var
 | 
					var
 | 
				
			||||||
  i, sign: Integer;
 | 
					  i, sign: Integer;
 | 
				
			||||||
  an, ai, max: TBigInt;
 | 
					  an, ai, max: TBigInt;
 | 
				
			||||||
@ -76,7 +77,8 @@ begin
 | 
				
			|||||||
  Result := TBigInt.One << (numeratorBit - denominatorBit);
 | 
					  Result := TBigInt.One << (numeratorBit - denominatorBit);
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function TRootIsolation.GetIsolatingInterval(const AC, AK, AH: Cardinal; constref ABound: TBigInt): TIsolatingInterval;
 | 
					class function TPolynomialRoots.CreateIsolatingInterval(const AC, AK, AH: Cardinal; constref ABound: TBigInt):
 | 
				
			||||||
 | 
					  TIsolatingInterval;
 | 
				
			||||||
begin
 | 
					begin
 | 
				
			||||||
  Result.C := AC;
 | 
					  Result.C := AC;
 | 
				
			||||||
  Result.K := AK;
 | 
					  Result.K := AK;
 | 
				
			||||||
@ -86,17 +88,18 @@ begin
 | 
				
			|||||||
  Result.B := ((AC + AH) * ABound) >> AK;
 | 
					  Result.B := ((AC + AH) * ABound) >> AK;
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function TRootIsolation.Bisect(constref APolynomial: TBigIntPolynomial): TIsolatingIntervals;
 | 
					class function TPolynomialRoots.BisectIsolation(constref APolynomial: TBigIntPolynomial): TIsolatingIntervals;
 | 
				
			||||||
var
 | 
					var
 | 
				
			||||||
  bound: TBigInt;
 | 
					  bound: TBigInt;
 | 
				
			||||||
begin
 | 
					begin
 | 
				
			||||||
  bound := CalcSimpleRootBound(APolynomial);
 | 
					  bound := CalcUpperRootBound(APolynomial);
 | 
				
			||||||
  Result := Bisect(APolynomial, bound);
 | 
					  Result := BisectIsolation(APolynomial, bound);
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// This is adapted from
 | 
					// This is adapted from
 | 
				
			||||||
// https://en.wikipedia.org/wiki/Real-root_isolation#Bisection_method
 | 
					// https://en.wikipedia.org/wiki/Real-root_isolation#Bisection_method
 | 
				
			||||||
function TRootIsolation.Bisect(constref APolynomial: TBigIntPolynomial; constref ABound: TBigInt): TIsolatingIntervals;
 | 
					class function TPolynomialRoots.BisectIsolation(constref APolynomial: TBigIntPolynomial; constref ABound: TBigInt):
 | 
				
			||||||
 | 
					  TIsolatingIntervals;
 | 
				
			||||||
type
 | 
					type
 | 
				
			||||||
  TWorkItem = record
 | 
					  TWorkItem = record
 | 
				
			||||||
    C, K: Cardinal;
 | 
					    C, K: Cardinal;
 | 
				
			||||||
@ -126,7 +129,7 @@ begin
 | 
				
			|||||||
      // Found an integer root at 0.
 | 
					      // Found an integer root at 0.
 | 
				
			||||||
      item.P := item.P.DivideByVariable;
 | 
					      item.P := item.P.DivideByVariable;
 | 
				
			||||||
      Dec(n);
 | 
					      Dec(n);
 | 
				
			||||||
      Result.Add(GetIsolatingInterval(item.C, item.K, 0, ABound));
 | 
					      Result.Add(CreateIsolatingInterval(item.C, item.K, 0, ABound));
 | 
				
			||||||
    end;
 | 
					    end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    varq := item.P.RevertOrderOfCoefficients.TranslateVariableByOne;
 | 
					    varq := item.P.RevertOrderOfCoefficients.TranslateVariableByOne;
 | 
				
			||||||
@ -134,7 +137,7 @@ begin
 | 
				
			|||||||
    if v = 1 then
 | 
					    if v = 1 then
 | 
				
			||||||
    begin
 | 
					    begin
 | 
				
			||||||
      // Found isolating interval.
 | 
					      // Found isolating interval.
 | 
				
			||||||
      Result.Add(GetIsolatingInterval(item.C, item.K, 1, ABound));
 | 
					      Result.Add(CreateIsolatingInterval(item.C, item.K, 1, ABound));
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
    else if v > 1 then
 | 
					    else if v > 1 then
 | 
				
			||||||
    begin
 | 
					    begin
 | 
				
			||||||
 | 
				
			|||||||
@ -32,10 +32,6 @@ type
 | 
				
			|||||||
  private
 | 
					  private
 | 
				
			||||||
    procedure AssertBisectResult(constref AIsolatingIntervals: TIsolatingIntervals; constref AExpectedRoots:
 | 
					    procedure AssertBisectResult(constref AIsolatingIntervals: TIsolatingIntervals; constref AExpectedRoots:
 | 
				
			||||||
      array of Cardinal);
 | 
					      array of Cardinal);
 | 
				
			||||||
  protected
 | 
					 | 
				
			||||||
    FRootIsolation: TRootIsolation;
 | 
					 | 
				
			||||||
    procedure SetUp; override;
 | 
					 | 
				
			||||||
    procedure TearDown; override;
 | 
					 | 
				
			||||||
  published
 | 
					  published
 | 
				
			||||||
    procedure TestBisectNoBound;
 | 
					    procedure TestBisectNoBound;
 | 
				
			||||||
    procedure TestBisectWithBound;
 | 
					    procedure TestBisectWithBound;
 | 
				
			||||||
@ -68,18 +64,6 @@ begin
 | 
				
			|||||||
  end;
 | 
					  end;
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
procedure TPolynomialRootsTestCase.SetUp;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  inherited SetUp;
 | 
					 | 
				
			||||||
  FRootIsolation := TRootIsolation.Create;
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
procedure TPolynomialRootsTestCase.TearDown;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  FRootIsolation.Free;
 | 
					 | 
				
			||||||
  inherited TearDown;
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
procedure TPolynomialRootsTestCase.TestBisectNoBound;
 | 
					procedure TPolynomialRootsTestCase.TestBisectNoBound;
 | 
				
			||||||
const
 | 
					const
 | 
				
			||||||
  expRoots: array of Cardinal = (34000, 23017, 5);
 | 
					  expRoots: array of Cardinal = (34000, 23017, 5);
 | 
				
			||||||
@ -90,7 +74,7 @@ begin
 | 
				
			|||||||
  // y = 3 * (x - 34000) * (x - 23017) * (x - 5) * (x^2 - 19) * (x + 112)
 | 
					  // y = 3 * (x - 34000) * (x - 23017) * (x - 5) * (x^2 - 19) * (x + 112)
 | 
				
			||||||
  //   = 3 * x^6 - 170730 * x^5 + 2329429920 * x^4 + 251300082690 * x^3 - 1270471872603 * x^2 + 4774763204640 * x - 24979889760000
 | 
					  //   = 3 * x^6 - 170730 * x^5 + 2329429920 * x^4 + 251300082690 * x^3 - 1270471872603 * x^2 + 4774763204640 * x - 24979889760000
 | 
				
			||||||
  a := TBigIntPolynomial.Create([-24979889760000, 4774763204640, -1270471872603, 251300082690, 2329429920, -170730, 3]);
 | 
					  a := TBigIntPolynomial.Create([-24979889760000, 4774763204640, -1270471872603, 251300082690, 2329429920, -170730, 3]);
 | 
				
			||||||
  r := FRootIsolation.Bisect(a);
 | 
					  r := TPolynomialRoots.BisectIsolation(a);
 | 
				
			||||||
  AssertBisectResult(r, expRoots);
 | 
					  AssertBisectResult(r, expRoots);
 | 
				
			||||||
  r.Free;
 | 
					  r.Free;
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
@ -105,7 +89,7 @@ begin
 | 
				
			|||||||
  // y = 3 * (x - 34000) * (x - 23017) * (x - 5) * (x^2 - 19) * (x + 112)
 | 
					  // y = 3 * (x - 34000) * (x - 23017) * (x - 5) * (x^2 - 19) * (x + 112)
 | 
				
			||||||
  //   = 3 * x^6 - 170730 * x^5 + 2329429920 * x^4 + 251300082690 * x^3 - 1270471872603 * x^2 + 4774763204640 * x - 24979889760000
 | 
					  //   = 3 * x^6 - 170730 * x^5 + 2329429920 * x^4 + 251300082690 * x^3 - 1270471872603 * x^2 + 4774763204640 * x - 24979889760000
 | 
				
			||||||
  a := TBigIntPolynomial.Create([-24979889760000, 4774763204640, -1270471872603, 251300082690, 2329429920, -170730, 3]);
 | 
					  a := TBigIntPolynomial.Create([-24979889760000, 4774763204640, -1270471872603, 251300082690, 2329429920, -170730, 3]);
 | 
				
			||||||
  r := FRootIsolation.Bisect(a, TBigInt.One << 15);
 | 
					  r := TPolynomialRoots.BisectIsolation(a, TBigInt.One << 15);
 | 
				
			||||||
  AssertBisectResult(r, expRoots);
 | 
					  AssertBisectResult(r, expRoots);
 | 
				
			||||||
  r.Free;
 | 
					  r.Free;
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user