
/*****************************************************************************\

MODULE: mat_ZZ

SUMMARY:

Defines the class matrix(ZZ).

\*****************************************************************************/


#include "matrix.h"
#include "vec_vec_ZZ.h"

matrix_decl(ZZ)

void add(matrix(ZZ)& X, const matrix(ZZ)& A, const matrix(ZZ)& B); 
// X = A + B

void sub(matrix(ZZ)& X, const matrix(ZZ)& A, const matrix(ZZ)& B); 
// X = A - B

void mul(matrix(ZZ)& X, const matrix(ZZ)& A, const matrix(ZZ)& B); 
// X = A * B

void mul(vector(ZZ)& x, const matrix(ZZ)& A, const vector(ZZ)& b); 
// x = A * b

void mul(vector(ZZ)& x, const vector(ZZ)& a, const matrix(ZZ)& B); 
// x = a * B

void mul(matrix(ZZ)& X, const matrix(ZZ)& A, const ZZ& b);
// X = A * b


void determinant(ZZ& d, const matrix(ZZ)& A, long deterministic=0);
// d = determinant(A)
// if !deterministic, a randomized strategy may be used that errs
//    with probability at most 2^{-80}.


void solve(ZZ& d, vector(ZZ)& x,
           const matrix(ZZ)& A, const vector(ZZ)& b,
           long deterministic=0)
// computes d = determinant(A) and solves x*A = b*d if d != 0;
// A must be a square matrix and have compatible dimensions with b.
// If !deterministic, the computation of d may use a randomized
// strategy that errs with probability 2^{-80}.


void inv(ZZ& d, matrix(ZZ)& X, const matrix(ZZ)& A, long deterministic=0);
// computes d = determinant(A) and solves X*A = I*d if d != 0;
// A must be a square matrix. 
// If !deterministic, the computation of d may use a randomized
// strategy that errs with probability 2^{-80}.


void ident(matrix(ZZ)& X, long n); 
// X = n x n identity matrix

long IsIdent(const matrix(ZZ)& A, long n);
// test if A is the n x n identity matrix

void diag(matrix(ZZ)& X, long n, const ZZ& d);
// X = n x n diagonal matrix with d on diagonal

long IsDiag(const matrix(ZZ)& A, long n, const ZZ& d);
// test if X is an  n x n diagonal matrix with d on diagonal


void transpose(matrix(ZZ)& X, const matrix(ZZ)& A);
// X = transpose of A



void operator<<(matrix(zz_p)& x, const matrix(ZZ)& a);
void operator<<(matrix(ZZ_p)& x, const matrix(ZZ)& a);
// conversion operators

long CRT(matrix(ZZ)& a, ZZ& prod, const matrix(zz_p)& A);
// Incremental Chinese Remaindering:
// If p is the current modulus with (p, prod) = 1;
// Computes b such that b = a mod prod and b = A mod p,
//    with coefficients in the interval (-p*prod/2, p*prod/2];
// Sets a = b, prod = p*prod, and returns 1 if a's value changed.


