=encoding utf8

=head1 NAME

Sidef::Types::Number::Gauss - Gaussian integer arithmetic in Sidef

=head1 DESCRIPTION

This class implements Gaussian integers, which are complex numbers of the form a + bi where both a and b are integers. Gaussian integers form a unique factorization domain and are useful in number theory, particularly in studying prime factorizations and solving Diophantine equations.

A Gaussian integer can be created using the C<Gauss(a, b)> constructor, which represents the complex number a + bi.

=head1 SYNOPSIS

    var a = Gauss(17, 19)      #=> 17+19i
    var b = Gauss(43, 97)      #=> 43+97i

    say a+b                    #=> 60+116i
    say a-b                    #=> -26-78i
    say a*b                    #=> -1112+2466i
    say a/b                    #=> 99/433-32i/433

    say a.norm                 #=> 650 (17² + 19²)
    say a.conj                 #=> 17-19i
    
    var g = Gauss(120, 84)
    say g.factor               #=> [Gauss(-1,1), Gauss(1,1), Gauss(1,1), Gauss(1,1), Gauss(2,1), Gauss(3,0)]
    
    var p = Gauss(3, 2)
    say p.is_prime             #=> true

=head1 INHERITS

Inherits methods from:

       * Sidef::Types::Number::Number

=head1 METHODS

=head2 !=

    a != b

Returns true if two Gaussian integers are not equal (their real or imaginary parts differ).

Aliases: I<ne>

=cut

=head2 %

    a % b

Returns the remainder when dividing Gaussian integer C<a> by C<b>, using the Euclidean division algorithm for Gaussian integers.

Aliases: I<mod>

=cut

=head2 &

    a & b

Performs bitwise AND operation on the real and imaginary parts separately.

Aliases: I<and>

=cut

=head2 *

    a * b

Returns the product of two Gaussian integers. If a = (p+qi) and b = (r+si), then a*b = (pr-qs) + (ps+qr)i.

Aliases: I<mul>

=cut

=head2 **

    a ** b

Returns the Gaussian integer C<a> raised to the power C<b>.

Aliases: I<pow>

=cut

=head2 +

    a + b

Returns the sum of two Gaussian integers by adding their real and imaginary parts separately.

Aliases: I<add>

=cut

=head2 ++

    a++

Increments the Gaussian integer by 1 (adds 1 to the real part).

Aliases: I<inc>

=cut

=head2 -

    a - b

Returns the difference of two Gaussian integers by subtracting their real and imaginary parts separately.

Aliases: I<sub>

=cut

=head2 --

    a--

Decrements the Gaussian integer by 1 (subtracts 1 from the real part).

Aliases: I<dec>

=cut

=head2 /

    a / b

Returns the quotient when dividing Gaussian integer C<a> by C<b>. The result may have rational real and imaginary parts.

Aliases: I<÷>, I<div>

=cut

=head2 <

    a < b

Compares two Gaussian integers by their norms. Returns true if the norm of C<a> is less than the norm of C<b>.

Aliases: I<lt>

=cut

=head2 <<

    a << b

Performs left bitwise shift on both real and imaginary parts by C<b> positions.

Aliases: I<lsft>, I<shift_left>

=cut

=head2 <=>

    a <=> b

Compares two Gaussian integers by their norms. Returns -1 if norm(a) < norm(b), 0 if equal, and 1 if norm(a) > norm(b).

Aliases: I<cmp>

=cut

=head2 ==

    a == b

Returns true if two Gaussian integers are equal (both real and imaginary parts match).

Aliases: I<eq>

=cut

=head2 >

    a > b

Compares two Gaussian integers by their norms. Returns true if the norm of C<a> is greater than the norm of C<b>.

Aliases: I<gt>

=cut

=head2 >>

    a >> b

Performs right bitwise shift on both real and imaginary parts by C<b> positions.

Aliases: I<rsft>, I<shift_right>

=cut

=head2 ^

    a ^ b

Performs bitwise XOR operation on the real and imaginary parts separately.

Aliases: I<xor>

=cut

=head2 |

    a | b

Performs bitwise OR operation on the real and imaginary parts separately.

Aliases: I<or>

=cut

=head2 ≤

    a ≤ b

Returns true if the norm of C<a> is less than or equal to the norm of C<b>.

Aliases: I<E<lt>=>, I<le>

=cut

=head2 ≥

    a ≥ b

Returns true if the norm of C<a> is greater than or equal to the norm of C<b>.

Aliases: I<E<gt>=>, I<ge>

=cut

=head2 a

    self.a

Returns the real part of the Gaussian integer.

Aliases: I<re>, I<real>

=cut

=head2 abs

    x.abs

Returns the absolute value (magnitude) of the Gaussian integer, which is sqrt(a² + b²) where the Gaussian integer is a+bi.

=cut

=head2 b

    self.b

Returns the imaginary part of the Gaussian integer.

Aliases: I<im>, I<imag>

=cut

=head2 ceil

    x.ceil

Returns a new Gaussian integer with the ceiling function applied to both the real and imaginary parts.

=cut

=head2 conj

    x.conj

Returns the complex conjugate of the Gaussian integer. If x = a+bi, returns a-bi.

=cut

=head2 divisors

    n.divisors

Returns an array of all Gaussian integer divisors of C<n>.

=cut

=head2 dump

    x.dump

Returns a string representation of the Gaussian integer suitable for debugging, showing its internal structure.

