int test_string_cast_vector()
{
    int Error = 0;

    {
        glm::vec2 A1(1, 2);
        std::string A2 = glm::to_string(A1);
        Error += A2 != std::string("vec2(1.000000, 2.000000)") ? 1 : 0;

        glm::vec3 B1(1, 2, 3);
        std::string B2 = glm::to_string(B1);
        Error += B2 != std::string("vec3(1.000000, 2.000000, 3.000000)") ? 1 : 0;

        glm::vec4 C1(1, 2, 3, 4);
        std::string C2 = glm::to_string(C1);
        Error += C2 != std::string("vec4(1.000000, 2.000000, 3.000000, 4.000000)") ? 1 : 0;

        glm::dvec2 J1(1, 2);
        std::string J2 = glm::to_string(J1);
        Error += J2 != std::string("dvec2(1.000000, 2.000000)") ? 1 : 0;

        glm::dvec3 K1(1, 2, 3);
        std::string K2 = glm::to_string(K1);
        Error += K2 != std::string("dvec3(1.000000, 2.000000, 3.000000)") ? 1 : 0;

        glm::dvec4 L1(1, 2, 3, 4);
        std::string L2 = glm::to_string(L1);
        Error += L2 != std::string("dvec4(1.000000, 2.000000, 3.000000, 4.000000)") ? 1 : 0;
    }

    {
        glm::bvec2 M1(false, true);
        std::string M2 = glm::to_string(M1);
        Error += M2 != std::string("bvec2(false, true)") ? 1 : 0;

        glm::bvec3 O1(false, true, false);
        std::string O2 = glm::to_string(O1);
        Error += O2 != std::string("bvec3(false, true, false)") ? 1 : 0;

        glm::bvec4 P1(false, true, false, true);
        std::string P2 = glm::to_string(P1);
        Error += P2 != std::string("bvec4(false, true, false, true)") ? 1 : 0;
    }

    {
        glm::ivec2 D1(1, 2);
        std::string D2 = glm::to_string(D1);
        Error += D2 != std::string("ivec2(1, 2)") ? 1 : 0;

        glm::ivec3 E1(1, 2, 3);
        std::string E2 = glm::to_string(E1);
        Error += E2 != std::string("ivec3(1, 2, 3)") ? 1 : 0;

        glm::ivec4 F1(1, 2, 3, 4);
        std::string F2 = glm::to_string(F1);
        Error += F2 != std::string("ivec4(1, 2, 3, 4)") ? 1 : 0;
    }

    {
        glm::i8vec2 D1(1, 2);
        std::string D2 = glm::to_string(D1);
        Error += D2 != std::string("i8vec2(1, 2)") ? 1 : 0;

        glm::i8vec3 E1(1, 2, 3);
        std::string E2 = glm::to_string(E1);
        Error += E2 != std::string("i8vec3(1, 2, 3)") ? 1 : 0;

        glm::i8vec4 F1(1, 2, 3, 4);
        std::string F2 = glm::to_string(F1);
        Error += F2 != std::string("i8vec4(1, 2, 3, 4)") ? 1 : 0;
    }

    {
        glm::i16vec2 D1(1, 2);
        std::string D2 = glm::to_string(D1);
        Error += D2 != std::string("i16vec2(1, 2)") ? 1 : 0;

        glm::i16vec3 E1(1, 2, 3);
        std::string E2 = glm::to_string(E1);
        Error += E2 != std::string("i16vec3(1, 2, 3)") ? 1 : 0;

        glm::i16vec4 F1(1, 2, 3, 4);
        std::string F2 = glm::to_string(F1);
        Error += F2 != std::string("i16vec4(1, 2, 3, 4)") ? 1 : 0;
    }

    {
        glm::i64vec2 D1(1, 2);
        std::string D2 = glm::to_string(D1);
        Error += D2 != std::string("i64vec2(1, 2)") ? 1 : 0;

        glm::i64vec3 E1(1, 2, 3);
        std::string E2 = glm::to_string(E1);
        Error += E2 != std::string("i64vec3(1, 2, 3)") ? 1 : 0;

        glm::i64vec4 F1(1, 2, 3, 4);
        std::string F2 = glm::to_string(F1);
        Error += F2 != std::string("i64vec4(1, 2, 3, 4)") ? 1 : 0;
    }

    return Error;
}
Esempio n. 2
0
int main(int argc, char *argv[])
{
  if (argc != 2)
    {
      puts("\a\n usage: math_tst matrix_file_name\n");
      exit( 1 );
    }
::printf("\n\n-------------  MACHINE (CPU) DEPENDENT THINGS  --------------\n\n");

// defining machine epsilon for different built in data types supported by C++
float        float_eps       = f_macheps();  // or use float.h values FLT_EPSILON
double       double_eps      = d_macheps();  // or use float.h values DBL_EPSILON
//long double  long_double_eps = ld_macheps(); // or use float.h values LDBL_EPSILON

::printf("\n float macheps = %.20e \n",float_eps);
::printf(" double macheps = %.20e \n",double_eps);
//::printf(" long double macheps = %.20Le \n\n\n",long_double_eps);


// Usual tolerance is defined as square root of machine epsilon
float        sqrt_f_eps       = sqrt(f_macheps());
double       sqrt_d_eps       = sqrt(d_macheps());
//long double  sqrt_ld_eps      = sqrt(ld_macheps());

::printf("\n sqrt float macheps = %.20e \n",sqrt_f_eps);
::printf(" sqrt double macheps = %.20e \n",sqrt_d_eps);
//::printf(" sqrt long double macheps = %.20Le \n",sqrt_ld_eps);



::printf("\n\n----------------  MATRIX  -----------------\n\n");

// New data type MATRIX is defined in such a way that it can be regarded
// as concrete data type.
// default constructor:
  BJmatrix matrix1;
  matrix1.print("m1","matrix1");

  static double initvalue[] = {1.0, 2.0,
                               3.0, 4.0};
// constructor with matrix initialization
  BJmatrix matrix2(2,2,initvalue);
  matrix2.print("m2","matrix2");

// unit matrix initialization ( third order )
  BJmatrix matrix3("I",3);
  matrix3.print("m3","matrix3");

// matrix initialization from the file that is in predefined format!
  BJmatrix  m(argv[1]);
  m.print("m","m is");
//====
// matrix assignment
  BJmatrix first_matrix = m;
  first_matrix.print("fm","first_matrix is");

// ---------------------------------
::printf("\n\n--------EIGENVECTORS and EIGENVALUES-----------\n");
  static double symm_initvalue[] = {1.0, 0.0,
                                    0.0, 0.0};
// constructor with matrix initialization
  BJmatrix sym_matrix(2,2,symm_initvalue);
  sym_matrix.print("m","Sym_matrix");

// Eigenvalues
  BJvector eval = sym_matrix.eigenvalues();
  eval.print("ev","Eigenvalues of sym_matrix");
// Eigenvectors
  BJmatrix evect = sym_matrix.eigenvectors();
  evect.print("ev","Eigenvectors of sym_matrix");

// matrix to file "test.$$$"
  m.write_standard("test.$$$", "this is a test");

// equivalence of two matrices ( within tolerance sqrt(macheps) )
  if ( first_matrix == m ) ::printf("\n first_matrix == m  TRUE \n");
  else ::printf("\a\n first_matrix == m  NOTTRUE \n");

// matrix addition
  BJmatrix m2 =m+m;
  m2.print("m2","\nm+m = \n");

// equivalence of two matrices ( within tolerance sqrt(macheps) )
  if ( m2 == m ) ::printf("\a\n m2 == m  TRUE \n");
  else ::printf("\n m2 == m  NOTTRUE \n");

// matrix substraction
  BJmatrix m3 =m-m;
  m3.print("m3","\nm-m = \n");

// matrix multiplication
  BJmatrix m4 = m*m;
  m4.print("m4","\n m*m = \n");

// matrix transposition
  BJmatrix mtran = m.transpose();
  mtran.print("mt","transpose of m is");

// determinant of matrix
 printf("determinant = %6.6f \n",m.determinant());

// matrix inversion
  BJmatrix minv = m.inverse();
  minv.print("mi","inverse of m is");
// check matrix inversion
  ( m * minv ).print("1"," m * m.inverse() ");

// minima, maxima, mean and variance values for matrix:
  printf("min = %6.6f \n", m.mmin() );
  printf("max = %6.6f \n", m.mmax() );
  printf("mean = %6.6f \n", m.mean() );
  printf("variance = %6.6f \n", m.variance() );

//====//===printf("\n\n-----------------  SKY MATRIX ----------------------\n\n");
//====//===
//====//===// skymatrix as defined by K.J. Bathe in "FE procedures in Engineering Analysis"
//====//===// The example is from that book too!
//====//===
//====//===int maxa[] = { 1,   2,         4,          6,          8,                  13};
//====//===double a[] = {2.0, 3.0, -2.0, 5.0, -2.0, 10.0, -3.0, 10.0, 4.0, 0.0, 0.0, -1.0};
//====//===double rhs[] = { 0.0, 1.0, 0.0, 0.0, 0.0 };
//====//===
//====//===// skymatrix constructor
//====//===  skymatrix first( 5, maxa, a);
//====//===
//====//===// simple print functions:
//====//===  first.full_print("\nfirst Sparse Skyline Matrix as FULL :\n ");
//====//===  first.lower_print("\nfirst Sparse Skyline Matrix :\n ");
//====//===  first.upper_print("\nfirst Sparse Skyline Matrix :\n ");
//====//===
//====//===// skymatrix assignment
//====//===  skymatrix second = first;
//====//===  second.full_print("\nsecond Sparse Skyline Matrix as FULL :\n ");
//====//===
//====//===//  skymatrix third; // not defined !
//====//===// assignments:
//====//===  skymatrix third = second = first;
//====//===
//====//===// LDL factorization ( see K.J. Bathe's book! )
//====//===  first = first.v_ldl_factorize();
//====//===
//====//===// simple print functions:
//====//===  first.lower_print("\n lower first but factorized :\n ");
//====//===  first.full_print("\nfirst but factorized Sparse Skyline Matrix as FULL :\n ");
//====//===  first.upper_print("\n upper first but factorized :\n ");
//====//===
//====//===// right hand side reduction ( see K.J. Bathe's book! ) ( vetor of unknowns is rhs )
//====//===  first.d_reduce_r_h_s_l_v( rhs );
//====//===  int i=0;
//====//===  for( i=0 ; i<5 ; i++ )
//====//===    {
//====//===      printf("intermediate_rhs[%d] = %8.4f\n",i, rhs[i]);
//====//===    }
//====//===
//====//===// backsubstitution
//====//===  first.d_back_substitute ( rhs );
//====//===  for( i=0 ; i<5 ; i++ )
//====//===    {
//====//===      printf("solution_rhs[%d] = %8.4f\n",i, rhs[i]);
//====//===    }
//====//===
//====//===// minima, maxima and mean values for skymatrix:
//====//===  printf("min = %6.6f \n", first.mmin() );
//====//===  printf("max = %6.6f \n", first.mmax() );
//====//===  printf("mean = %6.6f \n", first.mean() );
//====//===//
//====//===//
//====//===
//====//===printf("\n\n-----------------  PROFILE MATRIX ----------------------\n");
//====//===printf("-----------------  EXAMPLE 1 ----------------------\n\n");
//====//===
//====//===// profilematrix as defined by O.C. Zienkiewicz and R.L. Taylor
//====//===// in "The FEM  - fourth edition"
//====//===// The example is from: K.J. Bathe: "FE procedures in Engineering Analysis"
//====//===
//====//===int jp[]    = { 0,    1,    2,    3,                   7};
//====//===double au[] = {    -2.0, -2.0, -3.0, -1.0, 0.0, 0.0, 4.0};
//====//===double ad[] = { 2.0, 3.0, 5.0, 10.0, 10.0 };
//====//===double* al  = au;
//====//===double b[] = { 0.0, 1.0, 0.0, 0.0, 0.0 };
//====//===
//====//===// profile matrix constructor
//====//===  profilematrix first_profile( 5, jp, 'S', au, al, ad);
//====//===
//====//===// simple print function
//====//===  first_profile.full_print("\nfirst_profile Sparse Profile Matrix as FULL :\n ");
//====//===
//====//===// asignment operetor
//====//===  profilematrix second_profile = first_profile;
//====//===  second_profile.full_print("\nsecond_profile Sparse Profile Matrix as FULL :\n ");
//====//===
//====//===// triangularization ( Crout's method ); see: O.C. Zienkiewicz and R.L. Taylor:
//====//===// "The FEM - fourth edition"
//====//===  first_profile = first_profile.datri();
//====//===  first_profile.full_print("\nfirst but factorized Sparse Profile Matrix as FULL :\n ");
//====//===  ::printf("\n\n");
//====//===
//====//===// right hand side reduction and backsubstitution ( vector of unknowns is b )
//====//===  first_profile.dasol(b);
//====//===  for( i=0 ; i<5 ; i++ )
//====//===    {
//====//===      printf("solution_b[%d] = %8.4f\n",i, b[i]);
//====//===    }
//====//===
//====//===  printf("\n\nmin = %6.6f \n", first_profile.mmin() );
//====//===  printf("max = %6.6f \n", first_profile.mmax() );
//====//===  printf("mean = %6.6f \n", first_profile.mean() );
//====//===
//====//===
//====//===printf("\n-----------------  EXAMPLE 2 ----------------------\n\n");
//====//===
//====//===// The example is from: O.C. Zienkiewicz and R.L. Taylor:
//====//===// "The FEM - fourth edition"
//====//===int jp2[]    = { 0,    1,    3};
//====//===double au2[] = {    2.0, 1.0, 2.0};
//====//===double ad2[] = { 4.0, 4.0, 4.0};
//====//===double* al2  = au2;
//====//===double b2[] = { 0.0, 0.0, 1.0 };
//====//===
//====//===// profile matrix constructor
//====//===  profilematrix first_profile2( 3, jp2, 'S', au2, al2, ad2);
//====//===
//====//===// simple print function
//====//===  first_profile2.full_print("\nfirst_profile Sparse Profile Matrix as FULL :\n ");
//====//===
//====//===// asignment operetor
//====//===  profilematrix second_profile2 = first_profile2;
//====//===  second_profile2.full_print("\nsecond_profile Sparse Profile Matrix as FULL :\n ");
//====//===
//====//===// triangularization ( Crout's method ); see: O.C. Zienkiewicz and R.L. Taylor:
//====//===// "The FEM - fourth edition"
//====//===  profilematrix first_profile2TRI = first_profile2.datri();
//====//===  first_profile2TRI.full_print("\nfirst but factorized Sparse Profile Matrix as FULL :\n ");
//====//===  ::printf("\n\n");
//====//===
//====//===// right hand side reduction and backsubstitution ( vector of unknowns is b2 )
//====//===  first_profile2TRI.dasol( b2 );
//====//===  for( i=0 ; i<3 ; i++ )
//====//===    {
//====//===      printf("solution_b[%d] = %8.4f\n",i, b2[i]);
//====//===    }
//====//===
//====//===  printf("\n\nmin = %6.6f \n", first_profile2.mmin() );
//====//===  printf("max = %6.6f \n", first_profile2.mmax() );
//====//===  printf("mean = %6.6f \n", first_profile2.mean() );
//====//===
//====//===
//====//===printf("\n-----------------  EXAMPLE 3 ----------------------\n\n");
//====//===
//====//===// The main advantage of profile solver as described in
//====//===// O.C. Zienkiewicz and R.L. Taylor: "The FEM - fourth edition"
//====//===// is that it supports nonsymetric matrices stored in profile format.
//====//===
//====//===int jp3[]    = { 0,    1,    3};
//====//===double au3[] = { 2.0, 3.0, 2.0};
//====//===double ad3[] = { 4.0, 4.0, 4.0};
//====//===double al3[] = { 2.0, 1.0, 2.0};
//====//===double  b3[] = { 1.0, 1.0, 1.0 };
//====//===
//====//===// nonsymetric profile matrix constructor
//====//===  profilematrix first_profile3( 3, jp3, 'N', au3, al3, ad3);
//====//===
//====//===// print out
//====//===  first_profile3.full_print("\nfirst_profile Sparse Profile Matrix as FULL :\n ");
//====//===
//====//===// triangularization ( Crout's method ); see: O.C. Zienkiewicz and R.L. Taylor:
//====//===// "The FEM - fourth edition"
//====//===  profilematrix first_profile3TRI = first_profile3.datri();
//====//===  first_profile3TRI.full_print("\nfirst but factorized \
//====//===  Sparse Profile Matrix as FULL :\n ");
//====//===  ::printf("\n\n");
//====//===
//====//===// right hand side reduction and backsubstitution ( vector of unknowns is b3 )
//====//===  first_profile3TRI.dasol( b3 );
//====//===  for( i=0 ; i<3 ; i++ )
//====//===    {
//====//===      printf("solution_b[%d] = %8.4f\n",i, b3
//====//===      [i]);
//====//===    }
//====//===
//====//===  printf("\n\nmin = %6.6f \n", first_profile3.mmin() );
//====//===  printf("max = %6.6f \n", first_profile3.mmax() );
//====//===  printf("mean = %6.6f \n", first_profile3.mean() );
//====//===
//====//===
//====printf("\n\n------------  VECTOR  -------------------\n\n");

static double vect1[] = {2.0, 3.0, -2.0, 5.0, -2.0};
static double vect2[] = {1.0, 1.0, 1.0, 1.0, 1.0};

// vector constructor
  BJvector first_vector( 5, vect1);
  first_vector.print("f","\n\nfirst_vector vector\n");

// vector constructor
  BJvector second_vector ( 5, vect2);
  second_vector.print("s","\n\nsecond_vector vector\n");

// default constructor for vector
  BJvector third_vector;
// vector assignment
  third_vector = first_vector + second_vector;
  third_vector.print("t","\nfirst_vector + second_vector = \n");

  BJvector dot_product = first_vector.transpose() * second_vector; 
//  vector dot product;
//  dot_product = first_vector.transpose() * second_vector;
//====  dot_product.print("d","\nfirst_vector * second_vector \n");
//====
      
printf("\n\n------------VECTOR AND MATRIX -----------------\n\n");
static double vect3[] = {1.0, 2.0, 3.0, 4.0, 5.0};

//default construcotrs
matrix res1;
matrix res2;

// matrix constructor
matrix vect_as_matrix(5, 1, vect3);
BJvector vect(5, vect3);

first_matrix.print("f","\n first matrix");

// vector and matrix are quite similar !
vect_as_matrix.print("vm","\n vector as matrix");
vect.print("v","\n vector");

// this should give the same answer! ( vector multiplication with matrix
res1 = vect_as_matrix.transpose() * first_matrix;
res2 = vect.transpose() * first_matrix;

res1.print("r1","\n result");
res2.print("r2","\n result");






::printf("\n\n----------------- TENSOR --------------------\n\n");

// tensor default construcotr
  tensor t1;
  t1.print("t1","\n tensor t1");

  static double t2values[] = {  1,2,3,
                                4,5,6,
                                7,8,9  };
// tensor constructor with values assignments ( order 2 ; like matrix )
  tensor t2( 2, def_dim_2, t2values);
  t2.print("t2","\ntensor t2 (2nd-order with values assignement)");

  tensor tst( 2, def_dim_2, t2values); 
//  t2 = t2*2.0;
//  t2.print("t2x2","\ntensor t2 x 2.0");
  t2.print("t2","\noriginal tensor t2 ");
  tst.print("tst","\ntst ");

  tensor t2xt2 = t2("ij")*t2("jk");
  t2xt2.print("t2xt2","\ntensor t2 x t2");

  tensor t2xtst = t2("ij")*tst("jk");
  t2xtst.print("t2xtst","\ntensor t2 x tst");

  t2.print("t2","\noriginal tensor t2 ");


  static double Tvalues[] = {   1,2,3,
                                4,5,6,
                                7,8,9  };
  tensor multTest( 2, def_dim_2, t2values);

	 double a = 5.0;

	 double b  = a * multTest("ab"):

// tensor constructor with 0.0 assignment ( order 4 ; 4D array )
  tensor ZERO(4,def_dim_4,0.0);
  ZERO.print("z","\ntensor ZERO (4-th order with value assignment)");

  static double t4val[] =
{ 11.100,  12.300,  13.100,   15.230,  16.450,   14.450,  17.450,  18.657,  19.340,
 110.020, 111.000, 112.030,  114.034, 115.043,  113.450, 116.670, 117.009, 118.060,
 128.400, 129.500, 130.060,  132.560, 133.000,  131.680, 134.100, 135.030, 136.700,
 119.003, 120.400, 121.004,  123.045, 124.023,  122.546, 125.023, 126.043, 127.000,
 137.500, 138.600, 139.000,  141.067, 142.230,  140.120, 143.250, 144.030, 145.900,
 146.060, 147.700, 148.990,  150.870, 151.000,  149.780, 152.310, 153.200, 154.700,
 164.050, 165.900, 166.003,  168.450, 169.023,  167.067, 170.500, 171.567, 172.500,
 155.070, 156.800, 157.067,  159.000, 160.230,  158.234, 161.470, 162.234, 163.800,
 173.090, 174.030, 175.340,  177.060, 178.500,  176.000, 179.070, 180.088, 181.200};

// tensor constructor with values assignment ( order 4 ; 4D array )
  tensor t4(4, def_dim_4, t4val);
  t4.print("t4","\ntensor t4 (4th-order with values assignment)");

//  Some relevant notes from the Dec. 96 Draft (as pointed out by KAI folks):
//  
//  "A binary operator shall be implemented either by a  non-static  member
//    function (_class.mfct_) with one parameter or by a non-member function
//    with two parameters.  Thus, for any binary  operator  @,  x@y  can  be
//    interpreted as either x.operator@(y) or operator@(x,y)." [13.5.2]
//  
//  "The order of evaluation of arguments [of a function call] is
//  unspecified."  [5.2.2 paragraph 9]
//  
//  
// SO THAT IS WHY I NEED THIS temp
// It is not evident which operator will be called up first: operator() or operator* .
// 
//% ////////////////////////////////////////////////////////////////////////
// testing the multi products using indicial notation:
  tensor tst1;
  tensor temp = t2("ij") *  t4("ijkl");
  tst1 = temp("kl")  * t4("klpq")  * t2("pq");
  tst1.print("tst1","\ntensor tst1 = t2(\"ij\")*t4(\"ijkl\")*t4(\"klpq\")*t2(\"pq\");");


// testing inverse function for 4. order tensor. Inverse for 4. order tensor
// is done by converting that tensor to matrix, inverting that matrix
// and finally converting matrix back to tensor
  tensor t4inv_2 = t4.inverse_2();
  t4inv_2.print("t4i","\ntensor t4 inverted_2");
  tensor unity_2 = t4("ijkl")*t4inv_2("klpq");
  unity_2.print("uno2","\ntensor unity_2");

//....................................................................
// There  are several built in tensor types. One of them is:
// Levi-Civita permutation tensor
  tensor e("e",3,def_dim_3);
  e.print("e","\nLevi-Civita permutation tensor e");

// The other one is:
// Kronecker delta tensor
  tensor I2("I", 2, def_dim_2);
  I2.print("I2","\ntensor I2 (2nd order unit tensor: Kronecker Delta -> d_ij)");

// tensor multiplications 
  tensor I2I2 = I2("ij")*I2("ij");
  I2I2.print("I2I2","\ntensor I2 * I2");

// tensor multiplications ( from right)
  tensor I2PI = I2*PI;
  I2PI.print("I2PI","\ntensor I2 * PI");

// tensor multiplications ( from left)
  tensor PII2 = PI*I2;
  PII2.print("PII2","\ntensor PI * I2");

// Unary minus
  tensor mPII2 = -PII2;
  mPII2.print("mPII2","\ntensor -PI * I2");

// trace function
  double deltatrace = I2.trace();
  ::printf("\ntrace of Kronecker delta is %f \n",deltatrace);

// determinant of 2. order tensor only!
  double deltadet = I2.determinant();
  ::printf("\ndeterminant of Kronecker delta is %f \n",deltadet);

// comparison  of tensor ( again within sqrt(macheps) tolerance )
  tensor I2again = I2;
  if ( I2again == I2 ) ::printf("\n I2again == I2  TRUE (OK)\n");
  else ::printf("\a\n\n\n I2again == I2  NOTTRUE \n\n\n");

//....................................................................
// some of the 4. order tensor used in conituum mechanics:
// the most general representation of the fourth order isotropic tensor
// includes the following fourth orther unit isotropic tensors:
  tensor I_ijkl( 4, def_dim_4, 0.0 );
  I_ijkl = I2("ij")*I2("kl");
//  I_ijkl.print("ijkl","\ntensor I_ijkl = d_ij d_kl)");
  tensor I_ikjl( 4, def_dim_4, 0.0 );
//  I_ikjl = I2("ij")*I2("kl");
  I_ikjl = I_ijkl.transpose0110();
//  I_ikjl.print("ikjl","\ntensor I_ikjl) ");
  tensor I_ikjl_inv_2 = I_ikjl.inverse_2();
//  I_ikjl_inv_2.print("I_ikjl","\ntensor I_ikjl_inverse_2)");
  if ( I_ikjl == I_ikjl_inv_2 ) ::printf("\n\n I_ikjl == I_ikjl_inv_2 !\n");
  else ::printf("\a\n\n           I_ikjl != I_ikjl_inv_2 !\n");

  tensor I_iljk( 4, def_dim_4, 0.0 );
//  I_ikjl = I2("ij")*I2("kl");
//..  I_iljk = I_ikjl.transpose0101();
  I_iljk = I_ijkl.transpose0111();
//  I_iljk.print("iljk","\ntensor I_iljk) ");
// To check out this three fourth-order isotropic tensor please see
// W.Michael Lai, David Rubin, Erhard Krempl
// " Introduction to Continuum Mechanics"
// QA808.2
// ISBN 0-08-022699-X

//....................................................................
// Multiplications between 4. order tensors
  ::printf("\n\n intermultiplications \n");
//  tensor I_ijkl_I_ikjl = I_ijkl("ijkl")*I_ikjl("ikjl");
  tensor I_ijkl_I_ikjl = I_ijkl("ijkl")*I_ikjl("ijkl");
  I_ijkl_I_ikjl.print("i","\n\n I_ijkl*I_ikjl \n");

//  tensor I_ijkl_I_iljk = I_ijkl("ijkl")*I_iljk("iljk");
  tensor I_ijkl_I_iljk = I_ijkl("ijkl")*I_iljk("ijkl");
  I_ijkl_I_iljk.print("i","\n\n I_ijkl*I_iljk \n");

//  tensor I_ikjl_I_iljk = I_ikjl("ikjl")*I_iljk("iljk");
  tensor I_ikjl_I_iljk = I_ikjl("ijkl")*I_iljk("ijkl");
 I_ikjl_I_iljk.print("i","\n\n I_ikjl*I_iljk \n");

//....................................................................
// More multiplications between 4. order tensors
  ::printf("\n\n   intermultiplications same with same \n");
  tensor I_ijkl_I_ijkl = I_ijkl("ijkl")*I_ijkl("ijkl");
  I_ijkl_I_ijkl.print("i","\n\n I_ijkl*I_ijkl \n");

  tensor I_ikjl_I_ikjl = I_ikjl("ikjl")*I_ikjl("ikjl");
  I_ikjl_I_ikjl.print("i","\n\n I_ikjl*I_ikjl \n");

  tensor I_iljk_I_iljk = I_iljk("iljk")*I_iljk("iljk");
  I_iljk_I_iljk.print("i","\n\n I_iljk*I_iljk \n");


// tensor additions ans scalar multiplications
// symmetric part of fourth oder unit isotropic tensor
  tensor I4s = (I_ikjl+I_iljk)*0.5;
//  tensor I4s = 0.5*(I_ikjl+I_iljk);
  I4s.print("I4s","\n symmetric tensor I4s = (I_ikjl+I_iljk)*0.5 ");
// skew-symmetric part of fourth oder unit isotropic tensor
  tensor I4sk = (I_ikjl-I_iljk)*0.5;
  I4sk.print("I4sk","\n skew-symmetric tensor I4sk = (I_ikjl-I_iljk)*0.5 ");

// equvalence check ( they should be different )
  if ( I4s == I4sk ) ::printf("\n\n I4s == I4sk !\n");
  else ::printf("\a\n\n           I4s != I4sk !\n");


//....................................................................
// e-delta identity  ( see Lubliner ( QA931 .L939 1990) page 2.
// and Lai ( QA808.2 L3 1978) page 12 )
  tensor ee = e("ijm")*e("klm");
  ee.print("ee","\ntensor e_ijm*e_klm");
  tensor id = ee - (I_ikjl - I_iljk);
  if ( id == ZERO ) ::printf("\n\n e-delta identity HOLDS !! \n\n");
  tensor ee1 = e("ilm")*e("jlm");
  ee1.print("ee1","\n\n e(\"ilm\")*e(\"jlm\") \n");
  tensor ee2 = e("ijk")*e("ijk");
  ee2.print("ee2","\n\n e(\"ijk\")*e(\"ijk\") \n");


//....................................................................
// Linear Isotropic Elasticity Tensor
// building elasticity tensor
  double Ey = 20000;
  double nu = 0.2;
// building stiffness tensor in one command line
  tensor E1 = (I_ijkl*((Ey*nu*2.0)/(2.0*(1.0+nu)*(1-2.0*nu)))) +
              ( (I_ikjl+I_iljk)*(Ey/(2.0*(1.0+nu))));
// building compliance tensor in one command line
  tensor D1= (I_ijkl * (-nu/Ey)) + ( (I_ikjl+I_iljk) * ((1.0+nu)/(2.0*Ey)));

// multiplication between them
  tensor test = E1("ijkl")*D1("klpq");
  test.print("t","\n\n\n test =  E1(\"ijkl\")*D1(\"klpq\") \n");
// and this should be equal to the symmetric part of 4. order unit tensor
  if ( test == I4s ) ::printf("\n test == I4s  TRUE  ( up to sqrt(macheps())) \n");
  else ::printf("\a\n\n\n   test == I4s    NOTTRUE  ( up to sqrt(macheps())) \n\n\n");

//............Different Way...........................................
// Linear Isotropic Elasticity Tensor
  double lambda = nu * Ey / (1. + nu) / (1. - 2. * nu);
  double mu = Ey / (2. * (1. + nu));
  ::printf("\n  lambda = %.12e\n",lambda);
  ::printf("      mu = %.12e\n",mu);

  ::printf("\nYoung Modulus = %.4e",Ey);
  ::printf("\nPoisson ratio = %.4e\n",nu);
  ::printf(  "    lambda + 2 mu = %.4e\n", (lambda + 2 * mu));

// building elasticity tensor
  tensor E2 = (I_ijkl * lambda) + (I4s * (2. * mu));
  E2.print("E2","tensor E2: elastic moduli Tensor = lambda*I2*I2+2*mu*I4s");

  tensor E2inv = E2.inverse();

// building compliance tensor
  tensor D2= (I_ijkl * (-nu/Ey)) + (I4s * (1./(2.*mu)));
  D2.print("D2","tensor D2: compliance Tensor (I_ijkl * (-nu/Ey)) + (I4s * (1./2./mu))");

  if ( E2inv == D2 ) ::printf("\n E2inv == D2   TRUE \n");
  else ::printf("\a\n\n\n  E2inv == D2   NOTTRUE \n\n\n");

  if ( E1 == E2 ) ::printf("\n E1 == E2  TRUE \n");
  else ::printf("\a\n\n\n  E1 == E2  NOTTRUE \n\n\n");

  if ( D1 == D2 ) ::printf("\n D1 == D2  TRUE \n");
  else ::printf("\a\n\n\n  D1 == D2  NOTTRUE \n\n\n");


// --------------
::printf("\n\n\n --------------------------TENSOR SCALAR MULTIPLICATION ----\n\n");
  tensor EEEE1 = E2;
  tensor EEEE2 = EEEE1*2.0;
  EEEE1.print("E1","tensor EEEE1");
  EEEE2.print("E2","tensor EEEE2");


//###printf("\n\n------------VECTOR AND SKYMATRIX -----------------\n\n");
//###// 1) use of member function full_val is of crucial importance here
//###// and it enable us to use skymatrix as if it is full matrix.
//###// There is however small time overhead but that can be optimized . . .
//###double vect4[] = {1.0, 2.0, 3.0, 4.0, 5.0};
//###
//###matrix res2;
//###vector vector2(5, vect4);
//###second.full_print();
//###vector2.print();
//###res2 = vector2.transpose() * second;
//###res2.print();
//###
//###
//###printf("\n\n------------ MATRIX AND SKYMATRIX -----------------\n\n");
//###// 1) use of member function full_val is of crucial importance here
//###// and it enable us to use skymatrix as if it is full matrix.
//###// There is however small time overhead but that can be optimized . . .
//###
//###matrix big_result;
//###big_result = first_matrix * second;
//###big_result.print();


  exit(1);
//  return 1;
}