13 #ifndef pointtypes_declare
14 #define pointtypes_declare
25 #define ERROR_MESSAGE() std::cout << "ERROR: file: " << __FILE__ << " line: " << __LINE__ << std::endl;
30 typedef enum {NO, YES, MAYBE} Boo;
35 enum class CritType {ND=0,radial=2,tangential=1,pseudo=3,};
38 std::ostream &operator<<(std::ostream &os, CritType
const &p);
42 int sign(T val){
return (T(0) < val) - (val < T(0));}
64 if(
this == &p)
return *
this;
75 bool operator==(
const Point_2d &p)
const{
76 return (x[0] == p.x[0])*(x[1] == p.x[1]);
78 bool operator!=(
const Point_2d &p)
const{
79 return (x[0] != p.x[0]) || (x[1] != p.x[1]);
84 tmp.x[0] = x[0] + p.x[0];
85 tmp.x[1] = x[1] + p.x[1];
90 tmp.x[0] = x[0] - p.x[0];
91 tmp.x[1] = x[1] - p.x[1];
104 Point_2d & operator/=(PosType value){
109 Point_2d operator/(PosType value)
const{
115 Point_2d & operator*=(PosType value){
120 Point_2d operator*(PosType value)
const{
121 return Point_2d(x[0]*value,x[1]*value);
126 return x[0]*p.x[0] + x[1]*p.x[1];
130 return x[0]*p.x[1] - x[1]*p.x[0];
135 return sqrt(x[0]*x[0] + x[1]*x[1]);
140 return x[0]*x[0] + x[1]*x[1];
144 void rotate(PosType theta){
145 PosType c = cos(theta),s = sin(theta);
147 x[0] = c*tmp - s*x[1];
148 x[1] = c*x[1] + s*tmp;
154 PosType c = cos(theta),s = sin(theta);
155 p[0] = c*x[0] - s*x[1];
156 p[1] = c*x[1] + s*x[0];
176 PosType* data(){
return x;}
181 PosType & operator[](
size_t i) {
return x[i];}
182 const PosType & operator[](
size_t i)
const {
return x[i];}
186 template <
typename T>
192 Matrix2x2(
const Matrix2x2<T> &F){
199 template <
typename B>
200 Matrix2x2<T> operator=(
const Matrix2x2<B> &F){
209 bool operator==(
const Matrix2x2<T> &F){
211 return (a[0] == F.a[0]) * (a[1] == F.a[1]) * (a[2] == F.a[2]) * (a[3] == F.a[3]);
215 Matrix2x2<T> operator*=(T f){
224 Matrix2x2<T> operator/=(T f){
233 Matrix2x2<T> operator*(T f)
const{
234 Matrix2x2<T> m = *
this;
241 v2[0] = a[0]*v[0] + a[1]*v[1];
242 v2[1] = a[2]*v[0] + a[3]*v[1];
247 Matrix2x2<T> operator/(T f)
const{
248 Matrix2x2<T> m = *
this;
254 template <
typename B>
255 Matrix2x2<T> operator*(
const Matrix2x2<B> &F)
const{
258 m.a[0] = a[0] * F.a[0] + a[1] * F.a[2];
259 m.a[1] = a[0] * F.a[1] + a[1] * F.a[3];
260 m.a[2] = a[2] * F.a[0] + a[3] * F.a[2];
261 m.a[3] = a[2] * F.a[1] + a[3] * F.a[3];
266 template <
typename B>
267 Matrix2x2<T> operator+=(
const Matrix2x2<B> &F){
276 template <
typename B>
277 Matrix2x2<T> operator+(
const Matrix2x2<B> &F)
const{
278 Matrix2x2<T> m = *
this;
283 template <
typename B>
284 Matrix2x2<T> operator-=(
const Matrix2x2<B> &F){
293 template <
typename B>
294 Matrix2x2<T> operator-(
const Matrix2x2<B> &F)
const{
295 Matrix2x2<T> m = *
this;
302 T & operator()(
int i,
int j){
306 T operator()(
int i,
int j)
const{
310 T & operator[](
int i){
314 const T & operator[](
int i)
const{
319 return a[0]*a[3] - a[1]*a[2];
322 Matrix2x2<T> inverse()
const{
336 std::swap(a[0],a[3]);
351 static Matrix2x2<T> I(){
358 static Matrix2x2<T> sig1(){
365 static Matrix2x2<T> sig2(){
368 m.a[1] = m.a[2] = -1;
372 static Matrix2x2<T> sig3(){
380 T kappa()
const {
return 1-(a[0] + a[3])/2; }
382 T gamma1()
const{
return (a[0] - a[3])/2;}
383 T gamma2()
const{
return (a[1] + a[2])/2;}
384 T gamma3()
const{
return (a[2] - a[1])/2;}
386 void set(T kappa,T gamma[3]){
387 a[0] = 1 - kappa + gamma[0];
388 a[3] = 1 - kappa - gamma[0];
390 a[1] = gamma[1] - gamma[3];
391 a[2] = gamma[1] + gamma[3];
394 void gamma(T *g)
const{
402 std::cout << std::endl;
403 std::cout << a[0] <<
" " << a[1] << std::endl;
404 std::cout << a[2] <<
" " << a[3] << std::endl;
408 void eigenv(T lambda[]){
409 T m = (a[0] + a[3])/2;
410 T determinent = det();
412 lambda[0] = m + sqrt( abs(m*m - determinent));
413 lambda[1] = m - sqrt( abs(m*m - determinent));
423 vec1[0] = lambdas[0] - a[3];
426 vec2[0] = lambdas[1] - a[3];
432 }
else if(a[1] != 0.0){
434 vec1[1] = lambdas[0] - a[0];
437 vec2[1] = lambdas[1] - a[0];
463 Point(PosType x,PosType y);
466 Point *image=
nullptr;
468 unsigned long head=0;
471 PosType *ptr_y(){
return image->x;}
475 Point_2d::operator=(p);
482 Matrix2x2<KappaType> A;
484 KappaType invmag()
const{
487 KappaType gamma1()
const{
490 KappaType gamma2()
const{
493 KappaType gamma3()
const{
496 KappaType kappa()
const{
501 double flux(){
return surface_brightness * gridsize * gridsize;}
504 float surface_brightness;
513 return (p1->x[0] < p2->x[0]);
516 return (p1->x[0] > p2->x[0]);
519 return (p1->x[1] < p2->x[1]);
522 return (p1->x[1] > p2->x[1]);
530 return (eigens[0] < 0)*(eigens[1] < 0);
534 std::ostream &operator<<(std::ostream &os,
Point const &p);
559 A = Matrix2x2<KappaType>::I();
567 y[0] = p.image->x[0];
568 y[1] = p.image->x[1];
578 y[0] = p.image->x[0];
579 y[1] = p.image->x[1];
598 assert(p.image !=
nullptr);
602 y[0] = p.image->x[0];
603 y[1] = p.image->x[1];
613 RAY & operator=(
const RAY &p){
631 PosType *ptr_y(){
return y.x;}
633 Matrix2x2<KappaType> A;
643 KappaType gamma1()
const{
646 KappaType gamma2()
const{
649 KappaType gamma3()
const{
652 KappaType kappa()
const{
660 std::ostream &operator<<(std::ostream &os,
Point_2d const &p);
662 void write_csv(std::string filename,
const std::vector<Point_2d> &v);
663 void write_csv(std::string filename,
const std::vector<RAY> &v);
664 void write_csv(std::string filename,
const std::vector<float> &v);
665 void write_csv(std::string filename,
const std::vector<double> &v);
666 void write_csv(std::string filename,
const std::vector<int> &v);
667 void read_csv(std::string filename,std::vector<Point_2d> &v);
674 std::ostream &operator<<(std::ostream &os,
RAY const &r);
679 ,
double my_boundary_p1[2],
double my_boundary_p2[2]
680 ,
double my_center[2],
int my_level);
683 struct Point *points;
688 unsigned long number;
689 double boundary_p1[2];
690 double boundary_p2[2];
700 PosType area(){
return (boundary_p2[0]-boundary_p1[0])*(boundary_p2[1]-boundary_p1[1]);}
702 std::list<Branch *> neighbors;
704 static unsigned long countID;
723 *
this = std::move(membank);
726 bank = std::move(membank.bank);
730 T * operator()(
size_t N){
731 if(N <= 0)
return nullptr;
733 bank.emplace_back(
new T[N]);
735 return bank.back().get();
756 size_t number_of_blocks(){
return bank.size();}
764 std::vector<std::unique_ptr<T[]> > bank;
816 iterator():current(NULL){ }
822 Point *operator*(){
return current;}
826 if(current->prev == NULL)
return false;
827 current=current->prev;
832 bool operator++(
int){
834 if(current->prev == NULL)
return false;
835 current=current->prev;
842 if(current->next == NULL)
return false;
843 current=current->next;
848 bool operator--(
int){
850 if(current->next == NULL)
return false;
851 current=current->next;
855 void JumpDownList(
int jump){
858 if(jump > 0)
for(i=0;i<jump;++i) --(*
this);
859 if(jump < 0)
for(i=0;i<abs(jump);++i) ++(*
this);
863 bool operator==(
const iterator my_it){
864 return (current == my_it.current);
867 bool operator!=(
const iterator my_it){
868 return (current != my_it.current);
873 unsigned long size()
const {
return Npoints;}
875 inline bool IsTop(PointList::iterator &it)
const{
878 inline bool IsBottom(PointList::iterator &it)
const{
879 return *it == bottom;
882 Point *Top()
const {
return top;}
883 Point *Bottom()
const {
return bottom;}
888 void InsertPointAfterCurrent(iterator ¤t,
Point *);
889 void InsertPointBeforeCurrent(iterator ¤t,
Point *);
891 void MoveCurrentToBottom(iterator ¤t);
894 void InsertListAfterCurrent(iterator ¤t,
PointList *list2);
895 void InsertListBeforeCurrent(iterator ¤t,
PointList *list2);
897 void ShiftList(iterator ¤t);
903 void setN(
unsigned long N){Npoints = N;}
904 void setTop(
Point *p){top = p;}
905 void setBottom(
Point *p){bottom = p;}
910 unsigned long Npoints;
931 template <
typename T = PosType>
950 if(
this == &p)
return *
this;
958 tmp.x[0] = x[0] + p.x[0];
959 tmp.x[1] = x[1] + p.x[1];
960 tmp.x[2] = x[2] + p.x[2];
965 tmp.x[0] = x[0] - p.x[0];
966 tmp.x[1] = x[1] - p.x[1];
967 tmp.x[2] = x[2] - p.x[2];
1002 Point_3d operator*(PosType value)
const{
1004 tmp[0] = x[0]*value;
1005 tmp[1] = x[1]*value;
1006 tmp[2] = x[2]*value;
1013 return x[0]*p.x[0] + x[1]*p.x[1] + x[2]*p.x[2];
1019 v[0] = x[1]*p[2] - x[2]*p[1];
1020 v[1] = x[2]*p[0] - x[0]*p[2];
1021 v[2] = x[0]*p[1] - x[1]*p[0];
1027 return sqrt(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]);
1030 T length_sqr()
const{
1031 return x[0]*x[0] + x[1]*x[1] + x[2]*x[2];
1036 T c = cos(theta),s = sin(theta);
1037 T tmp = c*x[0] - s*x[1];
1038 x[1] = c*x[1] + s*x[0];
1042 x[0] = c*tmp - s*x[2];
1043 x[2] = c*x[2] + s*tmp;
1061 double s = sqrt(x[0]*x[0] + x[1]*x[1]);
1068 Point_3d<T> v(-x[0]*x[2],-x[1]*x[2] ,x[0]*x[0] + x[1]*x[1]);
1073 T* data(){
return x;}
1076 T & operator[](
size_t i){
return x[i];}
1077 const T & operator[](
size_t i)
const {
return x[i];}
1080 template <
typename T>
1081 std::ostream &operator<<(std::ostream &os,
Point_3d<T> const &p) {
1082 return os << p.x[0] <<
" " << p.x[1] <<
" " << p.x[2];
1085 template <
typename T>
1086 void write_csv(std::string filename,
const std::vector<
Point_3d<T> > &v){
1087 std::ofstream file(filename);
1088 file <<
"x,y,z" << std::endl;
1089 for(
const Point_3d<T> &p : v) file << p[0] <<
"," << p[1] <<
"," << p[2] << std::endl;
1091 template <
typename T>
1092 void read_csv(std::string filename, std::vector<
Point_3d<T>> &v) {
1093 std::ifstream file(filename);
1094 if (!file.is_open()) {
1095 throw std::runtime_error(
"Could not open file: " + filename);
1100 std::getline(file, line);
1103 while (std::getline(file, line)) {
1104 std::stringstream ss(line);
1109 for (
int i = 0; i < 3; i++) {
1110 if (!std::getline(ss, value,
',')) {
1111 throw std::runtime_error(
"Invalid CSV format");
1113 p[i] = std::stod(value);
1122 template <
typename T>
1123 void write_csv(std::string filename,
const std::vector<T> &x,
const std::vector<T> &y){
1124 std::ofstream file(filename);
1125 if(x.size() != y.size()){
1126 throw std::invalid_argument(
"mismatch");
1129 file <<
"x,y" << std::endl;
1130 for(
int i=0 ; i<n ; ++i){
1131 file << x[i] <<
"," << y[i] << std::endl;
1135 inline double pointx(
Point &p){
return p.x[0];}
1136 inline double pointy(
Point &p){
return p.x[1];}
1270 template <
typename T = PosType>
1283 for(
int i=0 ; i<dim ; ++i ) x[i] = p.x[i];
1287 if(
this == &p)
return *
this;
1288 for(
int i=0 ; i<dim ; ++i ) x[i] = p.x[i];
1293 for(
int i=0 ; i<dim ; ++i ) tmp.x[i] = x[i] + p.x[i];
1298 for(
int i=0 ; i<dim ; ++i ) tmp.x[i] = x[i] - p.x[i];
1302 for(
int i=0 ; i<dim ; ++i ) x[i] += p.x[i];
1306 for(
int i=0 ; i<dim ; ++i ) x[i] -= p.x[i];
1310 for(
int i=0 ; i<dim ; ++i ) x[i]/=value;
1315 for(
int i=0 ; i<dim ; ++i ) tmp.x[i] = x[i]/value;
1319 for(
int i=0 ; i<dim ; ++i ) x[i] *=value;
1322 Point_nd operator*(PosType value)
const{
1324 for(
int i=0 ; i<dim ; ++i ) tmp.x[i] = x[i]*value;
1331 for(
int i=0 ; i<dim ; ++i ) ans += x[i]*p.x[i];
1338 for(
int i=0 ; i<dim ; ++i ) ans += x[i]*x[i];
1346 T* data(){
return x.data();}
1349 T & operator[](
size_t i){
return x[i];}
1350 const T & operator[](
size_t i)
const {
return x[i];}