Beispiel #1
0
/** This function checks eigenvalues to find which of
the two has the biggest modulus*/
int _QsortComplexEigenvalue( const void* _a, const void* _b ) {
	ComplexEigenvector* a = (ComplexEigenvector*) _a;
	ComplexEigenvector* b = (ComplexEigenvector*) _b;
	double tmp_a, tmp_b;
	tmp_a = Cmplx_Modulus(a->eigenvalue);
	tmp_b = Cmplx_Modulus(b->eigenvalue);
	if ( tmp_a > tmp_b )
		return 1;
	else
		return -1;
}
void ComplexVectorMathSuite_TestComplexVectorMathOperations( ComplexVectorMathSuiteData* data ) {
   unsigned procToWatch;
   Stream*  stream = Journal_Register( Info_Type, (Name)"VectorMathOperationsStream" );
   char     expected_file[PCU_PATH_MAX];

   procToWatch = data->nProcs >=2 ? 1 : 0;

   if (data->rank == procToWatch ) {
      #define STG_COMPLEXVECTOR_TOL 1e-16;
      
      Cmplx  i[] = {{1.00000000, 0.000000000},{0.00000000, 0.000000000},{0.000000000, 0.00000000}};
      Cmplx  j[] = {{0.00000000, 0.00000000},{1.0000000, 0.00000000},{0.00000000, 0.0000000}};
      Cmplx  k[] = {{0.00000000, 0.000000000},{0.00000000, 0.000000000},{1.000000000, 0.000000000}};
      Cmplx  A[] = {{7.4, 1.0}, {  2, 0.0}, {  5, 1.0}, { 1, 0.0}, {  3, 2.0}, {  -42, 0.0}};
      Cmplx  B[] = {{  4, 2.0}, {2.3, 0.0}, {5.8, 0.0}, { 6, 0.0}, {-12, 0.0}, {39289, 0.0}};
      Cmplx  C[] = {{23, 0.0}, {  5, 0.0}, {-14, 0.0}, {32, 0.0}, {-21, 1.0}, {   78, 0.0}};
      Cmplx  D[] = {{23, 0.0}, {  5, 0.0}, {-14, 0.0}, {32, 0.0}, {-21, 0.0}, {   78, 0.0}};
      double angle;
      Cmplx  **matrix;
      Cmplx  vector[6], differenceVector[6];
      Cmplx  *coordList[4];
      int    d;
      double realVector[3], tolerance;
      Cmplx  dotProductResult;
      Cmplx  value;
      
      Stream_RedirectFile( stream, "testComplexVectorMathOperations.dat" );

      tolerance = STG_COMPLEXVECTOR_TOL;
      
      coordList[0] = A;
      coordList[1] = B;
      coordList[2] = C;
      coordList[3] = D;
      Journal_Printf( stream, "****************************\n");
      Journal_Printf(stream, "Vectors - A, B, C, and D\n");
      
      StGermain_PrintNamedComplexVector( stream, A, 6 );
      StGermain_PrintNamedComplexVector( stream, B, 6 );
      StGermain_PrintNamedComplexVector( stream, C, 6 );
      StGermain_PrintNamedComplexVector( stream, D, 6 );

      /* Check Rotation functions */
      Journal_Printf( stream, "\n****************************\n");

      StGermain_PrintNamedComplexVector( stream, i, 3 );
      StGermain_PrintNamedComplexVector( stream, j, 3 );
      StGermain_PrintNamedComplexVector( stream, k, 3 );
      
      angle = M_PI / 2.0;
      
      Journal_Printf(stream, "Axis Rotation\n");            
      StGermain_RotateCoordinateAxisComplex( k, I_AXIS, angle, vector ) ;
      Journal_Printf( stream, "K Rotated %g radians around I axis - \n", angle);
      Cmplx_Subtract(vector[0], j[0], differenceVector[0]);
      Cmplx_Subtract(vector[1], j[1], differenceVector[1]);
      Cmplx_Subtract(vector[2], j[2], differenceVector[2]);
      
      if ( (Cmplx_Modulus(differenceVector[0]) < tolerance) && (Cmplx_Modulus(differenceVector[1]) < tolerance) &&
          (Cmplx_Modulus(differenceVector[2]) < tolerance) ) {
         Journal_Printf( stream, "Answer within tolerance %g of expected result: ", tolerance);
         StGermain_PrintNamedComplexVector( stream, j, 3);
      }
      else {
         Journal_Printf( stream, "Answer not within tolerance %g of expected result: ", tolerance);
         StGermain_PrintNamedComplexVector( stream, j, 3);
      }
      
      Journal_Printf(stream, "Angle Rotation\n");      
      StGermain_RotateComplexVector(k, angle,0.0, 0.0, vector);
      Journal_Printf( stream, "K Rotated %g radians around I axis - \n", angle); 
      Cmplx_Subtract(vector[0], j[0], differenceVector[0]);
      Cmplx_Subtract(vector[1], j[1], differenceVector[1]);
      Cmplx_Subtract(vector[2], j[2], differenceVector[2]);
      
      if ( (Cmplx_Modulus(differenceVector[0]) < tolerance) && (Cmplx_Modulus(differenceVector[1]) < tolerance) &&
          (Cmplx_Modulus(differenceVector[2]) < tolerance) ) {
         Journal_Printf( stream, "Answer within tolerance %g of expected result: ", tolerance);
         StGermain_PrintNamedComplexVector( stream, j, 3);
      }
      else {
         Journal_Printf( stream, "Answer not within tolerance %g of expected result: ", tolerance);
         StGermain_PrintNamedComplexVector( stream, j, 3);
      }
      
      Journal_Printf(stream, "Axis Rotation\n");      
      StGermain_RotateCoordinateAxisComplex( i, J_AXIS, angle, vector );
      Journal_Printf( stream, "I Rotated %g radians around J axis - \n", angle); 
      Cmplx_Subtract(vector[0], k[0], differenceVector[0]);
      Cmplx_Subtract(vector[1], k[1], differenceVector[1]);
      Cmplx_Subtract(vector[2], k[2], differenceVector[2]);
      
      if ( (Cmplx_Modulus(differenceVector[0]) < tolerance) && (Cmplx_Modulus(differenceVector[1]) < tolerance) &&
          (Cmplx_Modulus(differenceVector[2]) < tolerance) ) {
         Journal_Printf( stream, "Answer within tolerance %g of expected result: ", tolerance);
         StGermain_PrintNamedComplexVector( stream, k, 3);
      }
      else {
         Journal_Printf( stream, "Answer not within tolerance %g of expected result: ", tolerance);
         StGermain_PrintNamedComplexVector( stream, k, 3);
      }
      
      Journal_Printf(stream, "Angle Rotation\n");
      StGermain_RotateComplexVector(i, 0.0, angle, 0.0, vector );
      Journal_Printf( stream, "I Rotated %g radians around J axis - \n", angle); 
      Cmplx_Subtract(vector[0], k[0], differenceVector[0]);
      Cmplx_Subtract(vector[1], k[1], differenceVector[1]);
      Cmplx_Subtract(vector[2], k[2], differenceVector[2]);
      
      if ( (Cmplx_Modulus(differenceVector[0]) < tolerance) && (Cmplx_Modulus(differenceVector[1]) < tolerance) &&
          (Cmplx_Modulus(differenceVector[2]) < tolerance) ) {
         Journal_Printf( stream, "Answer within tolerance %g of expected result: ", tolerance);
         StGermain_PrintNamedComplexVector( stream, k, 3);
      }
      else {
         Journal_Printf( stream, "Answer not within tolerance %g of expected result: ", tolerance);
         StGermain_PrintNamedComplexVector( stream, k, 3);
      }
      
      Journal_Printf(stream, "Axis Rotation\n");      
      StGermain_RotateCoordinateAxisComplex( j, K_AXIS, angle, vector );
      Journal_Printf( stream, "J Rotated %g radians around K axis - \n", angle); 
      Cmplx_Subtract(vector[0], i[0], differenceVector[0]);
      Cmplx_Subtract(vector[1], i[1], differenceVector[1]);
      Cmplx_Subtract(vector[2], i[2], differenceVector[2]);
      
      if ( (Cmplx_Modulus(differenceVector[0]) < tolerance) && (Cmplx_Modulus(differenceVector[1]) < tolerance) &&
          (Cmplx_Modulus(differenceVector[2]) < tolerance) ) {
         Journal_Printf( stream, "Answer within tolerance %g of expected result: ", tolerance);
         StGermain_PrintNamedComplexVector( stream, i, 3);
      }
      else {
         Journal_Printf( stream, "Answer not within tolerance %g of expected result: ", tolerance);
         StGermain_PrintNamedComplexVector( stream, i, 3);
      }

      Journal_Printf(stream, "Angle Rotation\n");
      StGermain_RotateComplexVector( j, 0.0, 0.0, angle, vector );
      Journal_Printf( stream, "J Rotated %g radians around K axis - \n", angle); 
      Cmplx_Subtract(vector[0], i[0], differenceVector[0]);
      Cmplx_Subtract(vector[1], i[1], differenceVector[1]);
      Cmplx_Subtract(vector[2], i[2], differenceVector[2]);
      
      if ( (Cmplx_Modulus(differenceVector[0]) < tolerance) && (Cmplx_Modulus(differenceVector[1]) < tolerance) &&
          (Cmplx_Modulus(differenceVector[2]) < tolerance) ) {
         Journal_Printf( stream, "Answer within tolerance %g of expected result: ", tolerance);
         StGermain_PrintNamedComplexVector( stream, i, 3);
      }
      else {
         Journal_Printf( stream, "Answer not within tolerance %g of expected result: ", tolerance);
         StGermain_PrintNamedComplexVector( stream, i, 3);
      }

      angle = M_PI / 4.0;

      StGermain_RotateComplexVector(i, 0.0, angle, angle, vector );
      Journal_Printf( stream, "I Rotated %g radians around J axis "
      "and %2g radians around K axis: \n", angle, angle);
      StGermain_PrintNamedComplexVector( stream, vector, 3 );

      StGermain_RotateComplexVector(j, angle, 0.0, angle, vector );
      Journal_Printf( stream, "J Rotated %g radians around I axis "
      "and %g radians around K axis: \n", angle, angle); 
      StGermain_PrintNamedComplexVector( stream, vector, 3 );

      StGermain_RotateComplexVector(k, angle, angle, 0.0, vector );
      Journal_Printf( stream, "K Rotated %g radians around I axis "
      "and %g radians around J axis: \n", angle, angle); 
      StGermain_PrintNamedComplexVector( stream, vector, 3 );

      /* Check addition function */
      Journal_Printf( stream, "\n****************************\n");
      Journal_Printf( stream, "vector = A + B\n");
      for ( d = 0 ; d <= 6 ; d++ ) {
         StGermain_ComplexVectorAddition( vector, A, B, d );
         StGermain_PrintNamedComplexVector( stream, vector, d );
      }

      /* Check subtraction function */
      Journal_Printf( stream, "\n****************************\n");
      Journal_Printf( stream, "vector = A - B\n");
      for ( d = 0 ; d <= 6 ; d++ ) {
         StGermain_ComplexVectorSubtraction( vector, A, B, d );
         StGermain_PrintNamedComplexVector( stream, vector, d );
      }
   
      /* Check Magnitude Function */
      Journal_Printf( stream, "\n****************************\n");
      Journal_Printf( stream, "Check Magnitude Function\n");
      for ( d = 0 ; d <= 6 ; d++ ) {
         Journal_Printf( stream, "dim = %d magnitude A = %2.3f\n", d, StGermain_ComplexVectorMagnitude( A, d ) );
         Journal_Printf( stream, "dim = %d magnitude B = %2.3f\n", d, StGermain_ComplexVectorMagnitude( B, d ) );
      }

      /* Check Dot Product */
      Journal_Printf( stream, "\n****************************\n");
      Journal_Printf( stream, "Check Dot Product Function\n");
      Journal_Printf( stream, "value = A . B \n");
      
      for (d = 0; d <=6; d++) {
      StGermain_ComplexVectorDotProduct(A, B, d, dotProductResult);         
      Journal_Printf( stream, "dim = %d dot product = %2.3f + %2.3f i\n",
         d, dotProductResult[0], dotProductResult[1] );
      }

      /* Check Cross Product */
      /* Tested against http://www.engplanet.com/redirect.html?3859 */
      Journal_Printf( stream, "\n****************************\n");
      Journal_Printf( stream, "Check Cross Product Function\n");
      Journal_Printf( stream, " A x B in 3-D\n");
      StGermain_ComplexVectorCrossProduct( vector, A, B );
      StGermain_PrintNamedComplexVector( stream, vector, 3 );

      /* Checking centroid function */
      Journal_Printf( stream, "\n****************************\n");
      Journal_Printf( stream, "Checking centroid function\n");
      for ( d = 0 ; d <= 6 ; d++ ) {
         StGermain_ComplexTriangleCentroid( vector, A, B, C, d );
         StGermain_PrintNamedComplexVector( stream, vector, d );
      }

      /* Check Normalisation Function */
      Journal_Printf( stream, "\n****************************\n");
      Journal_Printf( stream, "Check Normalisation Function\n");
      
      Journal_Printf( stream, "2-D\n\n");
      d = 2;
      StGermain_PrintNamedComplexVector( stream, A, d );
      StGermain_ComplexVectorNormalise( A, d );
      StGermain_PrintNamedComplexVector( stream, A, d);
      Journal_Printf( stream, "mag = %2.3f\n", StGermain_ComplexVectorMagnitude( A, d ) );

      Journal_Printf( stream, "3-D\n\n");
      d = 3;
      StGermain_PrintNamedComplexVector( stream, B, d );
      StGermain_ComplexVectorNormalise( B, d );
      StGermain_PrintNamedComplexVector( stream, B, d);
      Journal_Printf( stream, "mag = %2.3f\n", StGermain_ComplexVectorMagnitude( B, d ) );

      Journal_Printf( stream, "5-D\n\n");
      d = 5;
      StGermain_PrintNamedComplexVector( stream, C, d );
      StGermain_ComplexVectorNormalise( C, d );
      StGermain_PrintNamedComplexVector( stream, C, d);
      Journal_Printf( stream, "mag = %2.3f\n", StGermain_ComplexVectorMagnitude( C, d ) );

      Journal_Printf( stream, "\n****************************\n");
      Journal_Printf( stream, "Check StGermain_ComplexVectorCrossProductMagnitude\n");
      A[0][REAL_PART] = 1.0; A[0][IMAG_PART] = 1.0; 
      A[1][REAL_PART] = 2.0; A[1][IMAG_PART] = 0.0;
      A[2][REAL_PART] = 3.0; A[2][IMAG_PART] = 0.0;
      B[0][REAL_PART] = 4.0; B[0][IMAG_PART] = 0.0;
      B[1][REAL_PART] = 5.0; B[1][IMAG_PART] = 0.0;
      B[2][REAL_PART] = 6.0; B[2][IMAG_PART] = 3.0;
      StGermain_PrintNamedComplexVector( stream, A, 3);
      StGermain_PrintNamedComplexVector( stream, B, 3);
      
      StGermain_ComplexVectorCrossProductMagnitude(A, B, 2, value ) ;
      Journal_Printf( stream, "mag = %2.3g + %2.3g i (2D)\n", value[REAL_PART], value[IMAG_PART] );
      
      StGermain_ComplexVectorCrossProductMagnitude(A, B, 3, value ) ;
      Journal_Printf( stream, "mag = %2.3g + %2.3g i (3D)\n", value[REAL_PART], value[IMAG_PART] );

      Journal_Printf( stream, "\n****************************\n");
      Journal_Printf( stream, "Check StGermain_ComplexScalarTripleProduct \n");
      
      matrix = Memory_Alloc_2DArray( Cmplx, 3, 3, (Name)"matrix"  );
      
      matrix[0][0][REAL_PART] = 1.0;  matrix[0][0][IMAG_PART] = 1.0;
      matrix[0][1][REAL_PART] = 2.0;  matrix[0][1][IMAG_PART] = 0.0; 
      matrix[0][2][REAL_PART] = 3.0;  matrix[0][2][IMAG_PART] = 2.0;
      matrix[1][0][REAL_PART] = 4.0;  matrix[1][0][IMAG_PART] = 0.0;
      matrix[1][1][REAL_PART] = 5.0;  matrix[1][1][IMAG_PART] = 3.0; 
      matrix[1][2][REAL_PART] = 6.0;  matrix[1][2][IMAG_PART] = 0.0;
      matrix[2][0][REAL_PART] = 7.0;  matrix[2][0][IMAG_PART] = 1.0;
      matrix[2][1][REAL_PART] = 8.0;  matrix[2][1][IMAG_PART] = 0.0;
      matrix[2][2][REAL_PART] = 11.0; matrix[2][2][IMAG_PART] = 1.0;
      StGermain_PrintNamedComplexVector( stream, matrix[0], 3);
      StGermain_PrintNamedComplexVector( stream, matrix[1], 3);
      StGermain_PrintNamedComplexVector( stream, matrix[2], 3);

      StGermain_ComplexScalarTripleProduct( matrix[0], matrix[1], matrix[2], value );
      Journal_Printf( stream, "scalar triple product: ");
      Journal_PrintCmplx( stream, value );
      
      StGermain_ComplexScalarTripleProduct( matrix[2], matrix[0], matrix[1], value );
      Journal_Printf( stream, "scalar triple product: ");
      Journal_PrintCmplx( stream, value );
      StGermain_ComplexScalarTripleProduct( matrix[1], matrix[2], matrix[0], value );
      Journal_Printf( stream, "scalar triple product: ");
      Journal_PrintCmplx( stream, value );
      
      Journal_Printf( stream, "\n****************************\n");
      Journal_Printf( stream, "Check Vector_ToComplexVector function \n");
      
      realVector[0] = 1.0; realVector[1] = 2.0; realVector[2] = 3.0;
      
      StGermain_PrintNamedVector(stream, realVector, 3);
      Vector_ToComplexVector(realVector, 3, matrix[0]) ;
      StGermain_PrintNamedComplexVector( stream, matrix[0], 3);

      Journal_Printf( stream, "\n****************************\n");
      Journal_Printf( stream, "Check ComplexVector_ToVector function \n");   
      
      matrix[0][0][REAL_PART] = 5.0; matrix[0][0][IMAG_PART] = 0.0;
      matrix[0][1][REAL_PART] = 6.0; matrix[0][1][IMAG_PART] = 0.0; 
      matrix[0][2][REAL_PART] = 7.0; matrix[0][2][IMAG_PART] = 0.0;
      
      StGermain_PrintNamedComplexVector( stream, matrix[0], 3);
      ComplexVector_ToVector(matrix[0], 3, realVector) ;
      StGermain_PrintNamedVector(stream, realVector, 3);

      pcu_filename_expected( "testComplexVectorMathOperations.expected", expected_file );
      pcu_check_fileEq( "testComplexVectorMathOperations.dat", expected_file );
      remove( "testComplexVectorMathOperations.dat" );

      Memory_Free( matrix );
      Stream_CloseAndFreeFile( stream );
   }
}