/*********************************/
/* Application Test Routine      */
/*                               */
/* Version 1.9 math_matrix       */
/* author: Patrick Theobald (PT) */
/*********************************/

#include <fstream.h>
#define LIDIA_POINTER_ACCESS
#if defined(HAVE_MAC_DIRS) || defined(__MWERKS__)
#include <LiDIA:bigint.h>
#include <LiDIA:bigint_matrix.h>
#else
#include <LiDIA/bigint.h>
#include <LiDIA/bigint_matrix.h>
#endif

main()
{
  ifstream in(IN_NAME);
  ofstream dz(OUT_NAME);
  
  int i, j;

  /* pointer */
  bigint *pointer_1 = NULL;
  bigint *pointer_2 = NULL;
  bigint *pointer_3 = new bigint[4];
  bigint *pointer_4 = new bigint[6];
  bigint *pointer_5 = new bigint[4];
  bigint *pointer_6 = new bigint[6];

  /* vectors */
  math_vector < bigint > v1, v2;
  math_vector < bigint > v3(4, 4);
  math_vector < bigint > v4(6, 6);
  
  /* scalar */
  bigint scalar_1, scalar_2, scalar_3;
  in >> scalar_2 >> scalar_3;
  //cout << scalar_2 << scalar_3 << flush;
  lidia_size_t c,r;

  /* array */
  bigint **wertearray = new bigint *[2];
  for (i = 0; i < 2; i++)
    {
      wertearray[i] = new bigint[3];
      for (j = 0; j < 3; j++)
	{
	  in >> wertearray[i][j];
	  //cout << wertearray[i][j] << flush;
	}
    }
  
  cout << "**********************************************************" << endl;
  cout << "***             Test for class bigint_matrix           ***" << endl;
  cout << "***                     Version 2.0                    ***" << endl;
  cout << "**********************************************************" << endl;
  cout.flush();

  cout << "\ntesting constructors" << flush;
  dz << "testing constructor" << endl << flush;
  bigint_matrix  A(3, 1);
  bigint_matrix  B(2, 3);
  bigint_matrix  C(2, 3, (const bigint **)wertearray);
  bigint_matrix  D(C);
  bigint_matrix  E = C;
  bigint_matrix  F = C;
  dz << A << B << C << D << E << F << flush;
  cout << ".............................completed\n" << flush;

  A.read_from_stream(in);
  B.read_from_stream(in);
  C.read_from_stream(in);
  
  cout << "testing set_print_mode" << flush;
  dz << "testing set_print_mode\n" << flush;
  dz << " set A BEAUTY_MODE\n" << flush;
  A.set_print_mode(BEAUTY_MODE);
  dz << " set B LIDIA_MODE\n" << flush;
  B.set_print_mode(LIDIA_MODE);
  dz << " set C GP_MODE\n" << flush;
  C.set_print_mode(GP_MODE);
  dz << " set D MAPLE_MODE\n" << flush;
  D.set_print_mode(MAPLE_MODE);
  dz << " set E MATHEMATICA_MODE\n" << flush;
  E.set_print_mode(MATHEMATICA_MODE);
  dz << " set E KASH_MODE\n" << flush;
  E.set_print_mode(KASH_MODE);
  cout << "...........................completed\n" << flush;
  
  cout << "testing get_print_mode" << flush;
  dz << "testing get_print_mode\n" << flush;
  dz << A.get_print_mode() << endl << flush;
  dz << B.get_print_mode() << endl << flush;
  dz << C.get_print_mode() << endl << flush;
  dz << D.get_print_mode() << endl << flush;
  dz << E.get_print_mode() << endl << flush; 
  dz << F.get_print_mode() << endl << flush;
  cout << "...........................completed\n" << flush;
  
  cout << "testing write_to_stream" << flush;
  dz << "testing write_to_stream\n" << flush;
  ofstream out1("LIDIA");
  D.write_to_stream(out1);
  out1.close();
  cout << "..........................completed\n" << flush; 
  
  cout << "testing write_to_gp" << flush;
  dz << "testing write_to_gp\n" << flush;
  ofstream out2("GP");
  D.write_to_gp(out2);
  out2.close();
  cout << "..............................completed\n" << flush; 
  
  cout << "testing write_to_maple" << flush;
  dz << "testing write_to_maple\n" << flush;
  ofstream out3("MAPLE");
  D.write_to_maple(out3);
  out3.close();
  cout << "...........................completed\n" << flush; 

  cout << "testing write_to_mathematica" << flush;
  dz << "testing write_to_mathematica\n" << flush;
  ofstream out4("MATHEMATICA");
  D.write_to_mathematica(out4);
  out4.close(); 
  cout << ".....................completed\n" << flush; 

  cout << "testing write_to_kash" << flush;
  dz << "testing write_to_kash\n" << flush;
  ofstream out5("KASH");
  D.write_to_kash(out5);
  out5.close(); 
  cout << "............................completed\n" << flush; 
  
  A.set_print_mode(BEAUTY_MODE);
  B.set_print_mode(BEAUTY_MODE);
  C.set_print_mode(BEAUTY_MODE);
  D.set_print_mode(BEAUTY_MODE);
  E.set_print_mode(BEAUTY_MODE);
  F.set_print_mode(BEAUTY_MODE);
  
  cout << "testing read_from_stream" << flush;
  dz << "testing read_from_stream\n" << flush;
  ifstream in1("LIDIA");
  D.read_from_stream(in1);
  dz << D << flush;
  in1.close();
  cout << ".........................completed\n" << flush; 

  cout << "testing read_from_gp" << flush;
  dz << "testing read_from_gp\n" << flush;
  ifstream in2("GP");
  D.read_from_gp(in2);
  dz << D << flush;	
  in2.close();
  cout << ".............................completed\n" << flush; 

  cout << "testing read_from_maple" << flush;
  dz << "testing read_from_maple\n" << flush;
  ifstream in3("MAPLE");
  D.read_from_maple(in3);
  dz << D << flush;
  in3.close();
  cout << "..........................completed\n" << flush; 

  cout << "testing read_from_mathematica" << flush;
  dz << "testing read_from_mathematica\n" << flush;
  ifstream in4("MATHEMATICA");
  D.read_from_mathematica(in4);
  dz << D << flush;
  in4.close();
  cout << "....................completed\n" << flush; 

  cout << "testing read_from_kash" << flush;
  dz << "testing read_from_kash\n" << flush;
  ifstream in5("KASH");
  D.read_from_kash(in5);
  in5.close();
 cout << "...........................completed\n" << flush; 

  cout << "testing member" << flush;
  dz << "testing member" << endl << flush;
  scalar_1 = A.member(2, 1);
  dz << scalar_1 << endl;
  scalar_1 = A(2,1);
  dz << scalar_1 << endl << flush;
  cout << "...................................completed\n" << flush;

  cout << "testing column" << flush;
  dz << "testing column" << endl << flush;
  v1 = A(0);
  dz << v1 << endl << flush;
  dz << "\n" << flush;
  pointer_1 = A.column(1);
  for (i = 0; i < 4; i++)
    dz << pointer_1[i] << " " << flush;
  dz << "\n" << flush; 
  A.column(pointer_1, 2);
  for (i = 0; i < 4; i++)
    dz << pointer_1[i] << " " << flush;
  dz << "\n" << flush; 
  A.column_vector(v1, 2);
  dz << v1 << endl << flush;
  cout << "...................................completed\n" << flush;

  cout << "testing row" << flush;
  dz << "testing row" << endl << flush;
  v2 = A[0];
  dz << v2 << endl << flush;
  dz << "\n" << flush;
  pointer_2 = A.row(1);
  for (i = 0; i < 6; i++)
    dz << pointer_2[i] << " " << flush;
  dz << "\n" << flush;
  A.row(pointer_2, 2);
  for (i = 0; i < 6; i++)
    dz << pointer_2[i] << " " << flush;
  dz << "\n" << flush; 
  A.row_vector(v2, 2);
  dz << v2 << endl << flush;
  cout << "......................................completed\n" << flush;
  
  cout << "testing sto" << flush;
  E = A;
  dz << "testing sto" << endl << flush;
  E.sto(2, 0, 23);
  dz << E << flush;
  cout << "......................................completed\n" << flush;
  
  cout << "testing sto_column" << flush;
  dz << "testing sto_column" << endl << flush;
  E = A;
  E.sto_column(pointer_1, 3, 0);
  dz << E << flush;
  E.sto_column_vector(v1, 3, 1);
  dz << E << flush;
  cout << "...............................completed\n" << flush;

  cout << "testing sto_row" << flush;
  dz << "testing sto_row" << endl << flush;
  E = A;
  E.sto_row(pointer_2, 4, 0);
  dz << E << flush;
  E.sto_row_vector(v2, 4, 1);
  dz << E << flush;
  cout << "..................................completed\n" << flush;

  cout << "testing get_data" << flush;
  dz << "testing get_data" << endl << flush;
  r = E.get_no_of_rows();
  c = E.get_no_of_columns();
  bigint **value = E.get_data();
  for (i = 0; i < r; i++)
    for (j = 0; j < c; j++)
      dz << value[i][j] << " ";
  dz << endl << flush;
  for (i = 0; i < r; i++)
    delete[] value[i];
  delete[] value;
  cout << ".................................completed\n" << flush;

  cout << "testing swap" << flush;
  dz << "testing swap" << endl << flush;
  dz << E << A << flush;
  swap(E, A);
  dz << E << A << flush;
  swap(E, A);
  cout << ".....................................completed\n" << flush;

  cout << "testing swap_columns" << flush;
  dz << "testing swap_columns" << endl << flush;
  E = A;
  E.swap_columns(0, 5);
  dz << E << flush;
  cout << ".............................completed\n" << flush;
  
  cout << "testing swap_rows" << flush;
  dz << "testing swap_rows" << endl << flush;
  E = A;
  E.swap_rows(3, 0);
  dz << E << flush;
  cout << "................................completed\n" << flush;

  cout << "testing split_t" << flush;
  dz << "testing split_t" << endl << flush;
  bigint_matrix  Part1(2, 4), Part2(3, 2), Part3(2, 4), Part4(1, 2);
  A.split_t(Part1, Part2, Part3, Part4);
  dz << Part1 << Part2 << Part3 << Part4 << flush;
  cout << "...................................completed\n" << flush;

  cout << "testing split_h" << flush;
  dz << "testing split_h" << endl << flush;
  bigint_matrix  Part5(4, 4), Part6(4, 2);
  bigint_matrix  PartA(4, 5), PartB(4, 5), PartC(4, 5), PartD(4, 5);
  A.split_h(Part5, Part6);
  dz << Part5 << Part6 << flush;
  
  A.split_h(pointer_1, PartA);
  dz << PartA;
  for (i = 0; i< 4; i++)
    dz << pointer_1[i] << " ";
  dz << endl << flush;
  A.split_h(v1, PartB);
  dz << PartB << v1 << endl << flush;

  A.split_h(PartC, pointer_3);
  dz << PartC;
  for (i = 0; i< 4; i++)
    dz << pointer_3[i] << " ";
  dz << endl << flush;
  A.split_h(PartD, v3);
  dz << PartD << v3 << endl << flush;
  cout << ".................................completed\n" << flush;

  cout << "testing split_v" << flush;
  dz << "testing split_v" << endl << flush;
  bigint_matrix  Part7(1, 6), Part8(3, 6);
  bigint_matrix  PartE(3, 6), PartF(3, 6), PartG(3, 6), PartH(3, 6);
  A.split_v(Part7, Part8);
  dz << Part7 << Part8 << flush;

  A.split_v(pointer_2, PartE);
  dz << PartE;
  for (i = 0; i< 6; i++)
    dz << pointer_2[i] << " ";
  dz << endl << flush;
  A.split_v(v2, PartF);
  dz << PartF << v2 << endl << flush;

  A.split_v(PartG, pointer_4);
  dz << PartG;
  for (i = 0; i< 6; i++)
    dz << pointer_4[i] << " ";
  dz << endl << flush;
  A.split_v(PartH, v4);
  dz << PartH << v4 << endl << flush;
  cout << ".................................completed\n" << flush;

  cout << "testing compose_t" << flush;
  dz << "testing compose_t\n" << flush;
  {
    bigint_matrix  TMP(4, 6);
    TMP.compose_t(Part1, Part2, Part3, Part4);
    dz << TMP << flush;
  }
  cout << "..................................completed\n" << flush;

  cout << "testing compose_h" << flush;
  dz << "testing compose_h" << endl << flush;
  {
    bigint_matrix  TMP(4, 6);
    TMP.compose_h(Part5, Part6);
    dz << TMP << flush;

    TMP.compose_h(pointer_1, PartA);
    dz << TMP << flush;

    TMP.compose_h(v1, PartB);
    dz << TMP << flush;

    TMP.compose_h(PartC, pointer_3);
    dz << TMP << flush;

    TMP.compose_h(PartD, v3);
    dz << TMP << flush;
  }
  cout << "................................completed\n" << flush;

  cout << "testing compose_v" << flush;
  dz << "testing compose_v" << endl << flush;
  {
    bigint_matrix TMP(4, 6);
    TMP.compose_v(Part7, Part8);
    dz << TMP << flush;

    TMP.compose_v(pointer_2, PartE);
    dz << TMP << flush;

    TMP.compose_v(v2, PartF);
    dz << TMP << flush;

    TMP.compose_v(PartG, pointer_4);
    dz << TMP << flush;

    TMP.compose_v(PartH, v4);
    dz << TMP << flush;
  }
  cout << "................................completed\n" << flush;

  cout << "testing get_no_of_columns" << flush;
  dz << "testing get_no_of_columns" << endl << flush;
  scalar_1 = A.get_no_of_columns();
  dz << scalar_1 << endl << flush;
  cout << "........................completed\n" << flush;

  cout << "testing get_no_of_rows" << flush;
  dz << "testing get_no_of_rows" << endl << flush;
  scalar_1 = A.get_no_of_rows();
  dz << scalar_1 << endl << flush;
  cout << "...........................completed\n" << flush;

  cout << "testing set_no_of_columns" << flush;
  dz << "set_no_of_columns" << endl << flush;
  E = A;
  E.set_no_of_columns(3);
  dz << E << flush;
  cout << "........................completed\n" << flush; 

  cout << "testing set_no_of_rows" << flush;
  dz << "set_no_of_rows" << endl << flush;
  E.set_no_of_rows(3);
  dz << E << flush;
  cout << "...........................completed\n" << flush;
  
  cout << "testing assign" << flush;
  dz << "testing assign" << endl << flush;
  E = A;
  dz << E << flush;
  E.assign(A);
  dz << E << flush;
  assign(E, A);
  dz << E << flush;
  cout << "...................................completed\n" << flush;

  cout << "testing trans" << flush;
  dz << "testing trans" << endl << flush;
  E = trans(A);
  dz << E << flush;
  E = E.trans();
  dz << E << flush;
  E.trans(E);
  dz << E << flush;
  trans(E, E);
  dz << E << flush;
  cout << "....................................completed\n" << flush; 

  cout << "testing diag" << flush;
  dz << "diag" << endl << flush;
  E.diag(scalar_1, scalar_2);
  dz << E << flush;
  diag(E, scalar_2, scalar_3);
  dz << E << flush;
  cout << ".....................................completed\n" << flush; 

/***************************** END   OF PART: BASE_MATIRX ****************/
/***************************** BEGIN Of PART: MATH_MATRIX ****************/
  
  dz << A << B << C << D << E << flush;
  dz << v1 << v2 << v3 << v4 << endl << flush;

  cout << "testing addition" << flush;
  dz << "testing addition" << endl << flush;
  A += B;
  dz << A << flush;
  add(A, A, B);
  dz << A << flush;
  F = A + B;
  dz << F << flush;
  add(F, A, B);
  dz << F << flush;
  cout << ".................................completed\n" << flush;

  cout << "testing subtraction" << flush;
  dz << "testing subtraction" << endl << flush;
  A -= B;
  dz << A << flush;
  subtract(A, A, B);
  dz << A << flush;
  F = A - B;
  dz << F << flush;
  subtract(F, A, B);
  dz << F << flush;
  cout << "..............................completed\n" << flush;

  cout << "testing negate" << flush;
  dz << "testing negate" << endl << flush;
  F = -A;
  dz << F << flush;
  negate(F, A);
  dz << F << flush;
  cout << "...................................completed\n" << flush;

  cout << "testing multiplication" << flush;
  dz << "testing multiplication" << endl << flush;
  E = A, F = A;
  E *= C;
  dz << E << flush;
  E = A * C;
  dz << E << flush;
  multiply(F, A, C);
  dz << F << flush;
  cout << "...........................completed\n" << flush;

  cout << "testing addition with scalar" << flush;
  dz << "testing addition with scalar" << endl << flush;
  A += scalar_2;
  dz << A << flush;
  F = A + scalar_2;
  dz << F << flush;
  add(F, A, scalar_2);
  dz << F << flush;
  cout << ".....................completed\n" << flush;

  cout << "testing subtraction with scalar" << flush;
  dz << "testing subtraction with scalar" << endl << flush;
  A -= scalar_2;
  dz << A << flush;
  F = A - scalar_2;
  dz << F << flush;
  subtract(F, A, scalar_2);
  dz << F << flush;
  cout << "..................completed\n" << flush;

  cout << "testing multiplication with scalar" << flush;
  dz << "testing multiplication with scalar" << endl << flush;
  F = A;
  F *= scalar_3;
  dz << F << flush;
  F = A * scalar_3;
  dz << F << flush;
  multiply(F, A, scalar_3);
  dz << F << flush;
  cout << "...............completed\n" << flush;

  cout << "testing multiplication with array" << flush;
  dz << "testing multiplication with array" << endl << flush;
  pointer_3 = A * pointer_2;
  for (i = 0; i < 4; i++)
    dz << pointer_3[i] << " ";
  dz << endl << flush;
  multiply(pointer_5, A, pointer_2);
  for (i = 0; i < 4; i++)
    dz << pointer_5[i] << " ";
  dz << endl << flush;
  
  pointer_4 = pointer_1 * A;
  for (i = 0; i < 6; i++)
    dz << pointer_4[i] << " ";
  dz << endl << flush;
  multiply(pointer_6, pointer_1, A);
  for (i = 0; i < 6; i++)
    dz << pointer_6[i] << " ";
  dz << endl << flush;
  cout << "................completed\n" << flush; 
  
  cout << "testing multiplication with vector" << flush;
  dz << "testing multiplication with vector" << endl << flush;
  v3 = A * v2;
  dz << v3 << endl << flush;
  multiply(v3, A, v2);
  dz << v3 << endl << flush;
  
  v4 = v1 * A;
  dz << v4 << endl << flush;
  multiply(v4, v1, A);
  dz << v4 << endl << flush;
  cout << "...............completed\n" << flush; 

  cout << "testing trace" << flush;
  dz << "testing trace" << endl << flush;
  F = A * trans(A);
  scalar_1 = F.trace(); 
  dz << scalar_1 << endl << flush;
  F.trace(scalar_1);
  dz << scalar_1 << endl << flush;
  scalar_1 = trace(F); 
  dz << scalar_1 << endl << flush;
  cout << "....................................completed\n" << flush; 

  /***************************** END   OF PART: MATH_MATIRX ****************/
  /***************************** BEGIN Of PART: BIGINT_MATRIX **************/ 

  cout << "testing remainder" << flush;
  dz << "testing remainder" << endl << flush;
  F = A;
  F %= 13;
  dz << F << flush;
  F = A % 13;
  dz << F << flush;
  remainder(F, A, (bigint)13);
  dz << F << flush;
  cout << "................................completed\n" << flush;
  
  cout << "testing equal / unequal" << flush;
  bigint_matrix G = F;
  dz << "testing equal/unequal" << endl << flush;
  dz << (F == G) << endl << flush;
  dz << F.equal(G) << endl << flush;
  dz << equal(F, G) << endl << flush;
  dz << (F != G) << endl << flush;
  dz << F.unequal(G) << endl << flush;
  dz << unequal(F, G) << endl << flush;
  cout << "..........................completed\n" << flush;

  cout << "testing is_column_zero" << flush;  
  D.diag((bigint) 0, (bigint) 0);
  dz << "testing is_column_zero" << endl << flush;
  dz << D.is_column_zero(0) << endl << flush;
  dz << is_column_zero(F, 0) << endl << flush;
  cout << "...........................completed\n" << flush;

  cout << "testing is_row_zero" << flush;
  dz << "testing is_row_zero" << endl << flush;
  dz << D.is_row_zero(0) << "\n" << flush;
  dz << is_row_zero(F, 0) << "\n" << flush;
  cout << "..............................completed\n" << flush;

  cout << "testing is_matrix_zero" << flush;
  dz << "testing is_matrix_zero" << endl << flush;
  dz << D.is_matrix_zero() << "\n" << flush;
  dz << is_matrix_zero(F) << "\n" << flush;
  cout << "...........................completed\n" << flush;

  cout << "testing max / min " << flush;
  dz << "testing max / min" << endl << flush;
  A.max(scalar_1);
  dz << scalar_1 << endl << flush;
  dz << A.max() << endl << flush;
  dz << max(A) << endl << flush;
  A.min(scalar_1);
  dz << scalar_1 << endl << flush;
  dz << A.min() << endl << flush;
  dz << min(A) << endl << flush;
  cout << "...............................completed\n" << flush;

  cout << "testing max_pos / min_pos " << flush;
  dz << "testing min_pos / max_pos" << endl << flush;
  A.max_pos(scalar_1, i, j);
  dz << scalar_1 << " " << i << " " << j << endl << flush;
  dz << A.max_pos(i, j) << " " << i << " " << j << endl << flush;
  dz << max_pos(A, i, j) << " " << i << " " << j << endl << flush;
  A.min_pos(scalar_1, i, j);
  dz << scalar_1 << " " << i << " " << j << endl << flush;
  dz << A.min_pos(i, j) << " " << i << " " << j << endl << flush;
  dz << min_pos(A, i, j) << " " << i << " " << j << endl << flush;
  cout << ".......................completed\n" << flush;

  cout << "testing max_abs / min_abs " << flush;
  dz << "testing min_abs / max_abs" << endl << flush;
  A.max_abs(scalar_1);
  dz << scalar_1 << endl << flush;
  dz << A.max_abs() << endl << flush;
  dz << max_abs(A) << endl << flush;
  A.min_abs(scalar_1);
  dz << scalar_1 << endl << flush;
  dz << A.min_abs() << endl << flush;
  dz << min_abs(A) << endl << flush;
  cout << ".......................completed\n" << flush;

  cout << "testing max_abs_pos / min_abs_pos " << flush;
  dz << "testing min_abs_pos / max_abs_pos" << endl << flush;
  A.max_abs_pos(scalar_1, i, j);
  dz << scalar_1 << " " << i << " " << j << endl << flush;
  dz << A.max_abs_pos(i, j) << " " << i << " " << j << endl << flush;
  dz << max_abs_pos(A, i, j) << " " << i << " " << j << endl << flush;
  A.min_abs_pos(scalar_1, i, j);
  dz << scalar_1 << " " << i << " " << j << endl << flush;
  dz << A.min_abs_pos(i, j) << " " << i << " " << j << endl << flush;
  dz << min_abs_pos(A, i, j) << " " << i << " " << j << endl << flush;
  cout << "...............completed\n" << flush;

  cout << "testing hadamard " << flush;
  dz << "testing hadamard" << endl << flush;
  A.hadamard(scalar_1);
  dz << scalar_1 << endl << flush;
  dz << A.hadamard() << endl << flush;
  dz << hadamard(A) << endl << flush;
  cout << "................................completed\n" << flush;

  cout << "testing row_norm / column_norm " << flush;
  dz << "testing column_norm / row_norm" << endl << flush;
  A.row_norm(scalar_1, 0, 2);
  dz << scalar_1 << endl << flush;
  dz << A.row_norm(0, 2) << endl << flush;
  dz << row_norm(A, 0, 2) << endl << flush;
  A.column_norm(scalar_1, 0, 2);
  dz << scalar_1 << endl << flush;
  dz << A.column_norm(0, 2) << endl << flush;
  dz << column_norm(A, 0, 2) << endl << flush;
  cout << "..................completed\n" << flush; 

  //cout << A << B << C << D << E << F << flush;

  cout << "testing rank" << flush;
  dz << "testing rank" << endl << flush;
  dz << rank(A) << endl << flush;
  dz << A.rank() <<endl << flush;
  cout << ".....................................completed\n" << flush;
  
  cout << "testing lininr" << flush;
  dz << "testing lininr" << endl << flush;
  lidia_size_t *q = lininr(F);
  for (i = 0; i <= q[0]; i++)
    dz << q[i] << " ";
  dz << endl << flush;
  delete[] q;
  
  q = F.lininr();
  for (i = 0; i <= q[0]; i++)
    dz << q[i] << " ";
  dz << endl << flush;
  delete[] q;
  cout << "...................................completed\n" << flush;

  cout << "testing lininc" << flush;
  dz << "testing lininc" << endl << flush;
  lidia_size_t *q1 = lininc(F);
  for (i = 0; i <= q1[0]; i++)
    dz << q1[i] << " ";
  dz << endl << flush;
  delete[] q1;

  q1 = F.lininc();
  for (i = 0; i <= q1[0]; i++)
    dz << q1[i] << " ";
  dz << endl << flush;
  delete[] q1;
  cout << "...................................completed\n" << flush;

  cout << "testing RegExpansion" << flush;
  dz << "testing RegExpansion" << endl << flush;
  F = trans(A);
  q = lininr(F);
  D = A;
  E = A;
  regexpansion(D, q);
  dz << D << flush;
  E.regexpansion(q);
  dz << E << flush;
  cout << ".............................completed\n" << flush;

  cout << "testing adj" << flush;
  dz << "testing adj" << endl << flush;
  F = A * trans(A);
  bigint_matrix ADJ = adj(F);
  dz << ADJ << ADJ * F << flush;
  ADJ.adj(F);
  dz << ADJ << ADJ * F << flush;
  cout << "......................................completed\n" << flush;

  cout << "testing latticedet / latticedet2" << flush;
  dz << "testing latticedet / latticedet2" << endl << flush;
  A.latticedet(scalar_1);
  dz << scalar_1 << endl << flush;
  scalar_1 = A.latticedet();
  dz << scalar_1 << endl << flush;
  scalar_1 = latticedet(A);
  dz << scalar_1 << endl << flush;

  A.latticedet2(scalar_1);
  dz << scalar_1 << endl << flush;
  scalar_1 = A.latticedet2();
  dz << scalar_1 << endl << flush;
  scalar_1 = latticedet2(A);
  dz << scalar_1 << endl << flush;
  cout << ".................completed\n" << flush;

  cout << "testing det" << flush;
  dz << "testing det" << endl << flush;
  F.det(scalar_1);
  dz << scalar_1 << endl << flush;
  scalar_1 = F.det();
  dz << scalar_1 << endl << flush;
  scalar_1 = det(F);
  dz << scalar_1 << endl << flush;
  cout << "......................................completed\n" << flush;

  cout << "testing charpoly" << flush;
  dz << "charpoly" << endl << flush;
  c = F.get_no_of_columns();
  pointer_5 = charpoly(F);
  for (i = 0; i < c + 1; i++)
    dz << pointer_5[i] << " ";
  dz << endl << flush;

  pointer_5 = F.charpoly();
  for (i = 0; i < c + 1; i++)
    dz << pointer_5[i] << " ";
  dz << endl << flush;
  cout << ".................................completed\n" << flush; 

  cout << "testing hnf_simple" << flush;
  dz << "testing hnf_simple" << endl << flush;
  F = A;
  F.hnf_simple();
  dz << F << flush;
  F = A;
  F.hnf_simple(D);
  dz << F << A*D << flush;

  F = A;
  hnf_simple(F);
  dz << F << flush;
  F = A;
  hnf_simple(F, D);
  dz << F << A*D << flush;
  cout << "...............................completed\n" << flush;

  cout << "testing hnf_havas" << flush;
  dz << "testing hnf_havas" << endl << flush;
  F = A;
  F.hnf_havas();
  dz << F << flush;
  F = A;
  F.hnf_havas(D);
  dz << F << A*D << flush;

  F = A;
  hnf_havas(F);
  dz << F << flush;
  F = A;
  hnf_havas(F, D);
  dz << F << A*D << flush;
  cout << "................................completed\n" << flush;

  cout << "testing hnfmod_dkt" << flush;
  dz << "testing hnfmod_dkt" << endl << flush;
  scalar_1 = latticedet2(A);
  F = A;
  F.hnfmod_dkt(scalar_1);
  dz << F << flush;
  F = A;
  F.hnfmod_dkt();
  dz << F << flush;
  F = A;
  hnfmod_dkt(F);
  dz << F << flush;
  F = A;
  hnfmod_dkt(F, scalar_1);
  dz << F << flush;
  cout << "...............................completed\n" << flush;

  cout << "testing hnfmod_cohen" << flush;
  dz << "testing hnfmod_cohen" << endl << flush;
  scalar_1 = latticedet2(A);
  F = A;
  F.hnfmod_cohen(scalar_1);
  dz << F << flush;
  F = A;
  F.hnfmod_cohen();
  dz << F << flush;
  F = A;
  hnfmod_cohen(F);
  dz << F << flush;
  F = A;
  hnfmod_cohen(F, scalar_1);
  dz << F << flush;
  cout << ".............................completed\n" << flush;

  cout << "testing hnfmod_mueller" << flush;
  dz << "testing hnfmod_mueller" << endl << flush;
  F = A;
  F.hnfmod_mueller(D);
  dz << F << A*D << flush;

  F = A;
  hnfmod_mueller(F, D);
  dz << F << A*D << flush;
  cout << "...........................completed\n" << flush;
  
  cout << "testing kernel / kernel2" << flush;
  dz << "testing kernel / kernel2" << endl << flush;
  F = kernel(A);
  dz << F << flush;
  D.kernel(A);
  dz << D << flush;

  F = kernel2(A);
  dz << F << flush;
  D.kernel2(A);
  dz << D << flush;
  cout << ".........................completed\n" << flush;

  cout << "testing reginvimage / reginvimage2" << flush;
  dz << "testing reginvimage / reginvimage2" << endl << flush;
  C = A * trans(A);
  F = reginvimage(C, B);
  dz << F << flush;
  D.reginvimage(C, B);
  dz << D << flush;

  F = reginvimage2(C, B);
  dz << F << flush;
  D.reginvimage2(C, B);
  dz << D << flush;
  cout << "...............completed\n" << flush;

  cout << "testing image" << flush;
  dz << "testing image" << endl << flush;
  F = image(A);
  dz << F << flush;
  D.image(A);
  dz << D << flush;

  F = image2(A);
  dz << F << flush;
  D.image2(A);
  dz << D << flush;
  cout << "....................................completed\n" << flush;

  cout << "testing invimage" << flush;
  dz << "testing invimage" << endl << flush;
  pointer_1 = new bigint[4];
  pointer_1[0] = 30;
  pointer_1[1] = 40;
  pointer_1[2] = 50;
  pointer_1[3] = 60;
  F = invimage(A, pointer_1);
  dz << F << flush;
  D.invimage(A, pointer_1);
  dz << D << flush;
  cout << ".................................completed\n" << flush;

  cout << "testing solve" << flush;
  dz << "testing solve" << endl << flush;
  pointer_1[0] = 30;
  pointer_1[1] = 40;
  pointer_1[2] = 50;
  pointer_1[3] = 60;
  F = solve(A, pointer_1);
  dz << F << flush;
  D.solve(A, pointer_1);
  dz << D << flush;
  cout << "....................................completed\n" << flush;

  cout << "testing snf_hartley" << flush;
  dz << "testing snf_hartley" << endl << flush;
  F = A;
  F.snf_hartley();
  dz << F << flush;
  F = A;
  F.snf_hartley(D,E);
  dz << F << D * A * E << flush;
  F = A;
  snf_hartley(F);
  dz << F << flush;
  F = A;
  snf_hartley(F, D, E);
  dz << F << D * A * E << flush;
  cout << "..............................completed\n" << flush;

  cout << "testing snf_simple" << flush;
  dz << "testing snf_simple" << endl << flush;
  F = A;
  F.snf_simple();
  dz << F << flush;
  F = A;
  F.snf_simple(D,E);
  dz << F << D * A * E << flush;
  F = A;
  snf_simple(F);
  dz << F << flush;
  F = A;
  snf_simple(F, D, E);
  dz << F << D * A * E << flush;
  cout << "...............................completed\n" << flush;

  cout << "testing snf_havas" << flush;
  dz << "testing snf_havas" << endl << flush;
  F = A;
  F.snf_havas();
  dz << F << flush;
  F = A;
  F.snf_havas(D,E);
  dz << F << D * A * E << flush;
  F = A;
  snf_havas(F);
  dz << F << flush;
  F = A;
  snf_havas(F, D, E);
  dz << F << D * A * E << flush;
  cout << "................................completed\n" << flush;

  cout << "testing snf_mult" << flush;
  dz << "testing snf_mult" << endl << flush;
  F = A;
  F.snf_mult();
  dz << F << flush;
  F = A;
  F.snf_mult(D,E);
  dz << F << D * A * E << flush;
  F = A;
  snf_mult(F);
  dz << F << flush;
  F = A;
  snf_mult(F, D, E);
  dz << F << D * A * E << flush;
  cout << ".................................completed\n" << flush;

  cout << "testing snf_add" << flush;
  dz << "testing snf_add" << endl << flush;
  F = A;
  F.snf_add();
  dz << F << flush;
  F = A;
  F.snf_add(D,E);
  dz << F << D * A * E << flush;
  F = A;
  snf_add(F);
  dz << F << flush;
  F = A;
  snf_add(F, D, E);
  dz << F << D * A * E << flush;
  cout << "..................................completed\n" << flush;

  cout << "testing snf_new" << flush;
  dz << "testing snf_new" << endl << flush;
  F = A;
  F.snf_new();
  dz << F << flush;
  F = A;
  F.snf_new(D,E);
  dz << F << D * A * E << flush;
  F = A;
  snf_new(F);
  dz << F << flush;
  F = A;
  snf_new(F, D, E);
  dz << F << D * A * E << flush;
  cout << "..................................completed\n" << flush;
  
  cout << "testing snfmod_dkt" << flush;
  dz << "testing snfmod_dkt" << endl << flush;
  scalar_1 = latticedet2(A);
  F = A;
  F.snfmod_dkt(scalar_1);
  dz << F << flush;
  F = A;
  F.snfmod_dkt();
  dz << F << flush;
  F = A;
  snfmod_dkt(F);
  dz << F << flush;
  F = A;
  snfmod_dkt(F, scalar_1);
  dz << F << flush;
  cout << "...............................completed\n" << flush;

 cout << "testing snfmod_cohen" << flush;
  dz << "testing snfmod_cohen" << endl << flush;
  scalar_1 = latticedet2(A);
  F = A;
  F.snfmod_cohen(scalar_1);
  dz << F << flush;
  F = A;
  F.snfmod_cohen();
  dz << F << flush;
  F = A;
  snfmod_cohen(F);
  dz << F << flush;
  F = A;
  snfmod_cohen(F, scalar_1);
  dz << F << flush;
  cout << ".............................completed\n" << flush;

  cout << "\nThe functions ChinRest, get_primes, mgcd, mgcd1, mgcd2 and mgcd3 are\n"
    " tested by implication." << flush; 

  dz.close(); 
  cout << "\nPlease use now the 'diff' or 'cmp' command to verify\n";
  cout << "the equality of bigint_matrix_appl.dat";
  cout << " and bigint_matrix_appl.out.\n\n" << flush;
}
