00001
00005 #ifndef CIRCLE_PATTERN_CM
00006 #define CIRCLE_PATTERN_CM
00007 #define NOMINMAX
00008 #include <iostream>
00009 #define _USE_MATH_DEFINES
00010 #include <math.h>
00011
00012 class Mesh;
00013
00043 struct CirclePattern {
00044
00045 static double evaluateEnergy (Mesh * mesh, double * xx);
00046
00047 static void computeGradient (Mesh * mesh, double * xx, double * grad);
00048
00049 static void buildSparsityForHessian (Mesh * mesh, int * hessI, int * hessJ);
00050
00051 static void computeHessian (Mesh * mesh, double * xx, double * hessval);
00052
00053
00054 static double ImLi2Sum (const double& theta, const double& x,
00055 const double& tanHalfThetaStar, const double& clThetaStar);
00056
00058 static double Cl2 (const double & _x);
00059
00062 static double fTheta2(const double& cosTheta, const double& sinTheta, const double& x);
00063
00065 static double fThetaPrime2(const double & cosTheta, const double& sinTheta, const double & x) {
00066 double res = sinTheta/(cosh(x) - cosTheta);
00067 return res;
00068 }
00069
00071 static double IEEEremainder(const double & x, const double & div);
00072 };
00073
00074 inline double CirclePattern::fTheta2(const double& cosTheta, const double& sinTheta, const double& x){
00075 double ex = exp(x);
00076 double s1 = 1.0 - ex*cosTheta;
00077 double s2 = ex*sinTheta;
00078
00079 double res = M_PI - 2*atan2(s1, s2);
00080
00081 return res;
00082 }
00083
00084 inline double CirclePattern::IEEEremainder(const double & x, const double & div) {
00085
00086 double res;
00087 if (x >= 0) {
00088 if (x < div) res = x;
00089 else {
00090 double part = floor(x / div);
00091 res = x - part*div;
00092 }
00093 }
00094 else {
00095 double part = floor(x / div);
00096 res = x - part*div;
00097 }
00098 if (res < 0 || res > div) {
00099 std::cout << "x " << x << " div " << div << std::endl;
00100 std::cerr << "Wrong IEEEreminder!!!" << std::endl;
00101 }
00102 return res;
00103 }
00104
00105 inline double CirclePattern::Cl2 (const double & _x) {
00106 double TWO_PI = 2 * M_PI;
00107 double MINUS_LOG_2 = log(0.5);
00108 double BORDERLINE = 2.0944;
00109
00110 if (_x == 0.0) {
00111 return 0.0;
00112 }
00113
00114 double x = IEEEremainder(_x, TWO_PI);
00115
00116 if (x == 0.0) {
00117 return 0.0;
00118 }
00119
00120 if (fabs(x) <= BORDERLINE) {
00121 double xx = x * x;
00122 return ((((((((((((
00123 2.3257441143020875e-22 * xx
00124 + 1.0887357368300848e-20) * xx
00125 + 5.178258806090624e-19) * xx
00126 + 2.5105444608999545e-17) * xx
00127 + 1.2462059912950672e-15) * xx
00128 + 6.372636443183181e-14) * xx
00129 + 3.387301370953521e-12) * xx
00130 + 1.8978869988971e-10) * xx
00131 + 1.1482216343327455e-8) * xx
00132 + 7.873519778281683e-7) * xx
00133 + 0.00006944444444444444) * xx
00134 + 0.013888888888888888) * xx
00135 - log(fabs(x)) + 1.0) * x;
00136 }
00137 x += ((x > 0.0) ? - M_PI : M_PI);
00138 double xx = x * x;
00139 return ((((((((((((
00140 3.901950904063069e-15 * xx
00141 + 4.566487567193635e-14) * xx
00142 + 5.429792727596476e-13) * xx
00143 + 6.5812165661369675e-12) * xx
00144 + 8.167010963952222e-11) * xx
00145 + 1.0440290284867003e-9) * xx
00146 + 1.3870999114054669e-8) * xx
00147 + 1.941538399871733e-7) * xx
00148 + 2.927965167548501e-6) * xx
00149 + 0.0000496031746031746) * xx
00150 + 0.0010416666666666667) * xx
00151 + 0.041666666666666664) * xx
00152 + MINUS_LOG_2) * x;
00153 }
00154
00155 #endif
00156