00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "UblasCustomFunctions.hpp"
00031
00032
00033 c_vector<double, 1> Create_c_vector(double x)
00034 {
00035 c_vector<double, 1> v;
00036 v[0] = x;
00037 return v;
00038 }
00039
00040 c_vector<double, 2> Create_c_vector(double x, double y)
00041 {
00042 c_vector<double, 2> v;
00043 v[0] = x;
00044 v[1] = y;
00045 return v;
00046 }
00047
00048 c_vector<double, 3> Create_c_vector(double x, double y, double z)
00049 {
00050 c_vector<double, 3> v;
00051 v[0] = x;
00052 v[1] = y;
00053 v[2] = z;
00054 return v;
00055 }
00056
00057 c_vector<double,3> CalculateEigenvectorForSmallestNonzeroEigenvalue(c_matrix<double, 3, 3>& rA)
00058 {
00059 int info;
00060 c_vector<double, 3> eigenvalues_real_part;
00061 c_vector<double, 3> eigenvalues_imaginary_part;
00062 c_vector<double, 4*3 > workspace;
00063 c_matrix<double, 3, 3> right_eigenvalues;
00064
00065 char dont_compute_left_evectors = 'N';
00066 char compute_right_evectors = 'V';
00067
00068 int matrix_size = 3;
00069 int matrix_ld = matrix_size;
00070 int workspace_size = 4*matrix_size;
00071
00072 c_matrix<double, 3, 3> a_transpose;
00073 noalias(a_transpose) = trans(rA);
00074
00075
00076 LAPACKgeev_(&dont_compute_left_evectors, &compute_right_evectors,
00077 &matrix_size, a_transpose.data(),&matrix_ld,
00078 eigenvalues_real_part.data(), eigenvalues_imaginary_part.data(),
00079 NULL, &matrix_ld,
00080 right_eigenvalues.data(),&matrix_ld,
00081 workspace.data(),&workspace_size,
00082 &info);
00083 assert(info==0);
00084
00085
00086 assert(norm_2(eigenvalues_imaginary_part) < DBL_EPSILON);
00087
00088 unsigned index_of_smallest=UINT_MAX;
00089 double min_eigenvalue = DBL_MAX;
00090
00091 for (unsigned i=0; i<3; i++)
00092 {
00093 double eigen_magnitude = fabs(eigenvalues_real_part(i));
00094 if (eigen_magnitude < min_eigenvalue && eigen_magnitude >= DBL_EPSILON)
00095 {
00096
00097 min_eigenvalue = eigen_magnitude;
00098 index_of_smallest = i;
00099 }
00100 }
00101 assert (min_eigenvalue != DBL_MAX);
00102 assert (index_of_smallest != UINT_MAX);
00103 assert (min_eigenvalue >= DBL_EPSILON);
00104
00105 c_vector<double, 3> output;
00106 output(0) = right_eigenvalues(index_of_smallest, 0);
00107 output(1) = right_eigenvalues(index_of_smallest, 1);
00108 output(2) = right_eigenvalues(index_of_smallest, 2);
00109
00110 return output;
00111 }
00112
00113 double SmallPow(double x, unsigned exponent)
00114 {
00115 switch (exponent)
00116 {
00117 case 0:
00118 {
00119 return 1.0;
00120 }
00121 case 1:
00122 {
00123 return x;
00124 }
00125 case 2:
00126 {
00127 return x*x;
00128 }
00129 case 3:
00130 {
00131 return x*x*x;
00132 }
00133 default:
00134 {
00135 if (exponent % 2 == 0)
00136 {
00137
00138 double partial_answer=SmallPow(x, exponent/2);
00139 return partial_answer*partial_answer;
00140 }
00141 else
00142 {
00143 return SmallPow(x, exponent-1)*x;
00144 }
00145 }
00146
00147 }
00148 }
00149
00150 bool Divides(double smallerNumber, double largerNumber)
00151 {
00152 double remainder=fmod(largerNumber, smallerNumber);
00153
00154
00155 if (remainder < DBL_EPSILON*largerNumber)
00156 {
00157 return true;
00158 }
00159
00160
00161 if (fabs(remainder-smallerNumber) < DBL_EPSILON*largerNumber)
00162 {
00163 return true;
00164 }
00165
00166 return false;
00167 }