GLAMERDOC++
Gravitational Lensing Code Library
point.h
1 /*
2  * point.h
3  *
4  * Created on: Nov 15, 2010
5  * Author: bmetcalf
6  *
7  * Defines Point and Branch type.
8  *
9  * The Branch type needs to be defined here so that point.leaf can be defined.
10  */
11 
12 
13 #ifndef pointtypes_declare
14 #define pointtypes_declare
15 #include <complex>
16 #include <standard.h>
17 #include "Kist.h"
18 
19 #ifndef PI
20 #define PI 3.141593
21 #endif
22 
23 #ifndef error_message
24 #define error_message
25 #define ERROR_MESSAGE() std::cout << "ERROR: file: " << __FILE__ << " line: " << __LINE__ << std::endl;
26 #endif
27 
28 #ifndef boo_declare
29 #define boo_declare
30 typedef enum {NO, YES, MAYBE} Boo;
31 #endif
32 
33 
35 enum class CritType {ND=0,radial=2,tangential=1,pseudo=3,};
36 
37 //std::string to_string(const CritType &p);
38 std::ostream &operator<<(std::ostream &os, CritType const &p);
39 
41 template <typename T>
42 int sign(T val){return (T(0) < val) - (val < T(0));}
43 
48 struct Point_2d{
49  Point_2d(){
50  x[0]=x[1]=0.0;
51  }
52  Point_2d(double x1,double x2){
53  x[0]=x1;
54  x[1]=x2;
55  }
56 
57  ~Point_2d(){};
58 
59  Point_2d(const Point_2d &p){
60  x[0]=p.x[0];
61  x[1]=p.x[1];
62  }
63  Point_2d & operator=(const Point_2d &p){
64  if(this == &p) return *this;
65  x[0]=p.x[0];
66  x[1]=p.x[1];
67  return *this;
68  }
69  Point_2d(const PosType *p){
70  x[0]=p[0];
71  x[1]=p[1];
72  }
73 
74 
75  bool operator==(const Point_2d &p) const{
76  return (x[0] == p.x[0])*(x[1] == p.x[1]);
77  }
78  bool operator!=(const Point_2d &p) const{
79  return (x[0] != p.x[0]) || (x[1] != p.x[1]);
80  }
81 
82  Point_2d operator+(const Point_2d &p) const{
83  Point_2d tmp;
84  tmp.x[0] = x[0] + p.x[0];
85  tmp.x[1] = x[1] + p.x[1];
86  return tmp;
87  }
88  Point_2d operator-(const Point_2d &p) const{
89  Point_2d tmp;
90  tmp.x[0] = x[0] - p.x[0];
91  tmp.x[1] = x[1] - p.x[1];
92  return tmp;
93  }
94  Point_2d & operator+=(const Point_2d &p){
95  x[0]+=p.x[0];
96  x[1]+=p.x[1];
97  return *this;
98  }
99  Point_2d & operator-=(const Point_2d &p){
100  x[0]-=p.x[0];
101  x[1]-=p.x[1];
102  return *this;
103  }
104  Point_2d & operator/=(PosType value){
105  x[0]/=value;
106  x[1]/=value;
107  return *this;
108  }
109  Point_2d operator/(PosType value) const{
110  Point_2d tmp;
111  tmp[0] = x[0]/value;
112  tmp[1] = x[1]/value;
113  return tmp;
114  }
115  Point_2d & operator*=(PosType value){
116  x[0]*=value;
117  x[1]*=value;
118  return *this;
119  }
120  Point_2d operator*(PosType value) const{
121  return Point_2d(x[0]*value,x[1]*value);
122  }
123 
125  PosType operator*(const Point_2d &p) const{
126  return x[0]*p.x[0] + x[1]*p.x[1];
127  }
129  PosType operator^(const Point_2d &p) const{
130  return x[0]*p.x[1] - x[1]*p.x[0];
131  }
132 
134  PosType length() const{
135  return sqrt(x[0]*x[0] + x[1]*x[1]);
136  }
137 
139  PosType length_sqr() const{
140  return x[0]*x[0] + x[1]*x[1];
141  }
142 
143  // rotates the point
144  void rotate(PosType theta){
145  PosType c = cos(theta),s = sin(theta);
146  PosType tmp = x[0];
147  x[0] = c*tmp - s*x[1];
148  x[1] = c*x[1] + s*tmp;
149  }
150 
152  Point_2d rotated(PosType theta) const{
153  Point_2d p;
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];
157 
158  return p;
159  }
160 
162  void unitize(){
163  PosType s = length();
164  x[0] /= s;
165  x[1] /= s;
166  }
167 
169  Point_2d unit() const {
170  PosType s = length();
171  return Point_2d(x[0]/s,x[1]/s);
172  }
173 
174 
175  // returns a pointer to the position
176  PosType* data(){return x;}
177 
178  // array of size 2 containing the position
179  PosType x[2];
180 
181  PosType & operator[](size_t i) {return x[i];}
182  const PosType & operator[](size_t i) const {return x[i];}
183 };
184 
185 
186 template <typename T>
187 struct Matrix2x2{
188 
189  Matrix2x2(){
190  }
191 
192  Matrix2x2(const Matrix2x2<T> &F){
193  a[0] = F.a[0];
194  a[1] = F.a[1];
195  a[2] = F.a[2];
196  a[3] = F.a[3];
197  }
198 
199  template <typename B>
200  Matrix2x2<T> operator=(const Matrix2x2<B> &F){
201  a[0] = F.a[0];
202  a[1] = F.a[1];
203  a[2] = F.a[2];
204  a[3] = F.a[3];
205 
206  return *this;
207  }
208 
209  bool operator==(const Matrix2x2<T> &F){
210 
211  return (a[0] == F.a[0]) * (a[1] == F.a[1]) * (a[2] == F.a[2]) * (a[3] == F.a[3]);
212  }
213 
214 
215  Matrix2x2<T> operator*=(T f){
216  a[0] *= f;
217  a[1] *= f;
218  a[2] *= f;
219  a[3] *= f;
220 
221  return *this;
222  }
223 
224  Matrix2x2<T> operator/=(T f){
225  a[0] /= f;
226  a[1] /= f;
227  a[2] /= f;
228  a[3] /= f;
229 
230  return *this;
231  }
232 
233  Matrix2x2<T> operator*(T f) const{
234  Matrix2x2<T> m = *this;
235  m *= f;
236  return m;
237  }
238 
239  Point_2d operator*(const Point_2d &v) const{
240  Point_2d v2;
241  v2[0] = a[0]*v[0] + a[1]*v[1];
242  v2[1] = a[2]*v[0] + a[3]*v[1];
243  return v2;
244  }
245 
246 
247  Matrix2x2<T> operator/(T f) const{
248  Matrix2x2<T> m = *this;
249  m /= f;
250 
251  return m;
252  }
253 
254  template <typename B>
255  Matrix2x2<T> operator*(const Matrix2x2<B> &F) const{
256  Matrix2x2<T> m;
257 
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];
262 
263  return m;
264  }
265 
266  template <typename B>
267  Matrix2x2<T> operator+=(const Matrix2x2<B> &F){
268  a[0] += F.a[0];
269  a[1] += F.a[1];
270  a[2] += F.a[2];
271  a[3] += F.a[3];
272 
273  return *this;
274  }
275 
276  template <typename B>
277  Matrix2x2<T> operator+(const Matrix2x2<B> &F) const{
278  Matrix2x2<T> m = *this;
279  m += F;
280 
281  return m;
282  }
283  template <typename B>
284  Matrix2x2<T> operator-=(const Matrix2x2<B> &F){
285  a[0] -= F.a[0];
286  a[1] -= F.a[1];
287  a[2] -= F.a[2];
288  a[3] -= F.a[3];
289 
290  return *this;
291  }
292 
293  template <typename B>
294  Matrix2x2<T> operator-(const Matrix2x2<B> &F)const{
295  Matrix2x2<T> m = *this;
296  m -= F;
297 
298  return m;
299  }
300 
302  T & operator()(int i,int j){
303  return a[ i + 2*j ];
304  }
305 
306  T operator()(int i,int j) const{
307  return a[ i + 2*j ];
308  }
309 
310  T & operator[](int i){
311  return a[i];
312  }
313 
314  const T & operator[](int i) const{
315  return a[i];
316  }
317 
318  T det() const{
319  return a[0]*a[3] - a[1]*a[2];
320  }
321 
322  Matrix2x2<T> inverse() const{
323  Matrix2x2<T> m;
324 
325  m.a[0] = a[3];
326  m.a[3] = a[0];
327  m.a[1] = -a[1];
328  m.a[2] = -a[2];
329 
330  m /= det();
331  return m;
332  }
333 
334  void invert(){
335 
336  std::swap(a[0],a[3]);
337  a[1] *= -1;
338  a[2] *= -1;
339 
340  *this /= det();
341  }
342 
343  T a[4];
344 
345  // make the matrix the identity
346  void setToI(){
347  a[0] = a[3] = 1;
348  a[1] = a[2] = 0;
349  }
350 
351  static Matrix2x2<T> I(){
352  Matrix2x2<T> m;
353  m.a[0] = m.a[3] = 1;
354  m.a[1] = m.a[2] = 0;
355  return m;
356  }
357 
358  static Matrix2x2<T> sig1(){
359  Matrix2x2<T> m;
360  m.a[0] = -1;
361  m.a[3] = 1;
362  m.a[1] = m.a[2] = 0;
363  return m;
364  }
365  static Matrix2x2<T> sig2(){
366  Matrix2x2<T> m;
367  m.a[0] = m.a[3] = 0;
368  m.a[1] = m.a[2] = -1;
369  return m;
370  }
371 
372  static Matrix2x2<T> sig3(){
373  Matrix2x2<T> m;
374  m.a[0] = m.a[3] = 0;
375  m.a[1] = 1;
376  m.a[2] = -1;
377  return m;
378  }
379 
380  T kappa() const {return 1-(a[0] + a[3])/2; }
381  // defined according to GLAMER II convention
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;}
385 
386  void set(T kappa,T gamma[3]){
387  a[0] = 1 - kappa + gamma[0];
388  a[3] = 1 - kappa - gamma[0];
389 
390  a[1] = gamma[1] - gamma[3];
391  a[2] = gamma[1] + gamma[3];
392  }
393 
394  void gamma(T *g) const{
395  g[0] = gamma1();
396  g[1] = gamma2();
397  g[2] = gamma3();
398  }
399 
400 
401  void print() const {
402  std::cout << std::endl;
403  std::cout << a[0] << " " << a[1] << std::endl;
404  std::cout << a[2] << " " << a[3] << std::endl;
405  }
406 
407  // this assumes that the eigenvalues are real
408  void eigenv(T lambda[]){
409  T m = (a[0] + a[3])/2;
410  T determinent = det();
411 
412  lambda[0] = m + sqrt( abs(m*m - determinent));
413  lambda[1] = m - sqrt( abs(m*m - determinent));
414  }
415 
416  // returns the eigenvectors in vec1 and vec2
417  // vec1 corresponds to lambda[0] and vec2 to lambda[1]
418  void eigen_vec(Point_2d &vec1,Point_2d &vec2,T lambdas[]){
419 
420  eigenv(lambdas);
421 
422  if(a[2] != 0.0){
423  vec1[0] = lambdas[0] - a[3];
424  vec1[1] = a[2];
425 
426  vec2[0] = lambdas[1] - a[3];
427  vec2[1] = a[2];
428 
429  vec1.unitize();
430  vec2.unitize();
431 
432  }else if(a[1] != 0.0){
433  vec1[0] = a[1];
434  vec1[1] = lambdas[0] - a[0];
435 
436  vec2[0] = a[1];
437  vec2[1] = lambdas[1] - a[0];
438 
439  vec1.unitize();
440  vec2.unitize();
441 
442  }else{
443  vec1[0] = 1.0;
444  vec1[1] = 0.0;
445 
446  vec2[0] = 0.0;
447  vec2[1] = 1.0;
448  }
449  }
450 };
451 
452 
453 //struct branchstruct;
454 struct Branch;
455 
456 
459 struct Point: public Point_2d{
460 
461  Point();
462  Point(const Point_2d &p);
463  Point(PosType x,PosType y);
464  Point *next=nullptr; // pointer to next point in linked list
465  Point *prev=nullptr;
466  Point *image=nullptr; // pointer to point on image or source plane
467  unsigned long id=0;
468  unsigned long head=0; // marks beginning of allocated array of points for easy deallocation
469  Boo in_image; // marks if point is in image
470 
471  PosType *ptr_y(){return image->x;}
472 
475  Point_2d::operator=(p);
476 
477  return *this;
478  }
479 
480  double dt; // time delay : double implies permanent precision independently from DOUBLE_PRECISION
481 
482  Matrix2x2<KappaType> A;
483 
484  KappaType invmag() const{
485  return A.det();
486  }
487  KappaType gamma1() const{
488  return A.gamma1();
489  }
490  KappaType gamma2() const{
491  return A.gamma2();
492  }
493  KappaType gamma3() const{
494  return A.gamma3();
495  }
496  KappaType kappa() const{
497  return A.kappa();
498  }
499 
501  double flux(){return surface_brightness * gridsize * gridsize;}
502 
503  double gridsize; // the size of the most refined grid the point is in
504  float surface_brightness; // the surface brightness at this points
505 
506 
507  Branch *leaf;
508  bool flag;
509 
510  void Print();
511 
512  static bool orderX(Point *p1,Point *p2){
513  return (p1->x[0] < p2->x[0]);
514  }
515  static bool orderXrev(Point *p1,Point *p2){
516  return (p1->x[0] > p2->x[0]);
517  }
518  static bool orderY(Point *p1,Point *p2){
519  return (p1->x[1] < p2->x[1]);
520  }
521  static bool orderYrev(Point *p1,Point *p2){
522  return (p1->x[1] > p2->x[1]);
523  }
524 
526  bool inverted(){
527  KappaType eigens[2];
528  A.eigenv(eigens);
529 
530  return (eigens[0] < 0)*(eigens[1] < 0);
531  }
532 };
533 
534 std::ostream &operator<<(std::ostream &os, Point const &p);
535 
540 struct LinkedPoint : public Point
541 {
542  LinkedPoint(){
543  image = &im;
544  im.image = this;
545  }
546 
547  Point_2d& y(){return im;}
548 private:
549  Point im;
550 };
551 
552 
555 struct RAY{
556  RAY(){
557 
558  dt = 0.0;
559  A = Matrix2x2<KappaType>::I();
560  z = -1;
561 
562  };
563 
564  RAY(const Point &p,double zs = -1){
565  x[0] = p.x[0];
566  x[1] = p.x[1];
567  y[0] = p.image->x[0];
568  y[1] = p.image->x[1];
569 
570  dt = p.dt;
571 
572  A = p.A;
573  z = zs;
574  };
575  RAY(const LinkedPoint &p,double zs = -1){
576  x[0] = p.x[0];
577  x[1] = p.x[1];
578  y[0] = p.image->x[0];
579  y[1] = p.image->x[1];
580 
581  dt = p.dt;
582 
583  A = p.A;
584  z = zs;
585  };
586 
587  RAY(const RAY &p){
588  x = p.x;
589  y = p.y;
590 
591  dt = p.dt;
592 
593  A = p.A;
594  z = p.z;
595  };
596 
597  RAY & operator=(const Point &p){
598  assert(p.image != nullptr);
599 
600  x[0] = p.x[0];
601  x[1] = p.x[1];
602  y[0] = p.image->x[0];
603  y[1] = p.image->x[1];
604 
605  dt = p.dt;
606 
607  A = p.A;
608  z = -1;
609 
610  return *this;
611  };
612 
613  RAY & operator=(const RAY &p){
614  x = p.x;
615  y = p.y;
616 
617  dt = p.dt;
618 
619  A = p.A;
620  z = p.z;
621 
622  return *this;
623  };
624 
625  ~RAY(){};
626 
631  PosType *ptr_y(){return y.x;}
632 
633  Matrix2x2<KappaType> A;
634 
636  KappaType dt;
637  KappaType z;
638 
640  KappaType invmag() const{
641  return A.det();
642  }
643  KappaType gamma1() const{
644  return A.gamma1();
645  }
646  KappaType gamma2() const{
647  return A.gamma2();
648  }
649  KappaType gamma3() const{
650  return A.gamma3();
651  }
652  KappaType kappa() const{
653  return A.kappa();
654  }
655 
657  Point_2d alpha() const {return x - y;}
658 };
659 
660 std::ostream &operator<<(std::ostream &os, Point_2d const &p);
661 
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);
668 
669 //inline std::string to_string(RAY &r) {
670 // std::string s = "[" + std::to_string(r.x[0]) + "," + r.x[1] + ",[" + r.y[0] + "," + r.y[1]
671 // + "]," + r.z + "," + r.kappa() + ",[" + r.gamma1() + "," + r.gamma2() + "," + r.gamma3() + "]," << r.dt;
672 // return s;
673 //}
674 std::ostream &operator<<(std::ostream &os, RAY const &r);
675 
677 struct Branch{
678  Branch(Point *my_points,unsigned long my_npoints
679  ,double my_boundary_p1[2],double my_boundary_p2[2]
680  ,double my_center[2],int my_level);
681  ~Branch();
682 
683  struct Point *points;
684 
685  unsigned long npoints;
686  double center[2];
687  int level;
688  unsigned long number;
689  double boundary_p1[2];
690  double boundary_p2[2];
691  Branch *child1;
692  Branch *child2;
693  Branch *brother;
694  Branch *prev;
696  bool refined;
697 
698  void print();
699 
700  PosType area(){return (boundary_p2[0]-boundary_p1[0])*(boundary_p2[1]-boundary_p1[1]);}
701 
702  std::list<Branch *> neighbors;
703 private:
704  static unsigned long countID;
705 
706  // make a Branch uncopyable
707  Branch(const Branch &p);
708  Branch &operator=(Branch &p);
709  Branch &operator=(const Branch &p);
710 
711 } ;
712 
713 //typedef struct branchstruct Branch;
714 
718 template<typename T>
719 struct MemmoryBank{
720 
721  MemmoryBank():count(0){};
722  MemmoryBank(MemmoryBank &&membank){
723  *this = std::move(membank);
724  }
725  void operator=(MemmoryBank &&membank){
726  bank = std::move(membank.bank);
727  }
728 
729 
730  T * operator()(size_t N){
731  if(N <= 0) return nullptr;
732 
733  bank.emplace_back(new T[N]);
734  count += N;
735  return bank.back().get();
736  }
737 
738  // clear all data
739  void clear(){
740  bank.clear();
741  count = 0;
742  }
743 
744  // clear specific array, does not decrement count
745  bool clear(T *ptr){
746  for(auto &p : bank){
747  if(p.get() == ptr){
748  p.swap(bank.back());
749  bank.pop_back();
750  return true;
751  }
752  }
753  return false;
754  }
755 
756  size_t number_of_blocks(){return bank.size();}
757 
758 private:
759 
760  MemmoryBank(const MemmoryBank<T> &b);
761  MemmoryBank<T> & operator=(const MemmoryBank<T> &b);
762 
763  size_t count;
764  std::vector<std::unique_ptr<T[]> > bank;
765 };
766 
767 // A class that onlt counts iteslf for testing
768 //struct DummyClass{
769 // DummyClass(){
770 // N = count;
771 // ++count;
772 // };
773 // ~DummyClass(){
774 // std::cout << "delete " << N << std::endl;
775 // }
776 // int N;
777 // static int count;
778 //};
779 
780 //int DummyClass::count = 0;
781 //{ test lines for MemmoryBank
782 // MemmoryBank<DummyClass> pointbang;
783 //
784 // DummyClass *p = pointbang(10);
785 // p[7].N = 2;
786 // for(int i=0 ; i<10 ; ++i){
787 // cout << p[i].N << endl;
788 // }
789 //
790 // DummyClass *p2 = pointbang(5);
791 // for(int i=0 ; i<5 ; ++i){
792 // cout << p2[i].N << endl;
793 // }
794 //
795 // pointbang.clear(p2);
796 //
797 // DummyClass *p3 = pointbang(10);
798 //}
799 
804 struct PointList{
805  PointList(){
806  top=NULL;
807  Npoints=0;
808  bottom = top;
809  }
810  ~PointList(){}
811 
812  struct iterator{
813 
814  Point *current;
815 
816  iterator():current(NULL){ }
817 
818  iterator(Point *p){
819  current = p;
820  }
821 
822  Point *operator*(){return current;}
823 
824  bool operator++(){
825  assert(current);
826  if(current->prev == NULL) return false;
827  current=current->prev;
828  return true;
829  }
830 
832  bool operator++(int){
833  assert(current);
834  if(current->prev == NULL) return false;
835  current=current->prev;
836  return true;
837  }
838 
840  bool operator--(){
841  assert(current);
842  if(current->next == NULL) return false;
843  current=current->next;
844  return true;
845  }
846 
848  bool operator--(int){
849  assert(current);
850  if(current->next == NULL) return false;
851  current=current->next;
852  return true;
853  }
854 
855  void JumpDownList(int jump){
856  int i;
857 
858  if(jump > 0) for(i=0;i<jump;++i) --(*this);
859  if(jump < 0) for(i=0;i<abs(jump);++i) ++(*this);
860  }
861 
862 
863  bool operator==(const iterator my_it){
864  return (current == my_it.current);
865  }
866 
867  bool operator!=(const iterator my_it){
868  return (current != my_it.current);
869  }
870 
871  };
872 
873  unsigned long size() const {return Npoints;}
874 
875  inline bool IsTop(PointList::iterator &it) const{
876  return *it == top;
877  };
878  inline bool IsBottom(PointList::iterator &it) const{
879  return *it == bottom;
880  };
881 
882  Point *Top() const {return top;}
883  Point *Bottom() const {return bottom;}
884 
885  void EmptyList();
886  //void InsertAfterCurrent(iterator &current,double *x,unsigned long id,Point *image);
887  //void InsertBeforeCurrent(iterator &current,double *x,unsigned long id,Point *image);
888  void InsertPointAfterCurrent(iterator &current,Point *);
889  void InsertPointBeforeCurrent(iterator &current,Point *);
890 
891  void MoveCurrentToBottom(iterator &current);
892  Point *TakeOutCurrent(iterator &current);
893 
894  void InsertListAfterCurrent(iterator &current,PointList *list2);
895  void InsertListBeforeCurrent(iterator &current,PointList *list2);
896  void MergeLists(PointList* list2);
897  void ShiftList(iterator &current);
898 
899  //void FillList(double **x,unsigned long N
900  // ,unsigned long idmin);
901  void PrintList();
902 
903  void setN(unsigned long N){Npoints = N;}
904  void setTop(Point *p){top = p;}
905  void setBottom(Point *p){bottom = p;}
906 
907 private:
908  Point *top;
909  Point *bottom;
910  unsigned long Npoints;
911 
912  // make a point uncopyable
913  PointList &operator=(const PointList &p);
914 };
915 
916 typedef struct PointList *ListHndl;
917 
918 
919 // ***********************************************************
920 // routines for linked list of points
921 // ************************************************************
922 
923 //Point *NewPoint(double *x,unsigned long id);
924 
925 void SwapPointsInList(ListHndl list,Point *p1,Point *p2);
926 Point *sortList(long n, double arr[],ListHndl list,Point *firstpoint);
927 
931 template <typename T = PosType>
932 struct Point_3d{
933  Point_3d(){
934  x[0]=x[1]=x[2]=0.0;
935  }
936  Point_3d(T xx,T yy,T zz){
937  x[0]=xx;
938  x[1]=yy;
939  x[2]=zz;
940  }
941  ~Point_3d(){};
942 
943  Point_3d(const Point_3d &p){
944  x[0]=p.x[0];
945  x[1]=p.x[1];
946  x[2]=p.x[2];
947  }
948 
949  Point_3d & operator=(const Point_3d &p){
950  if(this == &p) return *this;
951  x[0]=p.x[0];
952  x[1]=p.x[1];
953  x[2]=p.x[2];
954  return *this;
955  }
956  Point_3d operator+(const Point_3d &p) const{
957  Point_3d tmp;
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];
961  return tmp;
962  }
963  Point_3d operator-(const Point_3d &p) const{
964  Point_3d tmp;
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];
968  return tmp;
969  }
970  Point_3d & operator+=(const Point_3d &p){
971  x[0]+=p.x[0];
972  x[1]+=p.x[1];
973  x[2]+=p.x[2];
974  return *this;
975  }
976  Point_3d & operator-=(const Point_3d &p){
977  x[0]-=p.x[0];
978  x[1]-=p.x[1];
979  x[2]-=p.x[2];
980  return *this;
981  }
982  Point_3d & operator/=(T value){
983  x[0]/=value;
984  x[1]/=value;
985  x[2]/=value;
986  return *this;
987  }
988  Point_3d operator/(T value) const{
989  Point_3d tmp;
990  tmp[0] = x[0]/value;
991  tmp[1] = x[1]/value;
992  tmp[2] = x[2]/value;
993 
994  return tmp;
995  }
996  Point_3d & operator*=(T value){
997  x[0] *=value;
998  x[1] *=value;
999  x[2] *=value;
1000  return *this;
1001  }
1002  Point_3d operator*(PosType value) const{
1003  Point_3d tmp;
1004  tmp[0] = x[0]*value;
1005  tmp[1] = x[1]*value;
1006  tmp[2] = x[2]*value;
1007 
1008  return tmp;
1009  }
1010 
1012  T operator*(const Point_3d &p) const {
1013  return x[0]*p.x[0] + x[1]*p.x[1] + x[2]*p.x[2];
1014  }
1015 
1018  Point_3d<T> v;
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];
1022  return v;
1023  }
1024 
1026  T length() const{
1027  return sqrt(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]);
1028  }
1029 
1030  T length_sqr() const{
1031  return x[0]*x[0] + x[1]*x[1] + x[2]*x[2];
1032  }
1033 
1035  void rotate(T theta,T phi){
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];
1039 
1040  c = cos(phi);
1041  s = sin(phi);;
1042  x[0] = c*tmp - s*x[2];
1043  x[2] = c*x[2] + s*tmp;
1044  }
1045 
1047  void unitize(){
1048  T s = length();
1049  x[0] /= s;
1050  x[1] /= s;
1051  x[2] /= s;
1052  }
1053 
1054  Point_3d<T> unit() const {
1055  PosType s = length();
1056  return Point_3d<T>(x[0]/s,x[1]/s,x[2]/s);
1057  }
1058 
1061  double s = sqrt(x[0]*x[0] + x[1]*x[1]);
1062  return Point_3d<T>(-x[1],x[0],0) / s;
1063  }
1064 
1068  Point_3d<T> v(-x[0]*x[2],-x[1]*x[2] ,x[0]*x[0] + x[1]*x[1]);
1069  v.unitize();
1070  return v;
1071  }
1072 
1073  T* data(){return x;}
1074 
1075  T x[3];
1076  T & operator[](size_t i){return x[i];}
1077  const T & operator[](size_t i) const {return x[i];}
1078 };
1079 
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];
1083 }
1084 
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;
1090 }
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);
1096  }
1097 
1098  // Skip header line
1099  std::string line;
1100  std::getline(file, line);
1101 
1102  // Read data lines
1103  while (std::getline(file, line)) {
1104  std::stringstream ss(line);
1105  std::string value;
1106  Point_3d<T> p;
1107 
1108  // Parse x,y,z values
1109  for (int i = 0; i < 3; i++) {
1110  if (!std::getline(ss, value, ',')) {
1111  throw std::runtime_error("Invalid CSV format");
1112  }
1113  p[i] = std::stod(value);
1114  }
1115 
1116  v.push_back(p);
1117  }
1118 }
1119 
1120 
1121 
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");
1127  }
1128  int n=x.size();
1129  file << "x,y" << std::endl;
1130  for(int i=0 ; i<n ; ++i){
1131  file << x[i] << "," << y[i] << std::endl;
1132  }
1133 }
1134 
1135 inline double pointx(Point &p){return p.x[0];}
1136 inline double pointy(Point &p){return p.x[1];}
1137 
1138 /*
1139 template <typename T>
1140 struct LISTiterator{
1141 
1142  std::list<T>::iterator current_it;
1143 
1144  LISTiterator(){ }
1145 
1146  T& operator*(){return *current_it;}
1147 
1148  bool operator++(){
1149  if(current_it == )
1150  --current_it;
1151 
1152  assert(current);
1153  if(current->prev == NULL) return false;
1154  current=current->prev;
1155  return true;
1156  }
1157 
1159  bool operator++(int){
1160  assert(current);
1161  if(current->prev == NULL) return false;
1162  current=current->prev;
1163  return true;
1164  }
1165 
1167  bool operator--(){
1168  assert(current);
1169  if(current->next == NULL) return false;
1170  current=current->next;
1171  return true;
1172  }
1173 
1175  bool operator--(int){
1176  assert(current);
1177  if(current->next == NULL) return false;
1178  current=current->next;
1179  return true;
1180  }
1181 
1182  void JumpDownList(int jump){
1183  int i;
1184 
1185  if(jump > 0) for(i=0;i<jump;++i) --(*this);
1186  if(jump < 0) for(i=0;i<abs(jump);++i) ++(*this);
1187  }
1188 
1189 
1190  bool operator==(const iterator my_it){
1191  return (current == my_it.current);
1192  }
1193 
1194  bool operator!=(const iterator my_it){
1195  return (current != my_it.current);
1196  }
1197 };
1198 
1199 
1200 template <typename T>
1201 struct LIST
1202 {
1203  LIST(){
1204  }
1205  ~LIST(){EmptyList();}
1206 
1207  std::list<T> list;
1208 
1209  LISTiterator<T> top(){
1210  iterator it;
1211  it.current_it = list.begin();
1212  return it;
1213  }
1214 
1215  LISTiterator<T> bottom(){
1216  iterator it;
1217  it.current_it = list.end();
1218  return it;
1219  }
1220 
1221  unsigned long size() const {return list.size();}
1222 
1223  inline bool IsTop(LISTiterator<T> &it) const{
1224  return it.current_it == list.begin();
1225  };
1226  inline bool IsBottom(LIST::iterator &it) const{
1227  return it.current_it == list.end();
1228  };
1229 
1230  T *Top() const {return list.front();}
1231  T *Bottom() const {return list.back();}
1232 
1233  void EmptyList(){list.clear();}
1234 
1235  void InsertAfterCurrent(LISTiterator<T> &it,T &d){
1236  list.insert(it.current_it+1,d);
1237  }
1238  void InsertBeforeCurrent(LISTiterator<T> &it,T &d){
1239  list.insert(it.current_it,d);
1240  }
1241 
1242  void MoveCurrentToBottom(iterator &current);
1243  Point *TakeOutCurrent(iterator &current);
1244 
1245  void InsertListAfterCurrent(iterator &current,PointList *list2);
1246  void InsertListBeforeCurrent(iterator &current,PointList *list2);
1247  void MergeLists(PointList* list2);
1248  void ShiftList(iterator &current);
1249 
1250  void PrintList();
1251 
1252  //void setN(unsigned long N){Npoints = N;}
1253  //void setTop(Point *p){top = p;}
1254  //void setBottom(Point *p){bottom = p;}
1255 
1256 private:
1257  //Point *top;
1258  //Point *bottom;
1259  //unsigned long Npoints;
1260 
1261  // make a point uncopyable
1262  LIST &operator=(const LIST &p);
1263 }
1264  */
1265 
1270 template <typename T = PosType>
1271 struct Point_nd{
1272  Point_nd():dim(0){ }
1273  Point_nd(int d):x(d,0),dim(d){ }
1274 
1275  void setD(int d){
1276  dim=d;
1277  x.resize(dim);
1278  }
1279 
1280  ~Point_nd(){};
1281 
1282  Point_nd(const Point_nd &p){
1283  for(int i=0 ; i<dim ; ++i ) x[i] = p.x[i];
1284  }
1285 
1286  Point_nd<T> & operator=(const Point_nd<T> &p){
1287  if(this == &p) return *this;
1288  for(int i=0 ; i<dim ; ++i ) x[i] = p.x[i];
1289  return *this;
1290  }
1291  Point_nd<T> operator+(const Point_nd<T> &p) const{
1292  Point_nd<T> tmp(dim);
1293  for(int i=0 ; i<dim ; ++i ) tmp.x[i] = x[i] + p.x[i];
1294  return tmp;
1295  }
1296  Point_nd<T> operator-(const Point_nd<T> &p) const{
1297  Point_nd<T> tmp(dim);
1298  for(int i=0 ; i<dim ; ++i ) tmp.x[i] = x[i] - p.x[i];
1299  return tmp;
1300  }
1301  Point_nd<T> & operator+=(const Point_nd<T> &p){
1302  for(int i=0 ; i<dim ; ++i ) x[i] += p.x[i];
1303  return *this;
1304  }
1305  Point_nd<T> & operator-=(const Point_nd<T> &p){
1306  for(int i=0 ; i<dim ; ++i ) x[i] -= p.x[i];
1307  return *this;
1308  }
1309  Point_nd<T> & operator/=(T value){
1310  for(int i=0 ; i<dim ; ++i ) x[i]/=value;
1311  return *this;
1312  }
1313  Point_nd<T> operator/(T value) const{
1314  Point_nd<T> tmp;
1315  for(int i=0 ; i<dim ; ++i ) tmp.x[i] = x[i]/value;
1316  return tmp;
1317  }
1318  Point_nd<T> & operator*=(T value){
1319  for(int i=0 ; i<dim ; ++i ) x[i] *=value;
1320  return *this;
1321  }
1322  Point_nd operator*(PosType value) const{
1323  Point_nd<T> tmp;
1324  for(int i=0 ; i<dim ; ++i ) tmp.x[i] = x[i]*value;
1325  return tmp;
1326  }
1327 
1329  T operator*(const Point_nd<T> &p) const {
1330  T ans = 0;
1331  for(int i=0 ; i<dim ; ++i ) ans += x[i]*p.x[i];
1332  return ans;
1333  }
1334 
1336  T length_sqr() const{
1337  T ans = 0;
1338  for(int i=0 ; i<dim ; ++i ) ans += x[i]*x[i];
1339  return ans;
1340  }
1341 
1342  T length() const{
1343  return sqrt(length_sqr());
1344  }
1345 
1346  T* data(){return x.data();}
1347 
1348  std::vector<T> x;
1349  T & operator[](size_t i){return x[i];}
1350  const T & operator[](size_t i) const {return x[i];}
1351 private:
1352  int dim;
1353 };
1354 
1355 #endif
Branch::npoints
unsigned long npoints
pointer to first points in Branch
Definition: point.h:685
Point_2d::rotated
Point_2d rotated(PosType theta) const
returns a copy of the point that it rotated
Definition: point.h:152
Point::flux
double flux()
surface_brightness * gridsize * gridsize
Definition: point.h:501
Point_3d::unitTheta
Point_3d< T > unitTheta()
Definition: point.h:1067
RAY::y
Point_2d y
source position
Definition: point.h:630
LinkedPoint
A point that automatically has an image point.
Definition: point.h:541
Branch
The box representing a branch of a binary tree structure. Used specifically in TreeStruct for organiz...
Definition: point.h:677
PointList
link list for points, uses the linking pointers within the Point type unlike Kist
Definition: point.h:804
Point_2d
Class for representing points or vectors in 2 dimensions. Not that the dereferencing operator is over...
Definition: point.h:48
RAY::alpha
Point_2d alpha() const
deflection angle, x-y
Definition: point.h:657
PointList::TakeOutCurrent
Point * TakeOutCurrent(iterator &current)
Definition: list.cpp:105
Point_3d::length
T length() const
length
Definition: point.h:1026
Branch::refined
bool refined
Marks point as start of a level of refinement.
Definition: point.h:696
RAY::dt
KappaType dt
time-delay
Definition: point.h:636
RAY::invmag
KappaType invmag() const
inverse of the magnification
Definition: point.h:640
Point::Point
Point()
Definition: Tree.cpp:63
standard.h
Point_nd
Definition: point.h:1271
Point_nd::operator*
T operator*(const Point_nd< T > &p) const
scalar product
Definition: point.h:1329
Point::operator=
Point operator=(const Point_2d &p)
Only copies position!!
Definition: point.h:474
Point_3d::rotate
void rotate(T theta, T phi)
a rotation theta around the z-axis followed by a rotation phi around the y-axis
Definition: point.h:1035
Point_2d::length
PosType length() const
length
Definition: point.h:134
RAY
Simple representaion of a light path giving position on the image and source planes and lensing quant...
Definition: point.h:555
Point_2d::length_sqr
PosType length_sqr() const
length^2
Definition: point.h:139
Point_3d::operator^
Point_3d< T > operator^(const Point_3d< T > &p) const
outer product
Definition: point.h:1017
Point::Print
void Print()
print out all member data for testing purposes
Definition: Tree.cpp:103
Point_3d::unitPhi
Point_3d< T > unitPhi()
returns the unit vector in the direction of the right handed spherical coordinate Phi
Definition: point.h:1060
Branch::print
void print()
print out all member data for testing purposes
Definition: Tree.cpp:168
Point_2d::operator*
PosType operator*(const Point_2d &p) const
scalar product
Definition: point.h:125
Point::inverted
bool inverted()
returns true if the image is double inverted, At very low magnification or when there is a rotation t...
Definition: point.h:526
Point_2d::operator^
PosType operator^(const Point_2d &p) const
outer product
Definition: point.h:129
Point_3d::operator*
T operator*(const Point_3d &p) const
scalar product
Definition: point.h:1012
Point_nd::length_sqr
T length_sqr() const
length
Definition: point.h:1336
Point_3d
Class for representing points or vectors in 3 dimensions. Not that the dereferencing operator is over...
Definition: point.h:932
Point
A point on the source or image plane that contains a position and the lensing quantities.
Definition: point.h:459
Point_2d::unitize
void unitize()
rescale to make a unit length vector
Definition: point.h:162
Point_2d::unit
Point_2d unit() const
rescale to make a unit length vector
Definition: point.h:169
RAY::x
Point_2d x
image position
Definition: point.h:625
MemmoryBank
Definition: point.h:719
Point_3d::unitize
void unitize()
rescale to make a unit length vector
Definition: point.h:1047