=cut

=head2 eval

    x.eval(v)

Evaluates the Gaussian integer in some context, replacing symbolic variables with the value C<v>.

=cut

=head2 factor

    z.factor

Returns an array of Gaussian prime factors of C<z>. Each factor is itself a Gaussian integer.

Aliases: I<factors>

=cut

=head2 factor_exp

    z.factor_exp

Returns an array of pairs [prime, exponent] representing the prime factorization of the Gaussian integer C<z>.

=cut

=head2 float

    x.float

Converts the Gaussian integer to a complex number with floating-point real and imaginary parts.

=cut

=head2 floor

    x.floor

Returns a new Gaussian integer with the floor function applied to both the real and imaginary parts.

=cut

=head2 gcd

    n.gcd(k)

Returns the greatest common divisor of two Gaussian integers using the Euclidean algorithm.

=cut

=head2 gcd_norm

    n.gcd_norm(k)

Returns the norm (squared magnitude) of the greatest common divisor of two Gaussian integers.

=cut

=head2 i

    x.i

Returns the imaginary unit multiplied by the Gaussian integer, effectively rotating it 90 degrees in the complex plane.

=cut

=head2 iabs

    x.iabs

Returns the squared absolute value (norm) of the Gaussian integer, which is a² + b² for a+bi.

=cut

=head2 inv

    x.inv

Returns the multiplicative inverse of the Gaussian integer, equal to conj(x)/norm(x).

=cut

=head2 invmod

    x.invmod(m)

Returns the modular multiplicative inverse of C<x> modulo C<m> in the Gaussian integers, if it exists.

=cut

=head2 is_coprime

    n.is_coprime(k)

Returns true if Gaussian integers C<n> and C<k> are coprime (their GCD is a unit: ±1 or ±i).

=cut

=head2 is_div

    x.is_div(y)

Returns true if Gaussian integer C<x> is divisible by C<y> (i.e., x/y is also a Gaussian integer).

Aliases: I<is_divisible>

=cut

=head2 is_imag

    x.is_imag

Returns true if the Gaussian integer is purely imaginary (real part is zero).

=cut

=head2 is_mone

    x.is_mone

Returns true if the Gaussian integer equals -1.

=cut

=head2 is_one

    x.is_one

Returns true if the Gaussian integer equals 1.

=cut

=head2 is_prime

    x.is_prime

Returns true if the Gaussian integer is a Gaussian prime. A Gaussian integer is prime if it cannot be factored into non-unit Gaussian integers.

=cut

=head2 is_real

    x.is_real

Returns true if the Gaussian integer is purely real (imaginary part is zero).

=cut

=head2 is_zero

    x.is_zero

Returns true if the Gaussian integer equals 0+0i.

=cut

=head2 lift

    x.lift

Converts the Gaussian integer to a standard complex number representation.

=cut

=head2 neg

    x.neg

Returns the negation of the Gaussian integer (multiplies by -1).

=cut

=head2 new

    self.new(a, b)
    Gauss(a, b)

Creates a new Gaussian integer with real part C<a> and imaginary part C<b>.

Aliases: I<call>

=cut

=head2 norm

    x.norm

Returns the norm of the Gaussian integer, which is a² + b² for x = a+bi. This is the squared magnitude.

=cut

=head2 parts

    self.parts

Returns an array containing the real and imaginary parts: [a, b] for a+bi.

=cut

=head2 powmod

    x.powmod(n, m)

Returns C<x> raised to the power C<n> modulo C<m> in the Gaussian integers.

=cut

=head2 pretty

    x.pretty

Returns a human-readable string representation of the Gaussian integer in the form "a+bi" or "a-bi".

Aliases: I<stringify>

=cut

=head2 reals

    self.reals

Returns an array containing both the real and imaginary parts as real numbers.

=cut

=head2 round

    x.round(r)

Rounds both the real and imaginary parts to C<r> decimal places, returning a new Gaussian integer.

=cut

=head2 sgn

    x.sgn

Returns the sign of the Gaussian integer as a unit Gaussian integer (one of 1, -1, i, -i) with the same argument.

=cut

=head2 sqr

    x.sqr

Returns the square of the Gaussian integer (x * x).

=cut

=head2 to_c

    self.to_c

Converts the Gaussian integer to a complex number.

Aliases: I<to_n>

=cut

=head2 to_s

    x.to_s

Converts the Gaussian integer to a string representation.

=cut

=head1 MATHEMATICAL BACKGROUND

Gaussian integers form a unique factorization domain, meaning every Gaussian integer can be uniquely factored into Gaussian primes (up to units and order). The units in the Gaussian integers are {1, -1, i, -i}.

A Gaussian integer a+bi is a Gaussian prime if and only if:

=over 4

=item * a = 0 and |b| is a prime number of the form 4k+3, or

=item * b = 0 and |a| is a prime number of the form 4k+3, or

=item * Both a and b are nonzero and a²+b² is a rational prime

=back

The norm function N(a+bi) = a²+b² is multiplicative: N(zw) = N(z)N(w).

=head1 SEE ALSO

=over 4

=item * L<Sidef::Types::Number::Number>

=item * L<Sidef::Types::Number::Complex>

=back

=head1 AUTHOR

Daniel "Trizen" Șuteu

=head1 LICENSE

This library is free software; you can redistribute it and/or modify it under the same terms as Sidef itself.

=cut
