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 < DBL_EPSILON)
00095 {
00096
00098 continue;
00099 }
00100 if (eigen_magnitude < min_eigenvalue)
00101 {
00102 min_eigenvalue = eigen_magnitude;
00103 index_of_smallest = i;
00104 }
00105 }
00106 assert (min_eigenvalue != DBL_MAX);
00107 assert (index_of_smallest != UINT_MAX);
00108 assert (min_eigenvalue >= DBL_EPSILON);
00109
00110 c_vector<double, 3> output;
00111 output(0) = right_eigenvalues(index_of_smallest, 0);
00112 output(1) = right_eigenvalues(index_of_smallest, 1);
00113 output(2) = right_eigenvalues(index_of_smallest, 2);
00114
00115 return output;
00116 }
00117
00118 double SmallPow(double x, unsigned exponent)
00119 {
00120 switch (exponent)
00121 {
00122 case 0:
00123 {
00124 return 1.0;
00125 }
00126 case 1:
00127 {
00128 return x;
00129 }
00130 case 2:
00131 {
00132 return x*x;
00133 }
00134 case 3:
00135 {
00136 return x*x*x;
00137 }
00138 default:
00139 {
00140 if (exponent % 2 == 0)
00141 {
00142
00143 double partial_answer=SmallPow(x, exponent/2);
00144 return partial_answer*partial_answer;
00145 }
00146 else
00147 {
00148 return SmallPow(x, exponent-1)*x;
00149 }
00150 }
00151
00152 }
00153 }
00154
00155 bool Divides(double smallerNumber, double largerNumber)
00156 {
00157 double remainder=fmod(largerNumber, smallerNumber);
00158
00159
00160 if (remainder < DBL_EPSILON*largerNumber)
00161 {
00162 return true;
00163 }
00164
00165
00166 if (fabs(remainder-smallerNumber) < DBL_EPSILON*largerNumber)
00167 {
00168 return true;
00169 }
00170
00171 return false;
00172 }