UblasCustomFunctions.cpp
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