mirror of
https://bitbucket.org/cosmicvoids/vide_public.git
synced 2025-07-08 01:01:11 +00:00
Imported healpix tree
This commit is contained in:
parent
4182c30485
commit
4bfb62f177
136 changed files with 26534 additions and 0 deletions
632
external/healpix/cxxsupport/arr.h
vendored
Normal file
632
external/healpix/cxxsupport/arr.h
vendored
Normal file
|
@ -0,0 +1,632 @@
|
|||
/*
|
||||
* This file is part of libcxxsupport.
|
||||
*
|
||||
* libcxxsupport is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libcxxsupport is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libcxxsupport; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*! \file arr.h
|
||||
* Various high-performance array classes used by the Planck LevelS package.
|
||||
*
|
||||
* Copyright (C) 2002 - 2010 Max-Planck-Society
|
||||
* \author Martin Reinecke
|
||||
*/
|
||||
|
||||
#ifndef PLANCK_ARR_H
|
||||
#define PLANCK_ARR_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include "cxxutils.h"
|
||||
|
||||
/*! \defgroup arraygroup Array classes */
|
||||
/*! \{ */
|
||||
|
||||
template <typename T> class normalAlloc__
|
||||
{
|
||||
public:
|
||||
T *alloc(tsize sz) const { return (sz>0) ? new T[sz] : 0; }
|
||||
void dealloc (T *ptr) const { delete[] ptr; }
|
||||
};
|
||||
|
||||
template <typename T, int align> class alignAlloc__
|
||||
{
|
||||
public:
|
||||
T *alloc(tsize sz) const
|
||||
{
|
||||
using namespace std;
|
||||
if (sz==0) return 0;
|
||||
void *res;
|
||||
planck_assert(posix_memalign(&res,align,sz*sizeof(T))==0,
|
||||
"error in posix_memalign()");
|
||||
return static_cast<T *>(res);
|
||||
}
|
||||
void dealloc(T *ptr) const
|
||||
{
|
||||
using namespace std;
|
||||
if (ptr) free(ptr);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*! View of a 1D array */
|
||||
template <typename T> class arr_ref
|
||||
{
|
||||
protected:
|
||||
tsize s;
|
||||
T *d;
|
||||
|
||||
public:
|
||||
/*! Constructs an \a arr_ref of size \a s_, starting at \a d_. */
|
||||
arr_ref(T *d_, tsize s_) : s(s_),d(d_) {}
|
||||
|
||||
/*! Returns the current array size. */
|
||||
tsize size() const { return s; }
|
||||
|
||||
/*! Writes \a val into every element of the array. */
|
||||
void fill (const T &val)
|
||||
{ for (tsize m=0; m<s; ++m) d[m]=val; }
|
||||
|
||||
/*! Returns a reference to element \a n */
|
||||
template<typename T2> T &operator[] (T2 n) {return d[n];}
|
||||
/*! Returns a constant reference to element \a n */
|
||||
template<typename T2> const T &operator[] (T2 n) const {return d[n];}
|
||||
|
||||
/*! Returns a pointer to the first array element, or NULL if the array
|
||||
is zero-sized. */
|
||||
T *begin() { return d; }
|
||||
/*! Returns a pointer to the one-past-last array element, or NULL if the
|
||||
array is zero-sized. */
|
||||
T *end() { return d+s; }
|
||||
/*! Returns a constant pointer to the first array element, or NULL if the
|
||||
array is zero-sized. */
|
||||
const T *begin() const { return d; }
|
||||
/*! Returns a constant pointer to the one-past-last array element, or NULL
|
||||
if the array is zero-sized. */
|
||||
const T *end() const { return d+s; }
|
||||
|
||||
/*! Copies all array elements to \a ptr. */
|
||||
template<typename T2> void copyToPtr (T *ptr) const
|
||||
{ for (tsize m=0; m<s; ++m) ptr[m]=d[m]; }
|
||||
|
||||
/*! Sorts the elements in the array, in ascending order. */
|
||||
void sort()
|
||||
{ std::sort (d,d+s); }
|
||||
|
||||
/*! Sorts the elements in the array, such that \a comp(d[i],d[j])==true
|
||||
for \a i<j. */
|
||||
template<typename Comp> void sort(Comp comp)
|
||||
{ std::sort (d,d+s,comp); }
|
||||
|
||||
/*! Helper function for linear interpolation (or extrapolation).
|
||||
\a idx and \a val are computed such that
|
||||
\a val=d[idx]+frac*(d[idx+1]-d[idx]). If \a val<d[0], \a frac will be
|
||||
negative, if \a val>d[s-1], frac will be larger than 1. In all other
|
||||
cases \a 0<=frac<=1.
|
||||
|
||||
The array must be ordered in ascending order; no two values may be
|
||||
equal. */
|
||||
void interpol_helper (const T &val, tsize &idx, double &frac) const
|
||||
{ ::interpol_helper (d, d+s, val, idx, frac); }
|
||||
|
||||
/*! Helper function for linear interpolation (or extrapolation).
|
||||
\a idx and \a val are computed such that
|
||||
\a val=d[idx]+frac*(d[idx+1]-d[idx]). If \a comp(val,d[0])==true,
|
||||
\a frac will be negative, if \a comp(val,d[s-1])==false, frac will be
|
||||
larger than 1. In all other cases \a 0<=frac<=1.
|
||||
|
||||
The array must be ordered such that \a comp(d[i],d[j])==true
|
||||
for \a i<j; no two values may be equal. */
|
||||
template<typename Comp> void interpol_helper (const T &val, Comp comp,
|
||||
tsize &idx, double &frac) const
|
||||
{ ::interpol_helper (d, d+s, val, comp, idx, frac); }
|
||||
|
||||
/*! Returns the minimum and maximum entry in \a minv and \a maxv,
|
||||
respectively. Throws an exception if the array is zero-sized. */
|
||||
void minmax (T &minv, T &maxv) const
|
||||
{
|
||||
planck_assert(s>0,"trying to find min and max of a zero-sized array");
|
||||
minv=maxv=d[0];
|
||||
for (tsize m=1; m<s; ++m)
|
||||
{
|
||||
if (d[m]<minv) minv=d[m];
|
||||
else if (d[m]>maxv) maxv=d[m];
|
||||
}
|
||||
}
|
||||
|
||||
/*! Returns \a true, if \a val is found in the array, else \a false. */
|
||||
bool contains (const T &val) const
|
||||
{
|
||||
for (tsize m=0; m<s; ++m)
|
||||
if (d[m]==val) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*! Returns the index of the first occurrence of \a val in the array.
|
||||
If it is not found, an exception is thrown. */
|
||||
tsize find (const T &val) const
|
||||
{
|
||||
for (tsize m=0; m<s; ++m)
|
||||
if (d[m]==val) return m;
|
||||
planck_fail ("entry '"+dataToString(val)+"' not found in array");
|
||||
}
|
||||
};
|
||||
|
||||
/*! An array whose size is known at compile time. Very useful for storing
|
||||
small arrays on the stack, without need for \a new and \a delete(). */
|
||||
template <typename T, tsize sz> class fix_arr
|
||||
{
|
||||
private:
|
||||
T d[sz];
|
||||
|
||||
public:
|
||||
/*! Returns the size of the array. */
|
||||
tsize size() const { return sz; }
|
||||
|
||||
/*! Returns a reference to element \a n */
|
||||
template<typename T2> T &operator[] (T2 n) {return d[n];}
|
||||
/*! Returns a constant reference to element \a n */
|
||||
template<typename T2> const T &operator[] (T2 n) const {return d[n];}
|
||||
};
|
||||
|
||||
|
||||
/*! One-dimensional array type, with selectable storage management. */
|
||||
template <typename T, typename storageManager> class arrT: public arr_ref<T>
|
||||
{
|
||||
private:
|
||||
storageManager stm;
|
||||
bool own;
|
||||
|
||||
void reset()
|
||||
{ this->d=0; this->s=0; own=true; }
|
||||
|
||||
public:
|
||||
/*! Creates a zero-sized array. */
|
||||
arrT() : arr_ref<T>(0,0), own(true) {}
|
||||
/*! Creates an array with \a sz entries. */
|
||||
arrT(tsize sz) : arr_ref<T>(stm.alloc(sz),sz), own(true) {}
|
||||
/*! Creates an array with \a sz entries, and initializes them with
|
||||
\a inival. */
|
||||
arrT(tsize sz, const T &inival) : arr_ref<T>(stm.alloc(sz),sz), own(true)
|
||||
{ arr_ref<T>::fill(inival); }
|
||||
/*! Creates an array with \a sz entries, which uses the memory pointed
|
||||
to by \a ptr.
|
||||
\note \a ptr will <i>not</i> be deallocated by the destructor.
|
||||
\warning Only use this if you REALLY know what you are doing.
|
||||
In particular, this is only safely usable if
|
||||
<ul>
|
||||
<li>\a T is a POD type</li>
|
||||
<li>\a ptr survives during the lifetime of the array object</li>
|
||||
<li>\a ptr is not subject to garbage collection</li>
|
||||
</ul>
|
||||
Other restrictions may apply. You have been warned. */
|
||||
arrT (T *ptr, tsize sz): arr_ref<T>(ptr,sz), own(false) {}
|
||||
/*! Creates an array which is a copy of \a orig. The data in \a orig
|
||||
is duplicated. */
|
||||
arrT (const arrT &orig): arr_ref<T>(stm.alloc(orig.s),orig.s), own(true)
|
||||
{ for (tsize m=0; m<this->s; ++m) this->d[m] = orig.d[m]; }
|
||||
/*! Frees the memory allocated by the object. */
|
||||
~arrT() { if (own) stm.dealloc(this->d); }
|
||||
|
||||
/*! Allocates space for \a sz elements. The content of the array is
|
||||
undefined on exit. \a sz can be 0. If \a sz is the
|
||||
same as the current size, no reallocation is performed. */
|
||||
void alloc (tsize sz)
|
||||
{
|
||||
if (sz==this->s) return;
|
||||
if (own) stm.dealloc(this->d);
|
||||
this->s = sz;
|
||||
this->d = stm.alloc(sz);
|
||||
own = true;
|
||||
}
|
||||
/*! Allocates space for \a sz elements. If \a sz is the
|
||||
same as the current size, no reallocation is performed.
|
||||
All elements are set to \a inival. */
|
||||
void allocAndFill (tsize sz, const T &inival)
|
||||
{ alloc(sz); this->fill(inival); }
|
||||
/*! Deallocates the memory held by the array, and sets the array size
|
||||
to 0. */
|
||||
void dealloc() {if (own) stm.dealloc(this->d); reset();}
|
||||
|
||||
/*! Changes the array to be a copy of \a orig. */
|
||||
arrT &operator= (const arrT &orig)
|
||||
{
|
||||
if (this==&orig) return *this;
|
||||
alloc (orig.s);
|
||||
for (tsize m=0; m<this->s; ++m) this->d[m] = orig.d[m];
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*! Reserves space for \a sz elements, then copies \a sz elements
|
||||
from \a ptr into the array. */
|
||||
template<typename T2> void copyFromPtr (const T2 *ptr, tsize sz)
|
||||
{
|
||||
alloc(sz);
|
||||
for (tsize m=0; m<this->s; ++m) this->d[m]=ptr[m];
|
||||
}
|
||||
|
||||
/*! Assigns the contents and size of \a other to the array.
|
||||
\note On exit, \a other is zero-sized! */
|
||||
void transfer (arrT &other)
|
||||
{
|
||||
if (own) stm.dealloc(this->d);
|
||||
this->d=other.d;
|
||||
this->s=other.s;
|
||||
own=other.own;
|
||||
other.reset();
|
||||
}
|
||||
/*! Swaps contents and size with \a other. */
|
||||
void swap (arrT &other)
|
||||
{
|
||||
std::swap(this->d,other.d);
|
||||
std::swap(this->s,other.s);
|
||||
std::swap(own,other.own);
|
||||
}
|
||||
};
|
||||
|
||||
/*! One-dimensional array type. */
|
||||
template <typename T>
|
||||
class arr: public arrT<T,normalAlloc__<T> >
|
||||
{
|
||||
public:
|
||||
/*! Creates a zero-sized array. */
|
||||
arr() : arrT<T,normalAlloc__<T> >() {}
|
||||
/*! Creates an array with \a sz entries. */
|
||||
arr(tsize sz) : arrT<T,normalAlloc__<T> >(sz) {}
|
||||
/*! Creates an array with \a sz entries, and initializes them with
|
||||
\a inival. */
|
||||
arr(tsize sz, const T &inival) : arrT<T,normalAlloc__<T> >(sz,inival) {}
|
||||
/*! Creates an array with \a sz entries, which uses the memory pointed
|
||||
to by \a ptr.
|
||||
\note \a ptr will <i>not</i> be deallocated by the destructor.
|
||||
\warning Only use this if you REALLY know what you are doing.
|
||||
In particular, this is only safely usable if
|
||||
<ul>
|
||||
<li>\a T is a POD type</li>
|
||||
<li>\a ptr survives during the lifetime of the array object</li>
|
||||
<li>\a ptr is not subject to garbage collection</li>
|
||||
</ul>
|
||||
Other restrictions may apply. You have been warned. */
|
||||
arr (T *ptr, tsize sz): arrT<T,normalAlloc__<T> >(ptr,sz) {}
|
||||
};
|
||||
|
||||
/*! One-dimensional array type, with selectable storage alignment. */
|
||||
template <typename T, int align>
|
||||
class arr_align: public arrT<T,alignAlloc__<T,align> >
|
||||
{
|
||||
public:
|
||||
/*! Creates a zero-sized array. */
|
||||
arr_align() : arrT<T,alignAlloc__<T,align> >() {}
|
||||
/*! Creates an array with \a sz entries. */
|
||||
arr_align(tsize sz) : arrT<T,alignAlloc__<T,align> >(sz) {}
|
||||
/*! Creates an array with \a sz entries, and initializes them with
|
||||
\a inival. */
|
||||
arr_align(tsize sz, const T &inival)
|
||||
: arrT<T,alignAlloc__<T,align> >(sz,inival) {}
|
||||
};
|
||||
|
||||
|
||||
/*! Two-dimensional array type, with selectable storage management.
|
||||
The storage ordering is the same as in C.
|
||||
An entry is located by address arithmetic, not by double dereferencing.
|
||||
The indices start at zero. */
|
||||
template <typename T, typename storageManager> class arr2T
|
||||
{
|
||||
private:
|
||||
tsize s1, s2;
|
||||
arrT<T, storageManager> d;
|
||||
|
||||
public:
|
||||
/*! Creates a zero-sized array. */
|
||||
arr2T() : s1(0), s2(0) {}
|
||||
/*! Creates an array with the dimensions \a sz1 and \a sz2. */
|
||||
arr2T(tsize sz1, tsize sz2)
|
||||
: s1(sz1), s2(sz2), d(s1*s2) {}
|
||||
/*! Creates an array with the dimensions \a sz1 and \a sz2
|
||||
and initializes them with \a inival. */
|
||||
arr2T(tsize sz1, tsize sz2, const T &inival)
|
||||
: s1(sz1), s2(sz2), d (s1*s2)
|
||||
{ fill(inival); }
|
||||
/*! Creates the array as a copy of \a orig. */
|
||||
arr2T(const arr2T &orig)
|
||||
: s1(orig.s1), s2(orig.s2), d(orig.d) {}
|
||||
/*! Frees the memory associated with the array. */
|
||||
~arr2T() {}
|
||||
|
||||
/*! Returns the first array dimension. */
|
||||
tsize size1() const { return s1; }
|
||||
/*! Returns the second array dimension. */
|
||||
tsize size2() const { return s2; }
|
||||
/*! Returns the total array size, i.e. the product of both dimensions. */
|
||||
tsize size () const { return s1*s2; }
|
||||
|
||||
/*! Allocates space for an array with \a sz1*sz2 elements.
|
||||
The content of the array is undefined on exit.
|
||||
\a sz1 or \a sz2 can be 0. If \a sz1*sz2 is the same as the
|
||||
currently allocated space, no reallocation is performed. */
|
||||
void alloc (tsize sz1, tsize sz2)
|
||||
{
|
||||
if (sz1*sz2 != d.size())
|
||||
d.alloc(sz1*sz2);
|
||||
s1=sz1; s2=sz2;
|
||||
}
|
||||
/*! Allocates space for an array with \a sz1*sz2 elements.
|
||||
All elements are set to \a inival.
|
||||
\a sz1 or \a sz2 can be 0. If \a sz1*sz2 is the same as the
|
||||
currently allocated space, no reallocation is performed. */
|
||||
void allocAndFill (tsize sz1, tsize sz2, const T &inival)
|
||||
{ alloc(sz1,sz2); fill(inival); }
|
||||
/*! Allocates space for an array with \a sz1*sz2 elements.
|
||||
The content of the array is undefined on exit.
|
||||
\a sz1 or \a sz2 can be 0. If \a sz1*sz2 is smaller than the
|
||||
currently allocated space, no reallocation is performed. */
|
||||
void fast_alloc (tsize sz1, tsize sz2)
|
||||
{
|
||||
if (sz1*sz2<=d.size())
|
||||
{ s1=sz1; s2=sz2; }
|
||||
else
|
||||
alloc(sz1,sz2);
|
||||
}
|
||||
/*! Deallocates the space and makes the array zero-sized. */
|
||||
void dealloc () {d.dealloc(); s1=0; s2=0;}
|
||||
|
||||
/*! Sets all array elements to \a val. */
|
||||
void fill (const T &val)
|
||||
{ for (tsize m=0; m<s1*s2; ++m) d[m]=val; }
|
||||
|
||||
/*! Changes the array to be a copy of \a orig. */
|
||||
arr2T &operator= (const arr2T &orig)
|
||||
{
|
||||
if (this==&orig) return *this;
|
||||
alloc (orig.s1, orig.s2);
|
||||
d = orig.d;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*! Returns a pointer to the beginning of slice \a n. */
|
||||
template<typename T2> T *operator[] (T2 n) {return &d[n*s2];}
|
||||
/*! Returns a constant pointer to the beginning of slice \a n. */
|
||||
template<typename T2> const T *operator[] (T2 n) const {return &d[n*s2];}
|
||||
|
||||
/*! Returns a reference to the element with the indices \a n1 and \a n2. */
|
||||
template<typename T2, typename T3> T &operator() (T2 n1, T3 n2)
|
||||
{return d[n1*s2 + n2];}
|
||||
/*! Returns a constant reference to the element with the indices
|
||||
\a n1 and \a n2. */
|
||||
template<typename T2, typename T3> const T &operator() (T2 n1, T3 n2) const
|
||||
{return d[n1*s2 + n2];}
|
||||
|
||||
/*! Returns the minimum and maximum entry in \a minv and \a maxv,
|
||||
respectively. Throws an exception if the array is zero-sized. */
|
||||
void minmax (T &minv, T &maxv) const
|
||||
{
|
||||
planck_assert(s1*s2>0,
|
||||
"trying to find min and max of a zero-sized array");
|
||||
minv=maxv=d[0];
|
||||
for (tsize m=1; m<s1*s2; ++m)
|
||||
{
|
||||
if (d[m]<minv) minv=d[m];
|
||||
if (d[m]>maxv) maxv=d[m];
|
||||
}
|
||||
}
|
||||
|
||||
/*! Swaps contents and sizes with \a other. */
|
||||
void swap (arr2T &other)
|
||||
{
|
||||
d.swap(other.d);
|
||||
std::swap(s1,other.s1);
|
||||
std::swap(s2,other.s2);
|
||||
}
|
||||
|
||||
/*! Returns \c true if the array and \a other have the same dimensions,
|
||||
else \c false. */
|
||||
template<typename T2, typename T3> bool conformable
|
||||
(const arr2T<T2,T3> &other) const
|
||||
{ return (other.size1()==s1) && (other.size2()==s2); }
|
||||
};
|
||||
|
||||
/*! Two-dimensional array type. The storage ordering is the same as in C.
|
||||
An entry is located by address arithmetic, not by double dereferencing.
|
||||
The indices start at zero. */
|
||||
template <typename T>
|
||||
class arr2: public arr2T<T,normalAlloc__<T> >
|
||||
{
|
||||
public:
|
||||
/*! Creates a zero-sized array. */
|
||||
arr2() : arr2T<T,normalAlloc__<T> > () {}
|
||||
/*! Creates an array with the dimensions \a sz1 and \a sz2. */
|
||||
arr2(tsize sz1, tsize sz2) : arr2T<T,normalAlloc__<T> > (sz1,sz2) {}
|
||||
/*! Creates an array with the dimensions \a sz1 and \a sz2
|
||||
and initializes them with \a inival. */
|
||||
arr2(tsize sz1, tsize sz2, const T &inival)
|
||||
: arr2T<T,normalAlloc__<T> > (sz1,sz2,inival) {}
|
||||
};
|
||||
|
||||
/*! Two-dimensional array type, with selectable storage alignment.
|
||||
The storage ordering is the same as in C.
|
||||
An entry is located by address arithmetic, not by double dereferencing.
|
||||
The indices start at zero. */
|
||||
template <typename T, int align>
|
||||
class arr2_align: public arr2T<T,alignAlloc__<T,align> >
|
||||
{
|
||||
public:
|
||||
/*! Creates a zero-sized array. */
|
||||
arr2_align() : arr2T<T,alignAlloc__<T,align> > () {}
|
||||
/*! Creates an array with the dimensions \a sz1 and \a sz2. */
|
||||
arr2_align(tsize sz1, tsize sz2)
|
||||
: arr2T<T,alignAlloc__<T,align> > (sz1,sz2) {}
|
||||
/*! Creates an array with the dimensions \a sz1 and \a sz2
|
||||
and initializes them with \a inival. */
|
||||
arr2_align(tsize sz1, tsize sz2, const T &inival)
|
||||
: arr2T<T,alignAlloc__<T,align> > (sz1,sz2,inival) {}
|
||||
};
|
||||
|
||||
/*! Two-dimensional array type. An entry is located by double dereferencing,
|
||||
i.e. via an array of pointers. The indices start at zero. */
|
||||
template <typename T> class arr2b
|
||||
{
|
||||
private:
|
||||
tsize s1, s2;
|
||||
arr<T> d;
|
||||
arr<T *> d1;
|
||||
|
||||
void fill_d1()
|
||||
{ for (tsize m=0; m<s1; ++m) d1[m] = &d[m*s2]; }
|
||||
|
||||
public:
|
||||
/*! Creates a zero-sized array. */
|
||||
arr2b() : s1(0), s2(0), d(0), d1(0) {}
|
||||
/*! Creates an array with the dimensions \a sz1 and \a sz2. */
|
||||
arr2b(tsize sz1, tsize sz2)
|
||||
: s1(sz1), s2(sz2), d(s1*s2), d1(s1)
|
||||
{ fill_d1(); }
|
||||
/*! Creates the array as a copy of \a orig. */
|
||||
arr2b(const arr2b &orig)
|
||||
: s1(orig.s1), s2(orig.s2), d(orig.d), d1(s1)
|
||||
{ fill_d1(); }
|
||||
/*! Frees the memory associated with the array. */
|
||||
~arr2b() {}
|
||||
|
||||
/*! Returns the first array dimension. */
|
||||
tsize size1() const { return s1; }
|
||||
/*! Returns the second array dimension. */
|
||||
tsize size2() const { return s2; }
|
||||
/*! Returns the total array size, i.e. the product of both dimensions. */
|
||||
tsize size () const { return s1*s2; }
|
||||
|
||||
/*! Allocates space for an array with \a sz1*sz2 elements.
|
||||
The content of the array is undefined on exit. */
|
||||
void alloc (tsize sz1, tsize sz2)
|
||||
{
|
||||
if ((s1==sz1) && (s2==sz2)) return;
|
||||
s1=sz1; s2=sz2;
|
||||
d.alloc(s1*s2);
|
||||
d1.alloc(s1);
|
||||
fill_d1();
|
||||
}
|
||||
/*! Deallocates the space and makes the array zero-sized. */
|
||||
void dealloc () {d.dealloc(); d1.dealloc(); s1=0; s2=0;}
|
||||
|
||||
/*! Sets all array elements to \a val. */
|
||||
void fill (const T &val)
|
||||
{ d.fill(val); }
|
||||
|
||||
/*! Changes the array to be a copy of \a orig. */
|
||||
arr2b &operator= (const arr2b &orig)
|
||||
{
|
||||
if (this==&orig) return *this;
|
||||
alloc (orig.s1, orig.s2);
|
||||
for (tsize m=0; m<s1*s2; ++m) d[m] = orig.d[m];
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*! Returns a pointer to the beginning of slice \a n. */
|
||||
template<typename T2> T *operator[] (T2 n) {return d1[n];}
|
||||
/*! Returns a constant pointer to the beginning of slice \a n. */
|
||||
template<typename T2> const T *operator[] (T2 n) const {return d1[n];}
|
||||
|
||||
/*! Returns a pointer to the beginning of the pointer array. */
|
||||
T **p0() {return &d1[0];}
|
||||
};
|
||||
|
||||
|
||||
/*! Three-dimensional array type. The storage ordering is the same as in C.
|
||||
An entry is located by address arithmetic, not by multiple dereferencing.
|
||||
The indices start at zero. */
|
||||
template <typename T> class arr3
|
||||
{
|
||||
private:
|
||||
tsize s1, s2, s3, s2s3;
|
||||
arr<T> d;
|
||||
|
||||
public:
|
||||
/*! Creates a zero-sized array. */
|
||||
arr3() : s1(0), s2(0), s3(0), s2s3(0), d(0) {}
|
||||
/*! Creates an array with the dimensions \a sz1, \a sz2 and \a sz3. */
|
||||
arr3(tsize sz1, tsize sz2, tsize sz3)
|
||||
: s1(sz1), s2(sz2), s3(sz3), s2s3(s2*s3), d(s1*s2*s3) {}
|
||||
/*! Creates the array as a copy of \a orig. */
|
||||
arr3(const arr3 &orig)
|
||||
: s1(orig.s1), s2(orig.s2), s3(orig.s3), s2s3(orig.s2s3), d(orig.d) {}
|
||||
/*! Frees the memory associated with the array. */
|
||||
~arr3() {}
|
||||
|
||||
/*! Returns the first array dimension. */
|
||||
tsize size1() const { return s1; }
|
||||
/*! Returns the second array dimension. */
|
||||
tsize size2() const { return s2; }
|
||||
/*! Returns the third array dimension. */
|
||||
tsize size3() const { return s3; }
|
||||
/*! Returns the total array size, i.e. the product of all dimensions. */
|
||||
tsize size () const { return s1*s2*s3; }
|
||||
|
||||
/*! Allocates space for an array with \a sz1*sz2*sz3 elements.
|
||||
The content of the array is undefined on exit. */
|
||||
void alloc (tsize sz1, tsize sz2, tsize sz3)
|
||||
{
|
||||
d.alloc(sz1*sz2*sz3);
|
||||
s1=sz1; s2=sz2; s3=sz3; s2s3=s2*s3;
|
||||
}
|
||||
/*! Deallocates the space and makes the array zero-sized. */
|
||||
void dealloc () {d.dealloc(); s1=0; s2=0; s3=0; s2s3=0;}
|
||||
|
||||
/*! Sets all array elements to \a val. */
|
||||
void fill (const T &val)
|
||||
{ d.fill(val); }
|
||||
|
||||
/*! Changes the array to be a copy of \a orig. */
|
||||
arr3 &operator= (const arr3 &orig)
|
||||
{
|
||||
if (this==&orig) return *this;
|
||||
alloc (orig.s1, orig.s2, orig.s3);
|
||||
d = orig.d;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*! Returns a reference to the element with the indices
|
||||
\a n1, \a n2 and \a n3. */
|
||||
template<typename T2, typename T3, typename T4> T &operator()
|
||||
(T2 n1, T3 n2, T4 n3)
|
||||
{return d[n1*s2s3 + n2*s3 + n3];}
|
||||
/*! Returns a constant reference to the element with the indices
|
||||
\a n1, \a n2 and \a n3. */
|
||||
template<typename T2, typename T3, typename T4> const T &operator()
|
||||
(T2 n1, T3 n2, T4 n3) const
|
||||
{return d[n1*s2s3 + n2*s3 + n3];}
|
||||
|
||||
/*! Swaps contents and sizes with \a other. */
|
||||
void swap (arr3 &other)
|
||||
{
|
||||
d.swap(other.d);
|
||||
std::swap(s1,other.s1);
|
||||
std::swap(s2,other.s2);
|
||||
std::swap(s3,other.s3);
|
||||
std::swap(s2s3,other.s2s3);
|
||||
}
|
||||
|
||||
/*! Returns \c true if the array and \a other have the same dimensions,
|
||||
else \c false. */
|
||||
template<typename T2> bool conformable (const arr3<T2> &other) const
|
||||
{ return (other.size1()==s1)&&(other.size2()==s2)&&(other.size3()==s3); }
|
||||
};
|
||||
|
||||
/*! \} */
|
||||
|
||||
#endif
|
266
external/healpix/cxxsupport/bstream.h
vendored
Normal file
266
external/healpix/cxxsupport/bstream.h
vendored
Normal file
|
@ -0,0 +1,266 @@
|
|||
/*
|
||||
* This file is part of libcxxsupport.
|
||||
*
|
||||
* libcxxsupport is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libcxxsupport is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libcxxsupport; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*! \file bstream.h
|
||||
* Classes for binary I/O with streams
|
||||
*
|
||||
* Copyright (C) 2010 Max-Planck-Society
|
||||
* \author Martin Reinecke
|
||||
*/
|
||||
|
||||
#ifndef PLANCK_BSTREAM_H
|
||||
#define PLANCK_BSTREAM_H
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
#include "datatypes.h"
|
||||
|
||||
/*! An object of this class can be cast to a \a bool, which indicates whether
|
||||
the computer architecture is big-endian (true) or little-endian (false). */
|
||||
class EndianTest__
|
||||
{
|
||||
private:
|
||||
bool big_end;
|
||||
|
||||
public:
|
||||
EndianTest__()
|
||||
{
|
||||
union { uint16 i16; uint8 i8; } tmp;
|
||||
tmp.i16 = 1;
|
||||
big_end = (tmp.i8==0);
|
||||
}
|
||||
operator bool() const { return big_end; }
|
||||
};
|
||||
|
||||
const EndianTest__ big_endian;
|
||||
|
||||
template<size_t size> inline void byteswap_helper__ (char *);
|
||||
template<> inline void byteswap_helper__<1> (char *)
|
||||
{}
|
||||
template<> inline void byteswap_helper__<2> (char *val)
|
||||
{
|
||||
using namespace std;
|
||||
swap (val[0],val[1]);
|
||||
}
|
||||
template<> inline void byteswap_helper__<4> (char *val)
|
||||
{
|
||||
using namespace std;
|
||||
swap (val[0],val[3]); swap (val[1],val[2]);
|
||||
}
|
||||
template<> inline void byteswap_helper__<8> (char *val)
|
||||
{
|
||||
using namespace std;
|
||||
swap (val[0],val[7]); swap (val[1],val[6]);
|
||||
swap (val[2],val[5]); swap (val[3],val[4]);
|
||||
}
|
||||
|
||||
/*! Performs an endianness conversion on \a val.
|
||||
\note \a T must be a primitive data type! */
|
||||
template<typename T> inline void byteswap (T &val)
|
||||
{ byteswap_helper__<sizeof(T)> (reinterpret_cast<char *> (&val)); }
|
||||
|
||||
const bool file_is_lsb=big_endian, file_is_msb=!big_endian,
|
||||
file_is_natural=false;
|
||||
|
||||
/*! Class for writing binary data to a stream. */
|
||||
class bostream
|
||||
{
|
||||
private:
|
||||
std::ostream &s;
|
||||
bool doswap;
|
||||
|
||||
public:
|
||||
/*! Creates a new object which is attached to \a s_ and performs
|
||||
endianness conversion if \a doswap_==true. */
|
||||
bostream (std::ostream &s_, bool doswap_=false)
|
||||
: s(s_), doswap(doswap_) {}
|
||||
|
||||
/*! Writes a binary representation of \a num objects of type \a T
|
||||
(stored in \a data) to the attached stream. Endianness conversion
|
||||
is performed if requested in the constructor.
|
||||
\note \a T must be a primitive data type! */
|
||||
template<typename T> bostream &put (const T *data, size_t num)
|
||||
{
|
||||
if ((sizeof(T)>1) && doswap)
|
||||
for (size_t m=0; m<num; ++m)
|
||||
{
|
||||
T tmp=data[m];
|
||||
byteswap (tmp);
|
||||
s.write (reinterpret_cast<const char *> (&tmp), sizeof(T));
|
||||
}
|
||||
else
|
||||
s.write (reinterpret_cast<const char *> (data), num*sizeof(T));
|
||||
return *this;
|
||||
}
|
||||
/*! Writes a binary representation of \a data to the attached stream.
|
||||
Endianness conversion is performed if requested in the constructor.
|
||||
\note \a T must be a primitive data type! */
|
||||
template<typename T> bostream &operator<< (const T &data)
|
||||
{
|
||||
put(&data,1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool getSwap() const
|
||||
{ return doswap; }
|
||||
void setSwap(bool newswap)
|
||||
{ doswap=newswap; }
|
||||
void flipSwap()
|
||||
{ doswap=!doswap; }
|
||||
};
|
||||
|
||||
/*! Class for reading binary data from a stream. */
|
||||
class bistream
|
||||
{
|
||||
private:
|
||||
std::istream &s;
|
||||
bool doswap;
|
||||
|
||||
public:
|
||||
/*! Creates a new object which is attached to \a s_ and performs
|
||||
endianness conversion if \a doswap_==true. */
|
||||
bistream (std::istream &s_, bool doswap_=false)
|
||||
: s(s_), doswap(doswap_) {}
|
||||
|
||||
/*! Reads a binary representation of \a num objects of type \a T
|
||||
from the attached stream and stores them in \a data. Endianness
|
||||
conversion is performed if requested in the constructor.
|
||||
\note \a T must be a primitive data type! */
|
||||
template<typename T> bistream &get (T *data, size_t num)
|
||||
{
|
||||
s.read (reinterpret_cast<char *> (data), num*sizeof(T));
|
||||
if ((sizeof(T)>1) && doswap)
|
||||
for (size_t m=0; m<num; ++m)
|
||||
byteswap (data[m]);
|
||||
return *this;
|
||||
}
|
||||
/*! Reads a binary representation of \a data from the attached stream.
|
||||
Endianness conversion is performed if requested in the constructor.
|
||||
\note \a T must be a primitive data type! */
|
||||
template<typename T> bistream &operator>> (T &data)
|
||||
{
|
||||
get (&data,1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool getSwap() const
|
||||
{ return doswap; }
|
||||
void setSwap(bool newswap)
|
||||
{ doswap=newswap; }
|
||||
void flipSwap()
|
||||
{ doswap=!doswap; }
|
||||
};
|
||||
|
||||
class bofstream: public std::ofstream
|
||||
{
|
||||
private:
|
||||
bool doswap;
|
||||
|
||||
public:
|
||||
/*! */
|
||||
bofstream (const char *fname, bool doswap_)
|
||||
: std::ofstream(fname,std::ios::binary), doswap(doswap_) {}
|
||||
|
||||
template<typename T> bofstream &operator<< (const T &data)
|
||||
{
|
||||
if (doswap)
|
||||
{
|
||||
T tmp = data;
|
||||
byteswap (tmp);
|
||||
write (reinterpret_cast<const char *> (&tmp), sizeof(T));
|
||||
}
|
||||
else
|
||||
write (reinterpret_cast<const char *> (&data), sizeof(T));
|
||||
return *this;
|
||||
}
|
||||
template<typename T> bofstream &put (const T *data, size_t num)
|
||||
{
|
||||
if (doswap)
|
||||
for (size_t m=0; m<num; ++m)
|
||||
{
|
||||
T tmp=data[m];
|
||||
byteswap (tmp);
|
||||
write (reinterpret_cast<const char *> (&tmp), sizeof(T));
|
||||
}
|
||||
else
|
||||
write (reinterpret_cast<const char *> (data), num*sizeof(T));
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool getSwap() const
|
||||
{ return doswap; }
|
||||
void setSwap(bool newswap)
|
||||
{ doswap=newswap; }
|
||||
void flipSwap()
|
||||
{ doswap=!doswap; }
|
||||
};
|
||||
|
||||
class bifstream: public std::ifstream
|
||||
{
|
||||
private:
|
||||
bool doswap;
|
||||
|
||||
public:
|
||||
/*! */
|
||||
bifstream ()
|
||||
: doswap(false) {}
|
||||
bifstream (const char *fname, bool doswap_)
|
||||
: std::ifstream(fname,std::ios::binary), doswap(doswap_) {}
|
||||
|
||||
void open (const char *fname, bool doswap_)
|
||||
{
|
||||
doswap=doswap_;
|
||||
std::ifstream::open(fname,std::ios::binary);
|
||||
}
|
||||
|
||||
template<typename T> bifstream &operator>> (T &data)
|
||||
{
|
||||
read (reinterpret_cast<char *> (&data), sizeof(T));
|
||||
if (doswap) byteswap (data);
|
||||
return *this;
|
||||
}
|
||||
template<typename T> bifstream &get (T *data, size_t num)
|
||||
{
|
||||
read (reinterpret_cast<char *> (data), num*sizeof(T));
|
||||
if (doswap)
|
||||
for (size_t m=0; m<num; ++m)
|
||||
byteswap (data[m]);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void rewind()
|
||||
{ seekg(0,std::ios::beg); }
|
||||
void skip(std::streamoff nbytes)
|
||||
{ seekg(nbytes,std::ios::cur); }
|
||||
|
||||
bool getSwap() const
|
||||
{ return doswap; }
|
||||
void setSwap(bool newswap)
|
||||
{ doswap=newswap; }
|
||||
void flipSwap()
|
||||
{ doswap=!doswap; }
|
||||
};
|
||||
|
||||
#endif
|
4
external/healpix/cxxsupport/cxxsupport.dox
vendored
Normal file
4
external/healpix/cxxsupport/cxxsupport.dox
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
/*! \mainpage LevelS C++ support library documentation
|
||||
Please refer to the <a href="modules.html">Modules</a> page for an overview
|
||||
of the supplied functionality.
|
||||
*/
|
304
external/healpix/cxxsupport/cxxutils.cc
vendored
Normal file
304
external/healpix/cxxsupport/cxxutils.cc
vendored
Normal file
|
@ -0,0 +1,304 @@
|
|||
/*
|
||||
* This file is part of libcxxsupport.
|
||||
*
|
||||
* libcxxsupport is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libcxxsupport is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libcxxsupport; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file contains the implementation of various convenience functions
|
||||
* used by the Planck LevelS package.
|
||||
*
|
||||
* Copyright (C) 2002 - 2010 Max-Planck-Society
|
||||
* Authors: Martin Reinecke, Reinhard Hell
|
||||
*/
|
||||
|
||||
// if we are using g++, check for version 3.0 or higher
|
||||
#ifdef __GNUC__
|
||||
#if (__GNUC__<3)
|
||||
#error your C++ compiler is too old. g++ version 3.0 or higher is required.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include "cxxutils.h"
|
||||
#include "datatypes.h"
|
||||
#include "openmp_support.h"
|
||||
#include "sse_utils.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
string trim (const string &orig)
|
||||
{
|
||||
string::size_type p1=orig.find_first_not_of(" \t");
|
||||
if (p1==string::npos) return "";
|
||||
string::size_type p2=orig.find_last_not_of(" \t");
|
||||
return orig.substr(p1,p2-p1+1);
|
||||
}
|
||||
|
||||
template<typename T> string dataToString (const T &x)
|
||||
{
|
||||
ostringstream strstrm;
|
||||
strstrm << x;
|
||||
return trim(strstrm.str());
|
||||
}
|
||||
|
||||
template<> string dataToString (const bool &x)
|
||||
{ return x ? "T" : "F"; }
|
||||
template<> string dataToString (const string &x)
|
||||
{ return trim(x); }
|
||||
template<> string dataToString (const float &x)
|
||||
{
|
||||
ostringstream strstrm;
|
||||
strstrm << setprecision(8) << x;
|
||||
return trim(strstrm.str());
|
||||
}
|
||||
template<> string dataToString (const double &x)
|
||||
{
|
||||
ostringstream strstrm;
|
||||
strstrm << setprecision(16) << x;
|
||||
return trim(strstrm.str());
|
||||
}
|
||||
|
||||
template string dataToString (const signed char &x);
|
||||
template string dataToString (const unsigned char &x);
|
||||
template string dataToString (const short &x);
|
||||
template string dataToString (const unsigned short &x);
|
||||
template string dataToString (const int &x);
|
||||
template string dataToString (const unsigned int &x);
|
||||
template string dataToString (const long &x);
|
||||
template string dataToString (const unsigned long &x);
|
||||
template string dataToString (const long long &x);
|
||||
template string dataToString (const unsigned long long &x);
|
||||
|
||||
string intToString(int64 x, tsize width)
|
||||
{
|
||||
ostringstream strstrm;
|
||||
strstrm << setw(width) << setfill('0') << x;
|
||||
return trim(strstrm.str());
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void end_stringToData (const string &x, const char *tn, istringstream &strstrm)
|
||||
{
|
||||
string error = string("conversion error in stringToData<")+tn+">(\""+x+"\")";
|
||||
planck_assert (strstrm,error);
|
||||
string rest;
|
||||
strstrm >> rest;
|
||||
// rest=trim(rest);
|
||||
planck_assert (rest.length()==0,error);
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
template<typename T> void stringToData (const string &x, T &value)
|
||||
{
|
||||
istringstream strstrm(x);
|
||||
strstrm >> value;
|
||||
end_stringToData (x,type2typename<T>(),strstrm);
|
||||
}
|
||||
|
||||
template<> void stringToData (const string &x, string &value)
|
||||
{ value = trim(x); }
|
||||
|
||||
template<> void stringToData (const string &x, bool &value)
|
||||
{
|
||||
const char *x2 = x.c_str();
|
||||
const char *fval[] = {"F","f","n","N","false",".false.","FALSE",".FALSE." };
|
||||
const char *tval[] = {"T","t","y","Y","true",".true.","TRUE",".TRUE." };
|
||||
for (tsize i=0; i< sizeof(fval)/sizeof(fval[0]); ++i)
|
||||
if (strcmp(x2,fval[i])==0) { value=false; return; }
|
||||
for (tsize i=0; i< sizeof(tval)/sizeof(tval[0]); ++i)
|
||||
if (strcmp(x2,tval[i])==0) { value=true; return; }
|
||||
planck_fail("conversion error in stringToData<bool>(\""+x+"\")");
|
||||
}
|
||||
|
||||
template void stringToData (const string &x, signed char &value);
|
||||
template void stringToData (const string &x, unsigned char &value);
|
||||
template void stringToData (const string &x, short &value);
|
||||
template void stringToData (const string &x, unsigned short &value);
|
||||
template void stringToData (const string &x, int &value);
|
||||
template void stringToData (const string &x, unsigned int &value);
|
||||
template void stringToData (const string &x, long &value);
|
||||
template void stringToData (const string &x, unsigned long &value);
|
||||
template void stringToData (const string &x, long long &value);
|
||||
template void stringToData (const string &x, unsigned long long &value);
|
||||
template void stringToData (const string &x, float &value);
|
||||
template void stringToData (const string &x, double &value);
|
||||
|
||||
bool equal_nocase (const string &a, const string &b)
|
||||
{
|
||||
if (a.size()!=b.size()) return false;
|
||||
for (tsize m=0; m<a.size(); ++m)
|
||||
if (tolower(a[m])!=tolower(b[m])) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
string tolower(const string &input)
|
||||
{
|
||||
string result=input;
|
||||
for (tsize m=0; m<result.size(); ++m)
|
||||
result[m]=char(tolower(result[m]));
|
||||
return result;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void openmp_status()
|
||||
{
|
||||
int threads = openmp_max_threads();
|
||||
if (threads>1)
|
||||
cout << "OpenMP active: max. " << threads << " threads. " << endl;
|
||||
}
|
||||
|
||||
void SSE_status()
|
||||
{
|
||||
#if(defined(PLANCK_HAVE_SSE)||defined(PLANCK_HAVE_SSE2))
|
||||
cout << "Processor features detected: ";
|
||||
#if(defined(PLANCK_HAVE_SSE)&&defined(PLANCK_HAVE_SSE2))
|
||||
cout << "SSE, SSE2" << endl;
|
||||
#elif(defined(PLANCK_HAVE_SSE))
|
||||
cout << "SSE" << endl;
|
||||
#else
|
||||
cout << "SSE2" << endl;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
} //unnamed namespace
|
||||
|
||||
void announce (const string &name)
|
||||
{
|
||||
string version = "v2.20";
|
||||
string name2 = name+" "+version;
|
||||
cout << endl << "+-";
|
||||
for (tsize m=0; m<name2.length(); ++m) cout << "-";
|
||||
cout << "-+" << endl;
|
||||
cout << "| " << name2 << " |" << endl;
|
||||
cout << "+-";
|
||||
for (tsize m=0; m<name2.length(); ++m) cout << "-";
|
||||
cout << "-+" << endl << endl;
|
||||
SSE_status();
|
||||
openmp_status();
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
void module_startup (const string &name, int argc, const char **,
|
||||
int argc_expected, const string &argv_expected, bool verbose)
|
||||
{
|
||||
if (verbose) announce (name);
|
||||
if (argc==argc_expected) return;
|
||||
cerr << "Usage: " << name << " " << argv_expected << endl;
|
||||
planck_fail_quietly ("Incorrect usage");
|
||||
}
|
||||
|
||||
void parse_file (const string &filename, map<string,string> &dict)
|
||||
{
|
||||
int lineno=0;
|
||||
dict.clear();
|
||||
ifstream inp(filename.c_str());
|
||||
planck_assert (inp,"Could not open parameter file '"+filename+"'.");
|
||||
while (inp)
|
||||
{
|
||||
string line;
|
||||
getline(inp, line);
|
||||
++lineno;
|
||||
// remove potential carriage returns at the end of the line
|
||||
line=line.substr(0,line.find("\r"));
|
||||
line=line.substr(0,line.find("#"));
|
||||
line=trim(line);
|
||||
if (line.size()>0)
|
||||
{
|
||||
string::size_type eqpos=line.find("=");
|
||||
if (eqpos!=string::npos)
|
||||
{
|
||||
string key=trim(line.substr(0,eqpos)),
|
||||
value=trim(line.substr(eqpos+1,string::npos));
|
||||
if (key=="")
|
||||
cerr << "Warning: empty key in '" << filename << "', line "
|
||||
<< lineno << endl;
|
||||
else
|
||||
{
|
||||
if (dict.find(key)!=dict.end())
|
||||
cerr << "Warning: key '" << key << "' multiply defined in '"
|
||||
<< filename << "', line " << lineno << endl;
|
||||
dict[key]=value;
|
||||
}
|
||||
}
|
||||
else
|
||||
cerr << "Warning: unrecognized format in '" << filename << "', line "
|
||||
<< lineno << ":\n" << line << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void calcShareGeneral (int64 glo, int64 ghi, int64 nshares, int64 myshare,
|
||||
int64 &lo, int64 &hi)
|
||||
{
|
||||
int64 nwork = ghi-glo;
|
||||
int64 nbase = nwork/nshares;
|
||||
int64 additional = nwork%nshares;
|
||||
lo = glo+myshare*nbase + ((myshare<additional) ? myshare : additional);
|
||||
hi = lo+nbase+(myshare<additional);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
template<typename T> void split (istream &stream, vector<T> &list)
|
||||
{
|
||||
while (stream)
|
||||
{
|
||||
string word;
|
||||
stream >> word;
|
||||
planck_assert (stream||stream.eof(),
|
||||
string("error while splitting stream into ") + type2typename<T>()
|
||||
+ "components");
|
||||
if (stream) list.push_back(stringToData<T>(word));
|
||||
}
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
template<typename T> void split (const string &inp, vector<T> &list)
|
||||
{
|
||||
istringstream stream(inp);
|
||||
split (stream,list);
|
||||
}
|
||||
|
||||
template void split (const string &inp, vector<string> &list);
|
||||
template void split (const string &inp, vector<float> &list);
|
||||
template void split (const string &inp, vector<double> &list);
|
||||
template void split (const string &inp, vector<int> &list);
|
||||
template void split (const string &inp, vector<long> &list);
|
||||
|
||||
void tokenize (const string &inp, char delim, vector<string> &list)
|
||||
{
|
||||
istringstream stream(inp);
|
||||
string token;
|
||||
list.clear();
|
||||
while (getline(stream,token,delim))
|
||||
list.push_back(token);
|
||||
}
|
383
external/healpix/cxxsupport/cxxutils.h
vendored
Normal file
383
external/healpix/cxxsupport/cxxutils.h
vendored
Normal file
|
@ -0,0 +1,383 @@
|
|||
/*
|
||||
* This file is part of libcxxsupport.
|
||||
*
|
||||
* libcxxsupport is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libcxxsupport is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libcxxsupport; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*! \file cxxutils.h
|
||||
* Various convenience functions used by the Planck LevelS package.
|
||||
*
|
||||
* Copyright (C) 2002 - 2010 Max-Planck-Society
|
||||
* \author Martin Reinecke \author Reinhard Hell
|
||||
*/
|
||||
|
||||
#ifndef PLANCK_CXXUTILS_H
|
||||
#define PLANCK_CXXUTILS_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
#include "error_handling.h"
|
||||
#include "datatypes.h"
|
||||
|
||||
/*! \defgroup mathutilsgroup Mathematical helper functions */
|
||||
/*! \{ */
|
||||
|
||||
/*! Returns \e true if | \a a-b | < \a epsilon * | \a b |, else \e false. */
|
||||
template<typename F> inline bool approx (F a, F b, F epsilon=1e-5)
|
||||
{
|
||||
using namespace std;
|
||||
return abs(a-b) < (epsilon*abs(b));
|
||||
}
|
||||
|
||||
/*! Returns \e true if | \a a-b | < \a epsilon, else \e false. */
|
||||
template<typename F> inline bool abs_approx (F a, F b, F epsilon=1e-5)
|
||||
{
|
||||
using namespace std;
|
||||
return abs(a-b) < epsilon;
|
||||
}
|
||||
|
||||
/*! Returns the largest integer which is smaller than (or equal to) \a arg. */
|
||||
template<typename I, typename F> inline I ifloor (F arg)
|
||||
{
|
||||
using namespace std;
|
||||
return I(floor(arg));
|
||||
}
|
||||
|
||||
/*! Returns the integer which is nearest to \a arg. */
|
||||
template<typename I, typename F> inline I nearest (F arg)
|
||||
{ return ifloor<I>(arg+0.5); }
|
||||
|
||||
/*! Returns \a v1+v2 if \a v1<0, \a v1-v2 if \a v1>=v2, else \a v1.
|
||||
\a v1 can be positive or negative; \a v2 must be positive. */
|
||||
template<typename T> inline T weak_modulo (T v1, T v2)
|
||||
{ return (v1>=0) ? ((v1<v2) ? v1 : (v1-v2)) : (v1+v2); }
|
||||
|
||||
/*! Returns the remainder of the division \a v1/v2.
|
||||
The result is non-negative.
|
||||
\a v1 can be positive or negative; \a v2 must be positive. */
|
||||
inline double fmodulo (double v1, double v2)
|
||||
{
|
||||
using namespace std;
|
||||
return (v1>=0) ? ((v1<v2) ? v1 : fmod(v1,v2)) : (fmod(v1,v2)+v2);
|
||||
}
|
||||
|
||||
/*! Returns the remainder of the division \a v1/v2.
|
||||
The result is non-negative.
|
||||
\a v1 can be positive or negative; \a v2 must be positive. */
|
||||
template<typename I> inline I imodulo (I v1, I v2)
|
||||
{ I v=v1%v2; return (v>=0) ? v : v+v2; }
|
||||
|
||||
/*! Returns -1 if \a signvalue is negative, else +1. */
|
||||
template<typename T> inline T sign (const T& signvalue)
|
||||
{ return (signvalue>=0) ? 1 : -1; }
|
||||
|
||||
/*! Returns \a val*pow(-1,m) */
|
||||
template<typename T, typename I> inline T xpow (I m, T val)
|
||||
{ return (m&1) ? -val : val; }
|
||||
|
||||
template <typename I, bool g4> struct isqrt_helper__
|
||||
{};
|
||||
template <typename I> struct isqrt_helper__ <I, false>
|
||||
{
|
||||
static uint32 isqrt (I arg)
|
||||
{
|
||||
using namespace std;
|
||||
return uint32 (sqrt(arg+0.5));
|
||||
}
|
||||
};
|
||||
template <typename I> struct isqrt_helper__ <I, true>
|
||||
{
|
||||
static uint32 isqrt (I arg)
|
||||
{
|
||||
using namespace std;
|
||||
long double arg2 = static_cast<long double>(arg)+0.5;
|
||||
return uint32 (sqrt(arg2));
|
||||
}
|
||||
};
|
||||
|
||||
/*! Returns the integer \a n, which fulfills \a n*n<=arg<(n+1)*(n+1). */
|
||||
template<typename I> inline uint32 isqrt (I arg)
|
||||
{ return isqrt_helper__<I,(sizeof(I)>4)>::isqrt(arg); }
|
||||
|
||||
/*! Returns the largest integer \a n that fulfills \a 2^n<=arg. */
|
||||
template<typename I> inline unsigned int ilog2 (I arg)
|
||||
{
|
||||
unsigned int res=0;
|
||||
while (arg > 0x0000FFFF) { res+=16; arg>>=16; }
|
||||
if (arg > 0x000000FF) { res|=8; arg>>=8; }
|
||||
if (arg > 0x0000000F) { res|=4; arg>>=4; }
|
||||
if (arg > 0x00000003) { res|=2; arg>>=2; }
|
||||
if (arg > 0x00000001) { res|=1; }
|
||||
return res;
|
||||
}
|
||||
|
||||
/*! Returns \a atan2(y,x) if \a x!=0 or \a y!=0; else returns 0. */
|
||||
inline double safe_atan2 (double y, double x)
|
||||
{
|
||||
using namespace std;
|
||||
return ((x==0.) && (y==0.)) ? 0.0 : atan2(y,x);
|
||||
}
|
||||
|
||||
/*! Helper function for linear interpolation (or extrapolation).
|
||||
The array must be ordered in ascending order; no two values may be equal. */
|
||||
template<typename T, typename Iter, typename Comp> inline void interpol_helper
|
||||
(const Iter &begin, const Iter &end, const T &val, Comp comp, tsize &idx,
|
||||
T &frac)
|
||||
{
|
||||
using namespace std;
|
||||
planck_assert((end-begin)>1,"sequence too small for interpolation");
|
||||
idx = lower_bound(begin,end,val,comp)-begin;
|
||||
if (idx>0) --idx;
|
||||
idx = min(tsize(end-begin-2),idx);
|
||||
frac = (val-begin[idx])/(begin[idx+1]-begin[idx]);
|
||||
}
|
||||
|
||||
/*! Helper function for linear interpolation (or extrapolation).
|
||||
The array must be ordered in ascending order; no two values may be equal. */
|
||||
template<typename T, typename Iter> inline void interpol_helper
|
||||
(const Iter &begin, const Iter &end, const T &val, tsize &idx, T &frac)
|
||||
{ interpol_helper (begin,end,val,std::less<T>(),idx,frac); }
|
||||
|
||||
/*! \} */
|
||||
|
||||
template<typename T> inline bool multiequal (const T &a, const T &b, const T &c)
|
||||
{ return (a==b) && (a==c); }
|
||||
|
||||
template<typename T> inline bool multiequal (const T &a, const T &b, const T &c,
|
||||
const T &d)
|
||||
{ return (a==b) && (a==c) && (a==d); }
|
||||
|
||||
template<typename T> inline bool multiequal (const T &a, const T &b, const T &c,
|
||||
const T &d, const T &e)
|
||||
{ return (a==b) && (a==c) && (a==d) && (a==e); }
|
||||
|
||||
template<typename T> inline bool multiequal (const T &a, const T &b, const T &c,
|
||||
const T &d, const T &e, const T &f)
|
||||
{ return (a==b) && (a==c) && (a==d) && (a==e) && (a==f); }
|
||||
|
||||
template<typename It, typename Comp> class IdxComp__
|
||||
{
|
||||
private:
|
||||
It begin;
|
||||
Comp comp;
|
||||
public:
|
||||
IdxComp__ (It begin_, Comp comp_): begin(begin_), comp(comp_) {}
|
||||
bool operator() (std::size_t a, std::size_t b) const
|
||||
{ return comp(*(begin+a),*(begin+b)); }
|
||||
};
|
||||
|
||||
/*! Performs an indirect sort on the supplied iterator range and returns in
|
||||
\a idx a \a vector containing the indices of the smallest, second smallest,
|
||||
third smallest, etc. element, according to \a comp. */
|
||||
template<typename It, typename T2, typename Comp>
|
||||
inline void buildIndex (It begin, It end, std::vector<T2> &idx, Comp comp)
|
||||
{
|
||||
using namespace std;
|
||||
T2 num=end-begin;
|
||||
idx.resize(num);
|
||||
for (T2 i=0; i<num; ++i) idx[i] = i;
|
||||
sort (idx.begin(),idx.end(),IdxComp__<It,Comp>(begin,comp));
|
||||
}
|
||||
|
||||
/*! Performs an indirect sort on the supplied iterator range and returns in
|
||||
\a idx a \a vector containing the indices of the smallest, second smallest,
|
||||
third smallest, etc. element. */
|
||||
template<typename It, typename T2> inline void buildIndex (It begin, It end,
|
||||
std::vector<T2> &idx)
|
||||
{
|
||||
using namespace std;
|
||||
typedef typename iterator_traits<It>::value_type T;
|
||||
buildIndex(begin,end,idx,less<T>());
|
||||
}
|
||||
|
||||
/*! Sorts the supplied iterator range according to the order given by \a idx.
|
||||
The operation is done out of place and requires temporary extra storage. */
|
||||
template<typename It, typename T2> inline void sortByIndex (It begin, It end,
|
||||
const std::vector<T2> &idx)
|
||||
{
|
||||
using namespace std;
|
||||
typedef typename iterator_traits<It>::value_type T;
|
||||
T2 num=end-begin;
|
||||
T *tmp= new T[num];
|
||||
for (T2 i=0; i<num; ++i) tmp[i]=*(begin+i);
|
||||
for (T2 i=0; i<num; ++i) *(begin+i) = tmp[idx[i]];
|
||||
delete[] tmp;
|
||||
}
|
||||
|
||||
/*! Sorts the supplied iterator range according to the order given by \a idx.
|
||||
The operation is done in place. */
|
||||
template<typename It, typename T2> inline void sortByIndex_inplace
|
||||
(It begin, It end, const std::vector<T2> &idx)
|
||||
{
|
||||
using namespace std;
|
||||
typedef typename iterator_traits<It>::value_type T;
|
||||
T2 num=end-begin;
|
||||
vector<bool> done(num,false);
|
||||
T2 cnt=0;
|
||||
while (cnt<num)
|
||||
{
|
||||
if (!done[cnt]) // new cycle
|
||||
{
|
||||
T tmp(*(begin+cnt));
|
||||
T2 cnt2 = cnt;
|
||||
T2 cnt3 = idx[cnt];
|
||||
while (cnt3!=cnt)
|
||||
{
|
||||
done[cnt2]=true;
|
||||
*(begin+cnt2)=*(begin+cnt3);
|
||||
cnt2=cnt3;
|
||||
cnt3=idx[cnt3];
|
||||
}
|
||||
*(begin+cnt2) = tmp;
|
||||
}
|
||||
++cnt;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename It, typename Comp> inline void indirectSort (It begin, It end,
|
||||
Comp comp)
|
||||
{
|
||||
using namespace std;
|
||||
typedef typename iterator_traits<It>::value_type T;
|
||||
vector<std::size_t> idx;
|
||||
buildIndex (begin,end,idx,comp);
|
||||
sortByIndex (begin,end,idx);
|
||||
}
|
||||
|
||||
template<typename It> inline void indirectSort (It begin, It end)
|
||||
{
|
||||
using namespace std;
|
||||
typedef typename iterator_traits<It>::value_type T;
|
||||
indirectSort(begin,end,less<T>());
|
||||
}
|
||||
|
||||
/*! \defgroup stringutilsgroup String handling helper functions */
|
||||
/*! \{ */
|
||||
|
||||
/*! Returns the string \a orig without leading and trailing whitespace. */
|
||||
std::string trim (const std::string &orig);
|
||||
|
||||
/*! Returns a string containing the text representation of \a x.
|
||||
Care is taken that no information is lost in the conversion. */
|
||||
template<typename T> std::string dataToString(const T &x);
|
||||
template<> std::string dataToString (const bool &x);
|
||||
template<> std::string dataToString (const std::string &x);
|
||||
template<> std::string dataToString (const float &x);
|
||||
template<> std::string dataToString (const double &x);
|
||||
|
||||
/*! Returns a string containing the text representation of \a x, padded
|
||||
with leading zeroes to \a width characters. */
|
||||
std::string intToString(int64 x, tsize width);
|
||||
|
||||
/*! Reads a value of a given datatype from a string */
|
||||
template<typename T> void stringToData (const std::string &x, T &value);
|
||||
template<> void stringToData (const std::string &x, std::string &value);
|
||||
template<> void stringToData (const std::string &x, bool &value);
|
||||
|
||||
/*! Reads a value of a given datatype from a string */
|
||||
template<typename T> inline T stringToData (const std::string &x)
|
||||
{ T result; stringToData(x,result); return result; }
|
||||
|
||||
/*! Parses the file \a filename and returns the key/value pairs in \a dict. */
|
||||
void parse_file (const std::string &filename,
|
||||
std::map<std::string,std::string> &dict);
|
||||
|
||||
/*! Case-insensitive string comparison
|
||||
Returns \a true, if \a a and \a b differ only in capitalisation,
|
||||
else \a false. */
|
||||
bool equal_nocase (const std::string &a, const std::string &b);
|
||||
|
||||
/*! Returns lowercase version of \a input. */
|
||||
std::string tolower(const std::string &input);
|
||||
|
||||
/*! \} */
|
||||
|
||||
/*! Prints a banner containing \a name, as well as some information about the
|
||||
source code and the parallelisation techniques enabled. */
|
||||
void announce (const std::string &name);
|
||||
|
||||
/*! Prints a banner containing \a name and checks if \a argc==argc_expected.
|
||||
If not, a usage description is given and the program is terminated. */
|
||||
void module_startup (const std::string &name, int argc, const char **argv,
|
||||
int argc_expected, const std::string &argv_expected, bool verbose=true);
|
||||
|
||||
/*! Divides the index range [\a glo; \a ghi) into \a nshares approximately
|
||||
equal parts, and returns the sub-range [\a lo; \a hi) of the
|
||||
part with the number \a myshare (first part has index 0). */
|
||||
void calcShareGeneral (int64 glo, int64 ghi, int64 nshares, int64 myshare,
|
||||
int64 &lo, int64 &hi);
|
||||
|
||||
/*! Helper class for dividing a range of work items into chunks of specified
|
||||
size. */
|
||||
class chunkMaker
|
||||
{
|
||||
private:
|
||||
uint64 s_full, s_chunk, offset;
|
||||
|
||||
public:
|
||||
/*! Creates an object that produces chunk information for \a s_full_
|
||||
work items and a desired chunk size of \a s_chunk_. */
|
||||
chunkMaker (uint64 s_full_, uint64 s_chunk_)
|
||||
: s_full(s_full_), s_chunk(s_chunk_), offset(0) {}
|
||||
|
||||
/*! Returns the total number of chunks. */
|
||||
uint64 nchunks() const
|
||||
{ return (s_full+s_chunk-1)/s_chunk; }
|
||||
|
||||
/*! Returns the start index of the next chunk in \a start, and its size
|
||||
in \a size. If all chunks have been processed already, the return
|
||||
value is \a false, else \a true. */
|
||||
bool getNext (uint64 &start, uint64 &size)
|
||||
{
|
||||
using namespace std;
|
||||
if (offset>=s_full) return false;
|
||||
start=offset;
|
||||
size=min(s_chunk,s_full-offset);
|
||||
offset+=s_chunk;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/*! Tries to split \a inp into a white-space separated list of values of
|
||||
type \a T, and appends them to \a list. */
|
||||
template<typename T> void split (const std::string &inp, std::vector<T> &list);
|
||||
|
||||
/*! Resizes \a container to zero and releases its memory. Typically used for
|
||||
std::vector.
|
||||
Taken from http://www.gotw.ca/gotw/054.htm */
|
||||
template<typename T> inline void releaseMemory (T &container)
|
||||
{ T().swap(container); }
|
||||
|
||||
/*! Releases all unused memory that \a container might have. Typically used for
|
||||
std::vector.
|
||||
Taken from http://www.gotw.ca/gotw/054.htm */
|
||||
template<typename T> inline void shrinkToFit (T &container)
|
||||
{ T(container).swap(container); }
|
||||
|
||||
/*! Breaks the string \a inp into tokens separated by \a delim, and returns them
|
||||
in \a list. */
|
||||
void tokenize (const std::string &inp, char delim,
|
||||
std::vector<std::string> &list);
|
||||
|
||||
#endif
|
284
external/healpix/cxxsupport/datatypes.h
vendored
Normal file
284
external/healpix/cxxsupport/datatypes.h
vendored
Normal file
|
@ -0,0 +1,284 @@
|
|||
/*
|
||||
* This file is part of libcxxsupport.
|
||||
*
|
||||
* libcxxsupport is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libcxxsupport is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libcxxsupport; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*! \file datatypes.h
|
||||
* This file defines various platform-independent data types.
|
||||
* If any of the requested types is not available, compilation aborts
|
||||
* with an error (unfortunately a rather obscure one).
|
||||
*
|
||||
* Copyright (C) 2004, 2008, 2009, 2010 Max-Planck-Society
|
||||
* \author Martin Reinecke
|
||||
*/
|
||||
|
||||
#ifndef PLANCK_DATATYPES_H
|
||||
#define PLANCK_DATATYPES_H
|
||||
|
||||
#include <string>
|
||||
#include <cstddef>
|
||||
#include "error_handling.h"
|
||||
|
||||
// Template magic to select the proper data types. These templates
|
||||
// should not be used outside this file.
|
||||
|
||||
template <typename T, bool equalSize> struct sizeChooserHelper__
|
||||
{ typedef void TYPE; };
|
||||
|
||||
template <typename T> struct sizeChooserHelper__<T,true>
|
||||
{ typedef T TYPE; };
|
||||
|
||||
template <typename T1, typename T2, typename T3> struct sizeChooserHelper2__
|
||||
{ typedef T1 TYPE; };
|
||||
|
||||
template <typename T2, typename T3> struct sizeChooserHelper2__ <void, T2, T3>
|
||||
{ typedef T2 TYPE; };
|
||||
|
||||
template <typename T3> struct sizeChooserHelper2__ <void, void, T3>
|
||||
{ typedef T3 TYPE; };
|
||||
|
||||
template <> struct sizeChooserHelper2__ <void, void, void>
|
||||
{ };
|
||||
|
||||
template <int sz, typename T1, typename T2=char, typename T3=char>
|
||||
struct sizeChooser__
|
||||
{
|
||||
typedef typename sizeChooserHelper2__
|
||||
<typename sizeChooserHelper__<T1,sizeof(T1)==sz>::TYPE,
|
||||
typename sizeChooserHelper__<T2,sizeof(T2)==sz>::TYPE,
|
||||
typename sizeChooserHelper__<T3,sizeof(T3)==sz>::TYPE >::TYPE TYPE;
|
||||
};
|
||||
|
||||
typedef signed char int8;
|
||||
typedef unsigned char uint8;
|
||||
|
||||
typedef sizeChooser__<2, short, int>::TYPE
|
||||
int16;
|
||||
typedef sizeChooser__<2, unsigned short, unsigned int>::TYPE
|
||||
uint16;
|
||||
|
||||
typedef sizeChooser__<4, int, long, short>::TYPE
|
||||
int32;
|
||||
typedef sizeChooser__<4, unsigned int, unsigned long, unsigned short>::TYPE
|
||||
uint32;
|
||||
|
||||
typedef sizeChooser__<8, long, long long>::TYPE
|
||||
int64;
|
||||
typedef sizeChooser__<8, unsigned long, unsigned long long>::TYPE
|
||||
uint64;
|
||||
|
||||
typedef sizeChooser__<4, float, double>::TYPE
|
||||
float32;
|
||||
typedef sizeChooser__<8, double, long double>::TYPE
|
||||
float64;
|
||||
|
||||
/*! unsigned integer type which should be used for array sizes */
|
||||
typedef std::size_t tsize;
|
||||
/*! signed integer type which should be used for relative array indices */
|
||||
typedef std::ptrdiff_t tdiff;
|
||||
|
||||
/*! mapping of Planck data types to integer constants */
|
||||
enum PDT {
|
||||
PLANCK_INT8 = 0,
|
||||
PLANCK_UINT8 = 1,
|
||||
PLANCK_INT16 = 2,
|
||||
PLANCK_UINT16 = 3,
|
||||
PLANCK_INT32 = 4,
|
||||
PLANCK_UINT32 = 5,
|
||||
PLANCK_INT64 = 6,
|
||||
PLANCK_UINT64 = 7,
|
||||
PLANCK_FLOAT32 = 8,
|
||||
PLANCK_FLOAT64 = 9,
|
||||
PLANCK_BOOL = 10,
|
||||
PLANCK_STRING = 11,
|
||||
PLANCK_INVALID = -1 };
|
||||
|
||||
/*! Returns the \a PDT constant associated with \a T. */
|
||||
template<typename T> inline PDT planckType();
|
||||
template<> inline PDT planckType<int8> () { return PLANCK_INT8; }
|
||||
template<> inline PDT planckType<uint8> () { return PLANCK_UINT8; }
|
||||
template<> inline PDT planckType<int16> () { return PLANCK_INT16; }
|
||||
template<> inline PDT planckType<uint16> () { return PLANCK_UINT16; }
|
||||
template<> inline PDT planckType<int32> () { return PLANCK_INT32; }
|
||||
template<> inline PDT planckType<uint32> () { return PLANCK_UINT32; }
|
||||
template<> inline PDT planckType<int64> () { return PLANCK_INT64; }
|
||||
template<> inline PDT planckType<uint64> () { return PLANCK_UINT64; }
|
||||
template<> inline PDT planckType<float32> () { return PLANCK_FLOAT32;}
|
||||
template<> inline PDT planckType<float64> () { return PLANCK_FLOAT64;}
|
||||
template<> inline PDT planckType<bool> () { return PLANCK_BOOL; }
|
||||
template<> inline PDT planckType<std::string>() { return PLANCK_STRING; }
|
||||
|
||||
/*! Returns the size (in bytes) of the Planck data type \a type. */
|
||||
inline int type2size (PDT type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case PLANCK_INT8 :
|
||||
case PLANCK_UINT8 :
|
||||
case PLANCK_BOOL :
|
||||
case PLANCK_STRING : return 1;
|
||||
case PLANCK_INT16 :
|
||||
case PLANCK_UINT16 : return 2;
|
||||
case PLANCK_INT32 :
|
||||
case PLANCK_UINT32 :
|
||||
case PLANCK_FLOAT32: return 4;
|
||||
case PLANCK_INT64 :
|
||||
case PLANCK_UINT64 :
|
||||
case PLANCK_FLOAT64: return 8;
|
||||
default:
|
||||
planck_fail ("type2size: unsupported data type");
|
||||
}
|
||||
}
|
||||
|
||||
/*! Converts the string \a type to a \a PDT. */
|
||||
inline PDT string2type(const std::string &type)
|
||||
{
|
||||
if (type=="FLOAT64") return PLANCK_FLOAT64;
|
||||
if (type=="FLOAT32") return PLANCK_FLOAT32;
|
||||
if (type=="INT8") return PLANCK_INT8;
|
||||
if (type=="UINT8") return PLANCK_UINT8;
|
||||
if (type=="INT16") return PLANCK_INT16;
|
||||
if (type=="UINT16") return PLANCK_UINT16;
|
||||
if (type=="INT32") return PLANCK_INT32;
|
||||
if (type=="UINT32") return PLANCK_UINT32;
|
||||
if (type=="INT64") return PLANCK_INT64;
|
||||
if (type=="UINT64") return PLANCK_UINT64;
|
||||
if (type=="BOOL") return PLANCK_BOOL;
|
||||
if (type=="STRING") return PLANCK_STRING;
|
||||
planck_fail ("string2type: unknown data type '"+type+"'");
|
||||
}
|
||||
|
||||
/*! Converts the Planck data type \a type to a C string. */
|
||||
inline const char *type2string (PDT type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case PLANCK_INT8 : return "INT8";
|
||||
case PLANCK_UINT8 : return "UINT8";
|
||||
case PLANCK_INT16 : return "INT16";
|
||||
case PLANCK_UINT16 : return "UINT16";
|
||||
case PLANCK_INT32 : return "INT32";
|
||||
case PLANCK_UINT32 : return "UINT32";
|
||||
case PLANCK_INT64 : return "INT64";
|
||||
case PLANCK_UINT64 : return "UINT64";
|
||||
case PLANCK_FLOAT32: return "FLOAT32";
|
||||
case PLANCK_FLOAT64: return "FLOAT64";
|
||||
case PLANCK_BOOL : return "BOOL";
|
||||
case PLANCK_STRING : return "STRING";
|
||||
default:
|
||||
planck_fail ("type2string: unsupported data type");
|
||||
}
|
||||
}
|
||||
|
||||
/*! Returns a C string describing the data type \a T. */
|
||||
template<typename T> inline const char *type2typename ();
|
||||
template<> inline const char *type2typename<signed char> ()
|
||||
{ return "signed char"; }
|
||||
template<> inline const char *type2typename<unsigned char> ()
|
||||
{ return "unsigned char"; }
|
||||
template<> inline const char *type2typename<short> ()
|
||||
{ return "short"; }
|
||||
template<> inline const char *type2typename<unsigned short> ()
|
||||
{ return "unsigned short"; }
|
||||
template<> inline const char *type2typename<int> ()
|
||||
{ return "int"; }
|
||||
template<> inline const char *type2typename<unsigned int> ()
|
||||
{ return "unsigned int"; }
|
||||
template<> inline const char *type2typename<long> ()
|
||||
{ return "long"; }
|
||||
template<> inline const char *type2typename<unsigned long> ()
|
||||
{ return "unsigned long"; }
|
||||
template<> inline const char *type2typename<long long> ()
|
||||
{ return "long long"; }
|
||||
template<> inline const char *type2typename<unsigned long long> ()
|
||||
{ return "unsigned long long"; }
|
||||
template<> inline const char *type2typename<float> ()
|
||||
{ return "float"; }
|
||||
template<> inline const char *type2typename<double> ()
|
||||
{ return "double"; }
|
||||
template<> inline const char *type2typename<bool> ()
|
||||
{ return "bool"; }
|
||||
template<> inline const char *type2typename<std::string> ()
|
||||
{ return "std::string"; }
|
||||
|
||||
/*! mapping of "native" data types to integer constants */
|
||||
enum NDT {
|
||||
NAT_CHAR,
|
||||
NAT_SCHAR,
|
||||
NAT_UCHAR,
|
||||
NAT_SHORT,
|
||||
NAT_USHORT,
|
||||
NAT_INT,
|
||||
NAT_UINT,
|
||||
NAT_LONG,
|
||||
NAT_ULONG,
|
||||
NAT_LONGLONG,
|
||||
NAT_ULONGLONG,
|
||||
NAT_FLOAT,
|
||||
NAT_DOUBLE,
|
||||
NAT_LONGDOUBLE,
|
||||
NAT_BOOL };
|
||||
|
||||
/*! Returns the \a NDT constant associated with \a T. */
|
||||
template<typename T> inline NDT nativeType();
|
||||
template<> inline NDT nativeType<char> () { return NAT_CHAR; }
|
||||
template<> inline NDT nativeType<signed char> () { return NAT_SCHAR; }
|
||||
template<> inline NDT nativeType<unsigned char> () { return NAT_UCHAR; }
|
||||
template<> inline NDT nativeType<short> () { return NAT_SHORT; }
|
||||
template<> inline NDT nativeType<unsigned short> () { return NAT_USHORT; }
|
||||
template<> inline NDT nativeType<int> () { return NAT_INT; }
|
||||
template<> inline NDT nativeType<unsigned int> () { return NAT_UINT; }
|
||||
template<> inline NDT nativeType<long> () { return NAT_LONG; }
|
||||
template<> inline NDT nativeType<unsigned long> () { return NAT_ULONG; }
|
||||
template<> inline NDT nativeType<long long> () { return NAT_LONGLONG; }
|
||||
template<> inline NDT nativeType<unsigned long long>() { return NAT_ULONGLONG; }
|
||||
template<> inline NDT nativeType<float> () { return NAT_FLOAT; }
|
||||
template<> inline NDT nativeType<double> () { return NAT_DOUBLE; }
|
||||
template<> inline NDT nativeType<long double> () { return NAT_LONGDOUBLE;}
|
||||
template<> inline NDT nativeType<bool> () { return NAT_BOOL; }
|
||||
|
||||
/*! Returns the size (in bytes) of the native data type \a type. */
|
||||
inline int ndt2size (NDT type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case NAT_CHAR :
|
||||
case NAT_SCHAR :
|
||||
case NAT_UCHAR : return sizeof(char);
|
||||
case NAT_SHORT :
|
||||
case NAT_USHORT : return sizeof(short);
|
||||
case NAT_INT :
|
||||
case NAT_UINT : return sizeof(int);
|
||||
case NAT_LONG :
|
||||
case NAT_ULONG : return sizeof(long);
|
||||
case NAT_LONGLONG :
|
||||
case NAT_ULONGLONG : return sizeof(long long);
|
||||
case NAT_FLOAT : return sizeof(float);
|
||||
case NAT_DOUBLE : return sizeof(double);
|
||||
case NAT_LONGDOUBLE: return sizeof(long double);
|
||||
case NAT_BOOL : return sizeof(bool);
|
||||
default:
|
||||
planck_fail ("ndt2size: unsupported data type");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
56
external/healpix/cxxsupport/error_handling.cc
vendored
Normal file
56
external/healpix/cxxsupport/error_handling.cc
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* This file is part of libcxxsupport.
|
||||
*
|
||||
* libcxxsupport is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libcxxsupport is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libcxxsupport; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Utilities for error reporting
|
||||
*
|
||||
* Copyright (C) 2003 - 2010 Max-Planck-Society
|
||||
* Author: Martin Reinecke
|
||||
*/
|
||||
|
||||
#include "error_handling.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
PlanckError::PlanckError(const string &message) : msg (message) {}
|
||||
PlanckError::PlanckError(const char *message) : msg (message) {}
|
||||
|
||||
void planck_failure__(const char *file, int line, const char *func,
|
||||
const string &msg)
|
||||
{
|
||||
cerr << "Error encountered at " << file << ", line " << line << endl;
|
||||
if (func) cerr << "(function " << func << ")" << endl;
|
||||
if (msg!="") cerr << endl << msg << endl;
|
||||
cerr << endl;
|
||||
}
|
||||
|
||||
void planck_failure__(const char *file, int line, const char *func,
|
||||
const char *msg)
|
||||
{ planck_failure__ (file,line,func,string(msg)); }
|
||||
|
||||
void killjob__()
|
||||
{ throw; }
|
100
external/healpix/cxxsupport/error_handling.h
vendored
Normal file
100
external/healpix/cxxsupport/error_handling.h
vendored
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* This file is part of libcxxsupport.
|
||||
*
|
||||
* libcxxsupport is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libcxxsupport is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libcxxsupport; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Utilities for error reporting
|
||||
*
|
||||
* Copyright (C) 2003 - 2010 Max-Planck-Society
|
||||
* Authors: Reinhard Hell, Martin Reinecke
|
||||
*/
|
||||
|
||||
#ifndef PLANCK_ERROR_HANDLING_H
|
||||
#define PLANCK_ERROR_HANDLING_H
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#if defined (__GNUC__)
|
||||
#define PLANCK_FUNC_NAME__ __PRETTY_FUNCTION__
|
||||
#else
|
||||
#define PLANCK_FUNC_NAME__ 0
|
||||
#endif
|
||||
|
||||
void planck_failure__(const char *file, int line, const char *func,
|
||||
const std::string &msg);
|
||||
void planck_failure__(const char *file, int line, const char *func,
|
||||
const char *msg);
|
||||
void killjob__();
|
||||
|
||||
class PlanckError
|
||||
{
|
||||
private:
|
||||
std::string msg;
|
||||
|
||||
public:
|
||||
explicit PlanckError(const std::string &message);
|
||||
explicit PlanckError(const char *message);
|
||||
|
||||
virtual const char* what() const
|
||||
{ return msg.c_str(); }
|
||||
|
||||
virtual ~PlanckError() {}
|
||||
};
|
||||
|
||||
/*! \defgroup errorgroup Error handling */
|
||||
/*! \{ */
|
||||
|
||||
/*! Writes diagnostic output and exits with an error status. */
|
||||
#define planck_fail(msg) \
|
||||
do { planck_failure__(__FILE__,__LINE__,PLANCK_FUNC_NAME__,msg); \
|
||||
throw PlanckError(msg); } while(0)
|
||||
|
||||
/*! Throws a PlanckError without diagnostic message. */
|
||||
#define planck_fail_quietly(msg) \
|
||||
do { throw PlanckError(msg); } while(0)
|
||||
|
||||
/*! Writes diagnostic output and exits with an error status if \a testval
|
||||
is \a false. */
|
||||
#define planck_assert(testval,msg) \
|
||||
do { if (testval); else planck_fail(msg); } while(0)
|
||||
|
||||
/*! Macro for improving error diagnostics. Should be placed immediately
|
||||
after the opening brace of \c main(). Must be used in conjunction with
|
||||
\c PLANCK_DIAGNOSIS_END. */
|
||||
#define PLANCK_DIAGNOSIS_BEGIN try {
|
||||
/*! Macro for improving error diagnostics. Should be placed immediately
|
||||
before the closing brace of \c main(). Must be used in conjunction with
|
||||
\c PLANCK_DIAGNOSIS_BEGIN. */
|
||||
#define PLANCK_DIAGNOSIS_END \
|
||||
} \
|
||||
catch (PlanckError &) \
|
||||
{ killjob__(); /* no need for further diagnostics; they were shown already */ } \
|
||||
catch (std::exception &e) \
|
||||
{ std::cerr << "std::exception: " << e.what() << std::endl; killjob__(); } \
|
||||
catch (...) \
|
||||
{ std::cerr << "Unknown exception" << std::endl; killjob__(); }
|
||||
|
||||
/*! \} */
|
||||
|
||||
#endif
|
109
external/healpix/cxxsupport/fftpack_support.h
vendored
Normal file
109
external/healpix/cxxsupport/fftpack_support.h
vendored
Normal file
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* This file is part of libcxxsupport.
|
||||
*
|
||||
* libcxxsupport is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libcxxsupport is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libcxxsupport; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2004-2010 Max-Planck-Society
|
||||
* \author Martin Reinecke
|
||||
*/
|
||||
|
||||
#ifndef PLANCK_FFTPACK_SUPPORT_H
|
||||
#define PLANCK_FFTPACK_SUPPORT_H
|
||||
|
||||
#include "ls_fft.h"
|
||||
#include "arr.h"
|
||||
#include "xcomplex.h"
|
||||
|
||||
class cfft
|
||||
{
|
||||
private:
|
||||
tsize n;
|
||||
complex_plan plan;
|
||||
|
||||
public:
|
||||
cfft () : n(0), plan(0) {}
|
||||
cfft (tsize size_)
|
||||
: n(size_), plan(make_complex_plan(size_)) {}
|
||||
~cfft ()
|
||||
{ if (plan!=0) kill_complex_plan (plan); }
|
||||
void Set (tsize size_)
|
||||
{
|
||||
if (plan!=0) kill_complex_plan (plan);
|
||||
n=size_;
|
||||
plan=make_complex_plan(size_);
|
||||
}
|
||||
|
||||
tsize size() const
|
||||
{ return n; }
|
||||
|
||||
void forward (double *data)
|
||||
{ complex_plan_forward(plan,data); }
|
||||
void backward (double *data)
|
||||
{ complex_plan_backward(plan,data); }
|
||||
void forward (xcomplex<double> *data)
|
||||
{ complex_plan_forward(plan,&(data->re)); }
|
||||
void backward (xcomplex<double> *data)
|
||||
{ complex_plan_backward(plan,&(data->re)); }
|
||||
void forward (arr<xcomplex<double> >&data)
|
||||
{ forward(&(data[0].re)); }
|
||||
void backward (arr<xcomplex<double> >&data)
|
||||
{ backward(&(data[0].re)); }
|
||||
};
|
||||
|
||||
class rfft
|
||||
{
|
||||
private:
|
||||
tsize n;
|
||||
real_plan plan;
|
||||
|
||||
public:
|
||||
rfft () : n(0), plan(0) {}
|
||||
rfft (tsize size_)
|
||||
: n(size_), plan(make_real_plan(size_)) {}
|
||||
~rfft ()
|
||||
{ if (plan!=0) kill_real_plan (plan); }
|
||||
void Set (tsize size_)
|
||||
{
|
||||
if (plan!=0) kill_real_plan (plan);
|
||||
n=size_;
|
||||
plan=make_real_plan(size_);
|
||||
}
|
||||
|
||||
tsize size() const
|
||||
{ return n; }
|
||||
|
||||
void forward_fftpack (double *data)
|
||||
{ real_plan_forward_fftpack(plan,data); }
|
||||
void backward_fftpack (double *data)
|
||||
{ real_plan_backward_fftpack(plan,data); }
|
||||
void forward_fftpack (arr<double> &data)
|
||||
{ forward_fftpack(&(data[0])); }
|
||||
void backward_fftpack (arr<double> &data)
|
||||
{ backward_fftpack(&(data[0])); }
|
||||
void forward_c (arr<xcomplex<double> >&data)
|
||||
{ real_plan_forward_c(plan,&(data[0].re)); }
|
||||
void backward_c (arr<xcomplex<double> >&data)
|
||||
{ real_plan_backward_c(plan,&(data[0].re)); }
|
||||
};
|
||||
|
||||
#endif
|
792
external/healpix/cxxsupport/fitshandle.cc
vendored
Normal file
792
external/healpix/cxxsupport/fitshandle.cc
vendored
Normal file
|
@ -0,0 +1,792 @@
|
|||
/*
|
||||
* This file is part of libcxxsupport.
|
||||
*
|
||||
* libcxxsupport is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libcxxsupport is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libcxxsupport; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file contains the implementation of the FITS I/O helper class
|
||||
* used by the Planck LevelS package.
|
||||
*
|
||||
* Copyright (C) 2002 - 2009 Max-Planck-Society
|
||||
* Author: Martin Reinecke
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
#include "fitsio.h"
|
||||
#include "fitshandle.h"
|
||||
#include "cxxutils.h"
|
||||
#include "safe_cast.h"
|
||||
|
||||
#define FPTR (static_cast<fitsfile *> (fptr))
|
||||
#define OFPTR (static_cast<fitsfile *> (orig.fptr))
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace {
|
||||
|
||||
template<typename T> inline int fitsType();
|
||||
template<> inline int fitsType<float> () { return TFLOAT; }
|
||||
template<> inline int fitsType<double>() { return TDOUBLE; }
|
||||
|
||||
int type2bitpix (PDT type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case PLANCK_FLOAT32: return FLOAT_IMG;
|
||||
case PLANCK_FLOAT64: return DOUBLE_IMG;
|
||||
default: planck_fail ("unsupported component type");
|
||||
}
|
||||
}
|
||||
|
||||
/*! Converts a FITS type code (i.e. the data type of a FITS column) to the
|
||||
corresponding Planck type code. */
|
||||
PDT ftc2type (int ftc)
|
||||
{
|
||||
switch (ftc)
|
||||
{
|
||||
case TLOGICAL : return PLANCK_BOOL;
|
||||
case TBYTE : return PLANCK_INT8;
|
||||
case TSHORT : return PLANCK_INT16;
|
||||
case TINT :
|
||||
case TINT32BIT: return PLANCK_INT32;
|
||||
case TLONGLONG: return PLANCK_INT64;
|
||||
case TFLOAT : return PLANCK_FLOAT32;
|
||||
case TDOUBLE : return PLANCK_FLOAT64;
|
||||
case TSTRING : return PLANCK_STRING;
|
||||
default: planck_fail ("unsupported component type");
|
||||
}
|
||||
}
|
||||
|
||||
/*! Converts a Planck type code to the corresponding FITS type code
|
||||
(i.e. the data type of a FITS column). */
|
||||
int type2ftc (PDT type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case PLANCK_BOOL : return TLOGICAL;
|
||||
case PLANCK_INT8 :
|
||||
case PLANCK_UINT8 : return TBYTE;
|
||||
case PLANCK_INT16 : return TSHORT;
|
||||
case PLANCK_INT32 : return TINT;
|
||||
case PLANCK_INT64 : return TLONGLONG;
|
||||
case PLANCK_FLOAT32: return TFLOAT;
|
||||
case PLANCK_FLOAT64: return TDOUBLE;
|
||||
case PLANCK_STRING : return TSTRING;
|
||||
default: planck_fail ("unsupported component type");
|
||||
}
|
||||
}
|
||||
|
||||
const char *type2fitschar (PDT type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case PLANCK_BOOL : return "L";
|
||||
case PLANCK_FLOAT32: return "E";
|
||||
case PLANCK_FLOAT64: return "D";
|
||||
case PLANCK_INT8 :
|
||||
case PLANCK_UINT8 : return "B";
|
||||
case PLANCK_INT16 : return "I";
|
||||
case PLANCK_INT32 : return "J";
|
||||
case PLANCK_INT64 : return "K";
|
||||
case PLANCK_STRING : return "A";
|
||||
default:
|
||||
planck_fail(string("unknown data type ")+type2string(type));
|
||||
}
|
||||
}
|
||||
|
||||
const char *type2asciiform (PDT type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case PLANCK_FLOAT32: return "E14.7";
|
||||
case PLANCK_FLOAT64: return "D23.15";
|
||||
case PLANCK_UINT8 : return "I3";
|
||||
case PLANCK_INT8 : return "I4";
|
||||
case PLANCK_INT16 : return "I6";
|
||||
case PLANCK_INT32 : return "I11";
|
||||
case PLANCK_INT64 : return "I22";
|
||||
default:
|
||||
planck_fail(string("unknown data type ")+type2string(type));
|
||||
}
|
||||
}
|
||||
|
||||
string fixkey (const string &key)
|
||||
{
|
||||
for (tsize m=0; m<key.size(); ++m)
|
||||
if (islower(key[m])) return string("HIERARCH "+key);
|
||||
|
||||
return key;
|
||||
}
|
||||
} // unnamed namespace
|
||||
|
||||
fitscolumn::fitscolumn()
|
||||
: repcount_(0), type_(PLANCK_INVALID) {}
|
||||
|
||||
fitscolumn::fitscolumn (const string &nm, const string &un, int64 rc, PDT tp)
|
||||
: name_(nm), unit_(un), repcount_(rc), type_(tp) {}
|
||||
|
||||
void fitshandle::check_errors() const
|
||||
{
|
||||
char msg[81];
|
||||
if (status==0)
|
||||
{
|
||||
while (fits_read_errmsg(msg))
|
||||
cerr << "STALE FITS ERROR MESSAGE: " << msg << endl;
|
||||
fits_clear_errmsg();
|
||||
return;
|
||||
}
|
||||
fits_get_errstatus (status, msg);
|
||||
cerr << msg << endl;
|
||||
while (fits_read_errmsg(msg)) cerr << msg << endl;
|
||||
fits_clear_errmsg();
|
||||
status=0;
|
||||
planck_fail("FITS error");
|
||||
}
|
||||
|
||||
void fitshandle::clean_data()
|
||||
{
|
||||
if (!fptr) return;
|
||||
axes_.clear();
|
||||
columns_.clear();
|
||||
hdutype_=INVALID;
|
||||
bitpix_=INVALID;
|
||||
nrows_=0;
|
||||
}
|
||||
|
||||
void fitshandle::clean_all()
|
||||
{
|
||||
if (!fptr) return;
|
||||
clean_data();
|
||||
fits_close_file (FPTR, &status);
|
||||
check_errors();
|
||||
fptr=0;
|
||||
}
|
||||
|
||||
bool fitshandle::table_hdu (tsize col) const
|
||||
{
|
||||
if ((hdutype_!=ASCII_TBL) && (hdutype_!=BINARY_TBL)) return false;
|
||||
if ((col<=0) || (col>columns_.size())) return false;
|
||||
return true;
|
||||
}
|
||||
bool fitshandle::image_hdu () const
|
||||
{ return hdutype_==IMAGE_HDU; }
|
||||
|
||||
void fitshandle::init_image()
|
||||
{
|
||||
int naxis;
|
||||
fits_get_img_type (FPTR, &bitpix_, &status);
|
||||
fits_get_img_dim (FPTR, &naxis, &status);
|
||||
check_errors();
|
||||
arr<LONGLONG> naxes(naxis);
|
||||
fits_get_img_sizell (FPTR, naxis, &naxes[0], &status);
|
||||
for (long m=0; m<naxis; ++m) axes_.push_back(naxes[naxis-m-1]);
|
||||
check_errors();
|
||||
}
|
||||
|
||||
void fitshandle::init_asciitab()
|
||||
{
|
||||
char ttype[81], tunit[81], tform[81];
|
||||
int ncol, typecode;
|
||||
fits_get_num_cols (FPTR, &ncol, &status);
|
||||
{ LONGLONG tmp; fits_get_num_rowsll (FPTR, &tmp, &status); nrows_=tmp; }
|
||||
check_errors();
|
||||
for (int m=1; m<=ncol; ++m)
|
||||
{
|
||||
fits_get_acolparms (FPTR, m, ttype, 0, tunit, tform,
|
||||
0, 0, 0, 0, &status);
|
||||
fits_ascii_tform (tform, &typecode, 0,0, &status);
|
||||
check_errors();
|
||||
columns_.push_back (fitscolumn (ttype,tunit,1,ftc2type(typecode)));
|
||||
}
|
||||
}
|
||||
|
||||
void fitshandle::init_bintab()
|
||||
{
|
||||
char ttype[81], tunit[81], tform[81];
|
||||
LONGLONG repc;
|
||||
int ncol, typecode;
|
||||
fits_get_num_cols (FPTR, &ncol, &status);
|
||||
{ LONGLONG tmp; fits_get_num_rowsll (FPTR, &tmp, &status); nrows_=tmp; }
|
||||
check_errors();
|
||||
for (int m=1; m<=ncol; ++m)
|
||||
{
|
||||
fits_get_bcolparmsll (FPTR, m, ttype, tunit, tform, &repc,
|
||||
0, 0, 0, 0, &status);
|
||||
fits_binary_tform (tform, &typecode, 0,0, &status);
|
||||
check_errors();
|
||||
columns_.push_back (fitscolumn (ttype,tunit,repc,ftc2type(typecode)));
|
||||
}
|
||||
}
|
||||
|
||||
void fitshandle::init_data()
|
||||
{
|
||||
clean_data();
|
||||
fits_get_hdu_type (FPTR, &hdutype_, &status);
|
||||
check_errors();
|
||||
switch(hdutype_)
|
||||
{
|
||||
case IMAGE_HDU:
|
||||
init_image(); break;
|
||||
case ASCII_TBL:
|
||||
init_asciitab(); break;
|
||||
case BINARY_TBL:
|
||||
init_bintab(); break;
|
||||
default:
|
||||
planck_fail("init_data(): unsupported HDU type"); break;
|
||||
}
|
||||
}
|
||||
|
||||
void fitshandle::read_col (int colnum, void *data, int64 ndata, PDT type,
|
||||
int64 offset) const
|
||||
{
|
||||
planck_assert(table_hdu(colnum),"incorrect FITS table access");
|
||||
int64 repc = columns_[colnum-1].repcount();
|
||||
planck_assert (ndata<=(repc*nrows_-offset),"read_column(): array too large");
|
||||
int64 frow = offset/repc+1;
|
||||
int64 felem = offset%repc+1;
|
||||
fits_read_col (FPTR, type2ftc(type), colnum, frow, felem, ndata, 0, data, 0,
|
||||
&status);
|
||||
check_errors();
|
||||
}
|
||||
void fitshandle::write_col (int colnum, const void *data, int64 ndata,
|
||||
PDT type, int64 offset)
|
||||
{
|
||||
planck_assert(table_hdu(colnum),"incorrect FITS table access");
|
||||
int64 repc = columns_[colnum-1].repcount();
|
||||
int64 frow = offset/repc+1;
|
||||
int64 felem = offset%repc+1;
|
||||
fits_write_col (FPTR, type2ftc(type), colnum, frow, felem, ndata,
|
||||
const_cast<void *>(data), &status);
|
||||
nrows_ = max(nrows_,offset+ndata);
|
||||
check_errors();
|
||||
}
|
||||
|
||||
void fitshandle::getKeyHelper(const string &name) const
|
||||
{
|
||||
if (status==KEY_NO_EXIST)
|
||||
{
|
||||
fits_clear_errmsg();
|
||||
status=0;
|
||||
planck_fail("fitshandle::get_key(): key '"+name+"' not found");
|
||||
}
|
||||
check_errors();
|
||||
}
|
||||
|
||||
void fitshandle::open (const string &fname)
|
||||
{
|
||||
clean_all();
|
||||
fitsfile *ptr;
|
||||
fits_open_file(&ptr, fname.c_str(), READONLY, &status);
|
||||
fptr=ptr;
|
||||
check_errors();
|
||||
init_data();
|
||||
}
|
||||
|
||||
void fitshandle::create (const string &fname)
|
||||
{
|
||||
clean_all();
|
||||
fitsfile *ptr;
|
||||
fits_create_file(&ptr, fname.c_str(), &status);
|
||||
fptr=ptr;
|
||||
fits_write_imghdr(FPTR, 8, 0, 0, &status); // insert empty PHDU
|
||||
fits_write_date(FPTR, &status);
|
||||
check_errors();
|
||||
init_data();
|
||||
}
|
||||
|
||||
// static
|
||||
void fitshandle::delete_file (const string &name)
|
||||
{
|
||||
fitsfile *ptr;
|
||||
int stat = 0;
|
||||
fits_open_file(&ptr, name.c_str(), READWRITE, &stat);
|
||||
fits_delete_file(ptr, &stat);
|
||||
if (stat==0) return;
|
||||
|
||||
char msg[81];
|
||||
fits_get_errstatus (stat, msg);
|
||||
cerr << msg << endl;
|
||||
while (fits_read_errmsg(msg)) cerr << msg << endl;
|
||||
planck_fail("FITS error");
|
||||
}
|
||||
|
||||
void fitshandle::goto_hdu (int hdu)
|
||||
{
|
||||
int curhdu;
|
||||
fits_get_hdu_num(FPTR,&curhdu);
|
||||
if (curhdu!=hdu)
|
||||
{
|
||||
fits_movabs_hdu(FPTR, hdu, &hdutype_, &status);
|
||||
check_errors();
|
||||
init_data();
|
||||
}
|
||||
}
|
||||
|
||||
int fitshandle::num_hdus () const
|
||||
{
|
||||
int result;
|
||||
fits_get_num_hdus (FPTR, &result, &status);
|
||||
check_errors();
|
||||
return result;
|
||||
}
|
||||
|
||||
void fitshandle::insert_bintab (const vector<fitscolumn> &cols,
|
||||
const string &extname)
|
||||
{
|
||||
clean_data();
|
||||
int ncol=cols.size();
|
||||
arr2b<char> ttype(ncol,81), tform(ncol,81), tunit(ncol,81);
|
||||
|
||||
for (long m=0; m<ncol; ++m)
|
||||
{
|
||||
strcpy (ttype[m], cols[m].name().c_str());
|
||||
strcpy (tunit[m], cols[m].unit().c_str());
|
||||
ostringstream x;
|
||||
x << cols[m].repcount() << type2fitschar(cols[m].type());
|
||||
strcpy (tform[m], x.str().c_str());
|
||||
}
|
||||
fits_insert_btbl (FPTR, nrows_, ncol, ttype.p0(), tform.p0(), tunit.p0(),
|
||||
const_cast<char *>(extname.c_str()), 0, &status);
|
||||
check_errors();
|
||||
init_data();
|
||||
}
|
||||
|
||||
void fitshandle::insert_asctab (const vector<fitscolumn> &cols,
|
||||
const string &extname)
|
||||
{
|
||||
clean_data();
|
||||
int ncol=cols.size();
|
||||
arr2b<char> ttype(ncol,81), tform(ncol,81), tunit(ncol,81);
|
||||
|
||||
for (long m=0; m<ncol; ++m)
|
||||
{
|
||||
strcpy (ttype[m], cols[m].name().c_str());
|
||||
strcpy (tunit[m], cols[m].unit().c_str());
|
||||
ostringstream x;
|
||||
if (cols[m].type()!=TSTRING)
|
||||
{
|
||||
planck_assert (cols[m].repcount()==1,"bad repcount for ASCII table");
|
||||
x << type2asciiform(cols[m].type());
|
||||
}
|
||||
else
|
||||
{
|
||||
x << "A" << dataToString(cols[m].repcount());
|
||||
}
|
||||
strcpy (tform[m], x.str().c_str());
|
||||
}
|
||||
fits_insert_atbl (FPTR, 0, nrows_, ncol, ttype.p0(), 0, tform.p0(),
|
||||
tunit.p0(), const_cast<char *>(extname.c_str()), &status);
|
||||
check_errors();
|
||||
init_data();
|
||||
}
|
||||
|
||||
void fitshandle::insert_image (PDT type, const vector<int64> &Axes)
|
||||
{
|
||||
clean_data();
|
||||
arr<LONGLONG> tmpax(Axes.size());
|
||||
for (long m=0; m<long(Axes.size()); m++) tmpax[m]=Axes[Axes.size()-1-m];
|
||||
fits_insert_imgll (FPTR, type2bitpix(type), Axes.size(), &tmpax[0], &status);
|
||||
check_errors();
|
||||
init_data();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void fitshandle::insert_image (PDT type, const arr2<T> &data)
|
||||
{
|
||||
clean_data();
|
||||
arr<LONGLONG> tmpax(2);
|
||||
tmpax[0] = data.size2(); tmpax[1] = data.size1();
|
||||
fits_insert_imgll (FPTR, type2bitpix(type), 2, &tmpax[0], &status);
|
||||
arr2<T> &tmparr = const_cast<arr2<T> &> (data);
|
||||
fits_write_img (FPTR, fitsType<T>(), 1, tmpax[0]*tmpax[1],
|
||||
&tmparr[0][0], &status);
|
||||
check_errors();
|
||||
init_data();
|
||||
}
|
||||
|
||||
template void fitshandle::insert_image (PDT type, const arr2<double> &data);
|
||||
template void fitshandle::insert_image (PDT type, const arr2<float> &data);
|
||||
|
||||
void fitshandle::write_checksum()
|
||||
{
|
||||
planck_assert(connected(),"handle not connected to a file");
|
||||
fits_write_chksum (FPTR, &status);
|
||||
check_errors();
|
||||
}
|
||||
|
||||
const vector<int64> &fitshandle::axes() const
|
||||
{
|
||||
planck_assert(image_hdu(),"not connected to an image");
|
||||
return axes_;
|
||||
}
|
||||
const string &fitshandle::colname(int i) const
|
||||
{
|
||||
planck_assert(table_hdu(i),"incorrect FITS table access");
|
||||
return columns_[i-1].name();
|
||||
}
|
||||
const string &fitshandle::colunit(int i) const
|
||||
{
|
||||
planck_assert(table_hdu(i),"incorrect FITS table access");
|
||||
return columns_[i-1].unit();
|
||||
}
|
||||
int64 fitshandle::repcount(int i) const
|
||||
{
|
||||
planck_assert(table_hdu(i),"incorrect FITS table access");
|
||||
return columns_[i-1].repcount();
|
||||
}
|
||||
PDT fitshandle::coltype(int i) const
|
||||
{
|
||||
planck_assert(table_hdu(i),"incorrect FITS table access");
|
||||
return columns_[i-1].type();
|
||||
}
|
||||
int fitshandle::ncols() const
|
||||
{
|
||||
planck_assert(table_hdu(1),"incorrect FITS table access");
|
||||
return columns_.size();
|
||||
}
|
||||
int64 fitshandle::nrows() const
|
||||
{
|
||||
planck_assert(table_hdu(1),"incorrect FITS table access");
|
||||
return nrows_;
|
||||
}
|
||||
int64 fitshandle::nelems(int i) const
|
||||
{
|
||||
planck_assert(table_hdu(i),"incorrect FITS table access");
|
||||
if (columns_[i-1].type()==PLANCK_STRING) return nrows_;
|
||||
return nrows_*columns_[i-1].repcount();
|
||||
}
|
||||
int64 fitshandle::efficientChunkSize(int i) const
|
||||
{
|
||||
planck_assert(table_hdu(1),"incorrect FITS table access");
|
||||
long int res;
|
||||
fits_get_rowsize(FPTR, &res, &status);
|
||||
planck_assert(res>=1,"bad recommended FITS chunk size");
|
||||
check_errors();
|
||||
return res*columns_[i-1].repcount();
|
||||
}
|
||||
|
||||
void fitshandle::get_all_keys(vector<string> &keys) const
|
||||
{
|
||||
keys.clear();
|
||||
char card[81];
|
||||
const char *inclist[] = { "*" };
|
||||
planck_assert(connected(),"handle not connected to a file");
|
||||
fits_read_record (FPTR, 0, card, &status);
|
||||
check_errors();
|
||||
while (true)
|
||||
{
|
||||
fits_find_nextkey (FPTR, const_cast<char **>(inclist), 1,
|
||||
0, 0, card, &status);
|
||||
if (status!=0) break;
|
||||
if (fits_get_keyclass(card)==TYP_USER_KEY)
|
||||
{
|
||||
char keyname[80];
|
||||
int dummy;
|
||||
fits_get_keyname(card, keyname, &dummy, &status);
|
||||
check_errors();
|
||||
keys.push_back(trim(keyname));
|
||||
}
|
||||
check_errors();
|
||||
}
|
||||
if (status==KEY_NO_EXIST) { fits_clear_errmsg(); status=0; }
|
||||
check_errors();
|
||||
}
|
||||
|
||||
void fitshandle::set_key_void (const string &key, const void *value,
|
||||
PDT type, const string &comment)
|
||||
{
|
||||
planck_assert(connected(),"handle not connected to a file");
|
||||
string key2 = fixkey(key);
|
||||
switch (type)
|
||||
{
|
||||
case PLANCK_INT8:
|
||||
case PLANCK_UINT8:
|
||||
case PLANCK_INT16:
|
||||
case PLANCK_INT32:
|
||||
case PLANCK_INT64:
|
||||
case PLANCK_FLOAT32:
|
||||
case PLANCK_FLOAT64:
|
||||
fits_update_key (FPTR, type2ftc(type), const_cast<char *>(key2.c_str()),
|
||||
const_cast<void *>(value), const_cast<char *>(comment.c_str()),
|
||||
&status);
|
||||
break;
|
||||
case PLANCK_BOOL:
|
||||
{
|
||||
int val = *(static_cast<const bool *>(value));
|
||||
fits_update_key (FPTR, TLOGICAL, const_cast<char *>(key2.c_str()),
|
||||
&val, const_cast<char *>(comment.c_str()), &status);
|
||||
break;
|
||||
}
|
||||
case PLANCK_STRING:
|
||||
{
|
||||
string val = *(static_cast<const string *>(value));
|
||||
fits_update_key_longstr (FPTR, const_cast<char *>(key2.c_str()),
|
||||
const_cast<char *>(val.c_str()), const_cast<char *>(comment.c_str()),
|
||||
&status);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
planck_fail ("unsupported data type in set_key_void()");
|
||||
}
|
||||
check_errors();
|
||||
}
|
||||
|
||||
void fitshandle::get_key_void (const string &name, void *value, PDT type) const
|
||||
{
|
||||
planck_assert(connected(),"handle not connected to a file");
|
||||
switch (type)
|
||||
{
|
||||
case PLANCK_INT8:
|
||||
case PLANCK_UINT8:
|
||||
case PLANCK_INT16:
|
||||
case PLANCK_INT32:
|
||||
case PLANCK_INT64:
|
||||
case PLANCK_FLOAT32:
|
||||
case PLANCK_FLOAT64:
|
||||
fits_read_key (FPTR, type2ftc(type), const_cast<char *>(name.c_str()),
|
||||
value, 0, &status);
|
||||
getKeyHelper(name);
|
||||
break;
|
||||
case PLANCK_BOOL:
|
||||
{
|
||||
int val;
|
||||
fits_read_key (FPTR, TLOGICAL, const_cast<char *>(name.c_str()), &val, 0,
|
||||
&status);
|
||||
getKeyHelper(name);
|
||||
*(static_cast<bool *>(value))=val;
|
||||
break;
|
||||
}
|
||||
case PLANCK_STRING:
|
||||
{
|
||||
char *tmp=0;
|
||||
fits_read_key_longstr (FPTR, const_cast<char *>(name.c_str()), &tmp, 0,
|
||||
&status);
|
||||
getKeyHelper(name);
|
||||
*(static_cast<string *>(value))=tmp;
|
||||
if (tmp) free(tmp);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
planck_fail ("unsupported data type in get_key_void()");
|
||||
}
|
||||
check_errors();
|
||||
}
|
||||
|
||||
void fitshandle::delete_key (const string &name)
|
||||
{
|
||||
planck_assert(connected(),"handle not connected to a file");
|
||||
fits_delete_key (FPTR, const_cast<char *>(name.c_str()), &status);
|
||||
check_errors();
|
||||
}
|
||||
|
||||
void fitshandle::add_comment(const string &comment)
|
||||
{
|
||||
planck_assert(connected(),"handle not connected to a file");
|
||||
fits_write_comment(FPTR,const_cast<char *>(comment.c_str()),&status);
|
||||
check_errors();
|
||||
}
|
||||
|
||||
bool fitshandle::key_present(const string &name) const
|
||||
{
|
||||
char card[81];
|
||||
planck_assert(connected(),"handle not connected to a file");
|
||||
fits_read_card(FPTR, const_cast<char *>(name.c_str()), card, &status);
|
||||
if (status==KEY_NO_EXIST)
|
||||
{ fits_clear_errmsg(); status=0; return false; }
|
||||
check_errors();
|
||||
return true;
|
||||
}
|
||||
|
||||
void fitshandle::assert_pdmtype (const string &pdmtype) const
|
||||
{
|
||||
string type;
|
||||
get_key("PDMTYPE",type);
|
||||
if (pdmtype==type) return;
|
||||
cerr << "PDMTYPE " << pdmtype << " expected, but found " << type << endl;
|
||||
}
|
||||
|
||||
void fitshandle::read_column_raw_void
|
||||
(int colnum, void *data, PDT type, int64 num, int64 offset) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case PLANCK_INT8:
|
||||
case PLANCK_UINT8:
|
||||
case PLANCK_INT16:
|
||||
case PLANCK_INT32:
|
||||
case PLANCK_INT64:
|
||||
case PLANCK_FLOAT32:
|
||||
case PLANCK_FLOAT64:
|
||||
case PLANCK_BOOL:
|
||||
read_col (colnum, data, num, type, offset); break;
|
||||
case PLANCK_STRING:
|
||||
{
|
||||
string *data2 = static_cast<string *> (data);
|
||||
planck_assert(table_hdu(colnum),"incorrect FITS table access");
|
||||
planck_assert (num<=(nrows_-offset),
|
||||
"read_column(): array too large");
|
||||
arr2b<char> tdata(safe_cast<tsize>(num),
|
||||
safe_cast<tsize>(columns_[colnum-1].repcount()+1));
|
||||
fits_read_col (FPTR, TSTRING, colnum, offset+1, 1, num,
|
||||
0, tdata.p0(), 0, &status);
|
||||
check_errors();
|
||||
for (long m=0;m<num;++m) data2[m]=tdata[m];
|
||||
break;
|
||||
}
|
||||
default:
|
||||
planck_fail ("unsupported data type in read_column_raw_void()");
|
||||
}
|
||||
}
|
||||
|
||||
void fitshandle::write_column_raw_void
|
||||
(int colnum, const void *data, PDT type, int64 num, int64 offset)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case PLANCK_INT8:
|
||||
case PLANCK_UINT8:
|
||||
case PLANCK_INT16:
|
||||
case PLANCK_INT32:
|
||||
case PLANCK_INT64:
|
||||
case PLANCK_FLOAT32:
|
||||
case PLANCK_FLOAT64:
|
||||
case PLANCK_BOOL:
|
||||
write_col (colnum, data, num, type, offset); break;
|
||||
case PLANCK_STRING:
|
||||
{
|
||||
const string *data2 = static_cast<const string *> (data);
|
||||
planck_assert(table_hdu(colnum),"incorrect FITS table access");
|
||||
tsize stringlen = safe_cast<tsize>(columns_[colnum-1].repcount()+1);
|
||||
arr2b<char> tdata(safe_cast<tsize>(num), stringlen);
|
||||
for (long m=0;m<num;++m)
|
||||
{
|
||||
strncpy(tdata[m],data2[m].c_str(),stringlen-1);
|
||||
tdata[m][stringlen-1] = '\0';
|
||||
}
|
||||
fits_write_col (FPTR, TSTRING, colnum, offset+1, 1, num,
|
||||
tdata.p0(), &status);
|
||||
nrows_ = max(nrows_,offset+num);
|
||||
check_errors();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
planck_fail ("unsupported data type in write_column_raw_void()");
|
||||
}
|
||||
}
|
||||
|
||||
void fitshandle::write_image2D_void (const void *data, PDT type, tsize s1,
|
||||
tsize s2)
|
||||
{
|
||||
planck_assert(image_hdu(),"not connected to an image");
|
||||
planck_assert (axes_.size()==2, "wrong number of dimensions");
|
||||
planck_assert (axes_[0]==int64(s1), "wrong size of dimension 1");
|
||||
planck_assert (axes_[1]==int64(s2), "wrong size of dimension 2");
|
||||
|
||||
fits_write_img (FPTR, type2ftc(type), 1, axes_[0]*axes_[1],
|
||||
const_cast<void *>(data), &status);
|
||||
check_errors();
|
||||
}
|
||||
|
||||
void fitshandle::write_subimage_void (const void *data, PDT type, tsize sz,
|
||||
int64 offset)
|
||||
{
|
||||
planck_assert(image_hdu(),"not connected to an image");
|
||||
fits_write_img (FPTR, type2ftc(type), 1+offset, sz, const_cast<void *>(data),
|
||||
&status);
|
||||
check_errors();
|
||||
}
|
||||
|
||||
template<typename T> void fitshandle::read_image (arr2<T> &data) const
|
||||
{
|
||||
planck_assert(image_hdu(),"not connected to an image");
|
||||
planck_assert (axes_.size()==2, "wrong number of dimensions");
|
||||
data.alloc(safe_cast<tsize>(axes_[0]), safe_cast<tsize>(axes_[1]));
|
||||
fits_read_img (FPTR, fitsType<T>(), 1, axes_[0]*axes_[1], 0, &data[0][0], 0,
|
||||
&status);
|
||||
check_errors();
|
||||
}
|
||||
|
||||
template void fitshandle::read_image (arr2<float> &data) const;
|
||||
template void fitshandle::read_image (arr2<double> &data) const;
|
||||
|
||||
template<typename T> void fitshandle::read_image (arr3<T> &data) const
|
||||
{
|
||||
planck_assert(image_hdu(),"not connected to an image");
|
||||
planck_assert (axes_.size()==3, "wrong number of dimensions");
|
||||
data.alloc(safe_cast<tsize>(axes_[0]), safe_cast<tsize>(axes_[1]),
|
||||
safe_cast<tsize>(axes_[2]));
|
||||
fits_read_img (FPTR, fitsType<T>(), 1, axes_[0]*axes_[1]*axes_[2],
|
||||
0, &data(0,0,0), 0, &status);
|
||||
check_errors();
|
||||
}
|
||||
|
||||
template void fitshandle::read_image (arr3<float> &data) const;
|
||||
template void fitshandle::read_image (arr3<double> &data) const;
|
||||
|
||||
template<typename T> void fitshandle::read_subimage
|
||||
(arr2<T> &data, int xl, int yl) const
|
||||
{
|
||||
planck_assert(image_hdu(),"not connected to an image");
|
||||
planck_assert (axes_.size()==2, "wrong number of dimensions");
|
||||
for (tsize m=0; m<data.size1(); ++m)
|
||||
fits_read_img (FPTR, fitsType<T>(), (xl+m)*axes_[1]+yl+1,
|
||||
data.size2(), 0, &data[m][0], 0, &status);
|
||||
check_errors();
|
||||
}
|
||||
|
||||
template void fitshandle::read_subimage
|
||||
(arr2<float> &data, int xl, int yl) const;
|
||||
template void fitshandle::read_subimage
|
||||
(arr2<double> &data, int xl, int yl) const;
|
||||
|
||||
void fitshandle::read_subimage_void (void *data, PDT type, tsize ndata,
|
||||
int64 offset) const
|
||||
{
|
||||
planck_assert(image_hdu(),"not connected to an image");
|
||||
fits_read_img (FPTR, type2ftc(type), 1+offset, ndata, 0, data, 0, &status);
|
||||
check_errors();
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class cfitsio_checker
|
||||
{
|
||||
public:
|
||||
cfitsio_checker()
|
||||
{
|
||||
float fitsversion;
|
||||
planck_assert(fits_get_version(&fitsversion),
|
||||
"error calling fits_get_version()");
|
||||
int v_header = nearest<int>(1000.*CFITSIO_VERSION),
|
||||
v_library = nearest<int>(1000.*fitsversion);
|
||||
if (v_header!=v_library)
|
||||
cerr << endl << "WARNING: version mismatch between CFITSIO header (v"
|
||||
<< dataToString(v_header*0.001) << ") and linked library (v"
|
||||
<< dataToString(v_library*0.001) << ")." << endl << endl;
|
||||
}
|
||||
};
|
||||
|
||||
cfitsio_checker Cfitsio_Checker;
|
||||
|
||||
} // unnamed namespace
|
301
external/healpix/cxxsupport/fitshandle.h
vendored
Normal file
301
external/healpix/cxxsupport/fitshandle.h
vendored
Normal file
|
@ -0,0 +1,301 @@
|
|||
/*
|
||||
* This file is part of libcxxsupport.
|
||||
*
|
||||
* libcxxsupport is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libcxxsupport is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libcxxsupport; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*! \file fitshandle.h
|
||||
* Declaration of the FITS I/O helper class used by LevelS
|
||||
*
|
||||
* Copyright (C) 2002 - 2009 Max-Planck-Society
|
||||
* \author Martin Reinecke
|
||||
*/
|
||||
|
||||
#ifndef PLANCK_FITSHANDLE_H
|
||||
#define PLANCK_FITSHANDLE_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "arr.h"
|
||||
#include "datatypes.h"
|
||||
#include "safe_cast.h"
|
||||
|
||||
/*! \defgroup fitsgroup FITS-related functionality */
|
||||
/*! \{ */
|
||||
|
||||
/*! Class containing information about a single column in a FITS table. */
|
||||
class fitscolumn
|
||||
{
|
||||
private:
|
||||
std::string name_, unit_;
|
||||
int64 repcount_;
|
||||
PDT type_;
|
||||
|
||||
public:
|
||||
fitscolumn();
|
||||
/*! Creates a \a fitscolumn with name \a nm, unit \a un, a repetition
|
||||
count of \a rc, and a Planck type of \a tp. */
|
||||
fitscolumn (const std::string &nm, const std::string &un, int64 rc, PDT tp);
|
||||
|
||||
/*! Returns the column name. */
|
||||
const std::string &name() const {return name_;}
|
||||
/*! Returns the column unit string. */
|
||||
const std::string &unit() const {return unit_;}
|
||||
/*! Returns the repetition count of the column. */
|
||||
int64 repcount() const {return repcount_;}
|
||||
/*! Returns the Planck type of the column. */
|
||||
PDT type() const {return type_;}
|
||||
};
|
||||
|
||||
/*! Class for performing I/O from/to FITS files. */
|
||||
class fitshandle
|
||||
{
|
||||
private:
|
||||
enum { INVALID = -4711 };
|
||||
|
||||
mutable int status;
|
||||
void *fptr;
|
||||
int hdutype_, bitpix_;
|
||||
std::vector<int64> axes_;
|
||||
std::vector<fitscolumn> columns_;
|
||||
int64 nrows_;
|
||||
|
||||
void check_errors() const;
|
||||
|
||||
void clean_data();
|
||||
void clean_all();
|
||||
|
||||
bool connected() const { return (hdutype_!=INVALID); }
|
||||
bool table_hdu (tsize col) const;
|
||||
bool image_hdu () const;
|
||||
|
||||
void init_image();
|
||||
void init_asciitab();
|
||||
void init_bintab();
|
||||
void init_data();
|
||||
|
||||
void read_col (int colnum, void *data, int64 ndata, PDT type,
|
||||
int64 offset) const;
|
||||
void write_col (int colnum, const void *data, int64 ndata, PDT type,
|
||||
int64 offset);
|
||||
|
||||
void getKeyHelper(const std::string &name) const;
|
||||
|
||||
public:
|
||||
/*! the list of modes in which a \a fitshandle can be opened. */
|
||||
enum openmethod { CREATE, /*!< the file must not yet exist */
|
||||
OPEN /*!< the file must already exist */
|
||||
};
|
||||
|
||||
/*! \name File-level access and manipulation. */
|
||||
/*! \{ */
|
||||
|
||||
/*! Creates an unconnected \a fitshandle. */
|
||||
fitshandle ()
|
||||
: status(0), fptr(0), hdutype_(INVALID), bitpix_(INVALID), nrows_(0) {}
|
||||
/*! Performs all necessary cleanups. */
|
||||
~fitshandle() { clean_all(); }
|
||||
|
||||
/*! Connects to the file \a fname. */
|
||||
void open (const std::string &fname);
|
||||
/*! Creates the file \a fname and connects to it. */
|
||||
void create (const std::string &fname);
|
||||
/*! Closes the current file. */
|
||||
void close () { clean_all(); }
|
||||
/*! Deletes the file with name \a name. */
|
||||
static void delete_file (const std::string &name);
|
||||
/*! Jumps to the HDU with the absolute number \a hdu. */
|
||||
void goto_hdu (int hdu);
|
||||
/*! Returns the number of HDUs in the file. */
|
||||
int num_hdus () const;
|
||||
/*! Asserts that the PDMTYPE of the current HDU is \a pdmtype. */
|
||||
void assert_pdmtype (const std::string &pdmtype) const;
|
||||
/*! Inserts a binary table described by \a cols.
|
||||
The HDU has the name \a extname. */
|
||||
void insert_bintab (const std::vector<fitscolumn> &cols,
|
||||
const std::string &extname="xtension");
|
||||
/*! Inserts an ASCII table described by \a cols. The width of the
|
||||
columns is chosen automatically, in a way that avoids truncation.
|
||||
The HDU has the name \a extname. */
|
||||
void insert_asctab (const std::vector<fitscolumn> &cols,
|
||||
const std::string &extname="xtension");
|
||||
/*! Inserts a FITS image with the type given by \a type and dimensions
|
||||
given by \a Axes. */
|
||||
void insert_image (PDT type, const std::vector<int64> &Axes);
|
||||
/*! Inserts a 2D FITS image with the type given by \a type, whose
|
||||
contents are given in \a data. */
|
||||
template<typename T>
|
||||
void insert_image (PDT type, const arr2<T> &data);
|
||||
|
||||
/*! Computes the checksum for the current HDU and writes it into the
|
||||
header. */
|
||||
void write_checksum();
|
||||
|
||||
/*! \} */
|
||||
|
||||
/*! \name Information about the current HDU */
|
||||
/*! \{ */
|
||||
|
||||
/*! Returns the dimensions of the current image. */
|
||||
const std::vector<int64> &axes() const;
|
||||
/*! Returns the name of column \a #i. */
|
||||
const std::string &colname(int i) const;
|
||||
/*! Returns the unit of column \a #i. */
|
||||
const std::string &colunit(int i) const;
|
||||
/*! Returns repetition count of column \a #i. */
|
||||
int64 repcount(int i) const;
|
||||
/*! Returns the Planck type for column \a #i. */
|
||||
PDT coltype(int i) const;
|
||||
/*! Returns the number of columns in the current table. */
|
||||
int ncols() const;
|
||||
/*! Returns the number of rows in the current table. */
|
||||
int64 nrows() const;
|
||||
/*! Returns the total number of elements (nrows*repcount)
|
||||
in column \a #i. */
|
||||
int64 nelems(int i) const;
|
||||
/*! Returns the number of elements that should be read/written in a single
|
||||
call for optimum performance. This depends on the current HDU. */
|
||||
int64 efficientChunkSize(int i) const;
|
||||
|
||||
/*! \} */
|
||||
|
||||
/*! \name Keyword-handling methods */
|
||||
/*! \{ */
|
||||
|
||||
/*! Returns a list of all user-defined keys in the current HDU
|
||||
in \a keys. */
|
||||
void get_all_keys (std::vector<std::string> &keys) const;
|
||||
|
||||
void set_key_void (const std::string &key, const void *value, PDT type,
|
||||
const std::string &comment="");
|
||||
/*! Updates \a key with \a value and \a comment. */
|
||||
template<typename T> void set_key (const std::string &name,
|
||||
const T &value, const std::string &comment="")
|
||||
{ set_key_void (name, &value, planckType<T>(), comment); }
|
||||
/*! Deletes \a key from the header. */
|
||||
void delete_key (const std::string &name);
|
||||
/*! Adds \a comment as a comment line. */
|
||||
void add_comment (const std::string &comment);
|
||||
void get_key_void (const std::string &key, void *value, PDT type) const;
|
||||
/*! Reads the value belonging to \a key and returns it in \a value. */
|
||||
template<typename T> void get_key (const std::string &name, T &value) const
|
||||
{ get_key_void (name,&value,planckType<T>()); }
|
||||
/*! Returms the value belonging to \a key. */
|
||||
template<typename T> T get_key (const std::string &name) const
|
||||
{ T tmp; get_key(name, tmp); return tmp; }
|
||||
/*! Returns \a true if \a key is present, else \a false. */
|
||||
bool key_present (const std::string &name) const;
|
||||
|
||||
/*! \} */
|
||||
|
||||
/*! \name Methods for table data I/O */
|
||||
/*! \{ */
|
||||
|
||||
void read_column_raw_void
|
||||
(int colnum, void *data, PDT type, int64 num, int64 offset=0) const;
|
||||
/*! Copies \a num elements from column \a colnum to the memory pointed
|
||||
to by \a data, starting at offset \a offset in the column. */
|
||||
template<typename T> void read_column_raw
|
||||
(int colnum, T *data, int64 num, int64 offset=0) const
|
||||
{ read_column_raw_void (colnum, data, planckType<T>(), num, offset); }
|
||||
/*! Fills \a data with elements from column \a colnum,
|
||||
starting at offset \a offset in the column. */
|
||||
template<typename T> void read_column
|
||||
(int colnum, arr<T> &data, int64 offset=0) const
|
||||
{ read_column_raw (colnum, &(data[0]), data.size(), offset); }
|
||||
/*! Reads the element \a #offset from column \a colnum into \a data. */
|
||||
template<typename T> void read_column
|
||||
(int colnum, T &data, int64 offset=0) const
|
||||
{ read_column_raw (colnum, &data, 1, offset); }
|
||||
/*! Reads the whole column \a colnum into \a data (which is resized
|
||||
accordingly). */
|
||||
template<typename T> void read_entire_column
|
||||
(int colnum, arr<T> &data) const
|
||||
{
|
||||
data.alloc(safe_cast<tsize>(nelems(colnum)));
|
||||
read_column (colnum, data);
|
||||
}
|
||||
|
||||
void write_column_raw_void
|
||||
(int colnum, const void *data, PDT type, int64 num, int64 offset=0);
|
||||
/*! Copies \a num elements from the memory pointed to by \a data to the
|
||||
column \a colnum, starting at offset \a offset in the column. */
|
||||
template<typename T> void write_column_raw
|
||||
(int colnum, const T *data, int64 num, int64 offset=0)
|
||||
{ write_column_raw_void (colnum, data, planckType<T>(), num, offset); }
|
||||
/*! Copies all elements from \a data to the
|
||||
column \a colnum, starting at offset \a offset in the column. */
|
||||
template<typename T> void write_column
|
||||
(int colnum, const arr<T> &data, int64 offset=0)
|
||||
{ write_column_raw (colnum, &(data[0]), data.size(), offset); }
|
||||
/*! Copies \a data to the column \a colnum, at the position \a offset. */
|
||||
template<typename T> void write_column
|
||||
(int colnum, const T &data, int64 offset=0)
|
||||
{ write_column_raw (colnum, &data, 1, offset); }
|
||||
|
||||
/*! \} */
|
||||
|
||||
/*! \name Methods for image data I/O */
|
||||
/*! \{ */
|
||||
|
||||
/*! Reads the current image into \a data, which is resized accordingly. */
|
||||
template<typename T> void read_image (arr2<T> &data) const;
|
||||
/*! Reads the current image into \a data, which is resized accordingly. */
|
||||
template<typename T> void read_image (arr3<T> &data) const;
|
||||
/*! Reads a partial image, whose dimensions are given by the dimensions
|
||||
of \a data, into data. The starting pixel indices are given by
|
||||
\a xl and \a yl. */
|
||||
template<typename T> void read_subimage
|
||||
(arr2<T> &data, int xl, int yl) const;
|
||||
void read_subimage_void (void *data, PDT type, tsize ndata, int64 offset=0)
|
||||
const;
|
||||
/*! Fills \a data with values from the image, starting at the offset
|
||||
\a offset in the image. The image is treated as a one-dimensional
|
||||
array. */
|
||||
template<typename T> void read_subimage (arr<T> &data, int64 offset=0)
|
||||
const
|
||||
{ read_subimage_void (&data[0],planckType<T>(),data.size(),offset); }
|
||||
|
||||
void write_image2D_void (const void *data, PDT type, tsize s1,
|
||||
tsize s2);
|
||||
/*! Writes \a data into the current image. \a data must have the same
|
||||
dimensions as specified in the HDU. */
|
||||
template<typename T> void write_image (const arr2<T> &data)
|
||||
{
|
||||
write_image2D_void (&data[0][0],planckType<T>(),data.size1(),
|
||||
data.size2());
|
||||
}
|
||||
|
||||
void write_subimage_void (const void *data, PDT type, tsize sz,
|
||||
int64 offset);
|
||||
/*! Copies \a data to the image, starting at the offset
|
||||
\a offset in the image. The image is treated as a one-dimensional
|
||||
array. */
|
||||
template<typename T> void write_subimage (const arr<T> &data,
|
||||
int64 offset=0)
|
||||
{ write_subimage_void(&data[0],planckType<T>(),data.size(),offset); }
|
||||
|
||||
/*! \} */
|
||||
};
|
||||
|
||||
/*! \} */
|
||||
|
||||
#endif
|
3848
external/healpix/cxxsupport/font_data.inc
vendored
Normal file
3848
external/healpix/cxxsupport/font_data.inc
vendored
Normal file
File diff suppressed because it is too large
Load diff
60
external/healpix/cxxsupport/geom_utils.h
vendored
Normal file
60
external/healpix/cxxsupport/geom_utils.h
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* This file is part of libcxxsupport.
|
||||
*
|
||||
* libcxxsupport is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libcxxsupport is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libcxxsupport; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*! \file geom_utils.h
|
||||
* Geometric utility functions.
|
||||
*
|
||||
* Copyright (C) 2003, 2006 Max-Planck-Society
|
||||
* \author Martin Reinecke
|
||||
* \author Reinhard Hell
|
||||
*/
|
||||
|
||||
#ifndef PLANCK_GEOM_UTILS_H
|
||||
#define PLANCK_GEOM_UTILS_H
|
||||
|
||||
#include "cxxutils.h"
|
||||
#include "vec3.h"
|
||||
|
||||
/*! Returns the orientation when looking from point \a loc on the unit
|
||||
sphere in the direction \a dir. \a loc must be normalized. The result
|
||||
ranges from -pi to pi, is 0 for North and pi/2 for West, i.e. the angle
|
||||
is given in mathematically positive sense.
|
||||
|
||||
If \a loc is the North or South pole, the returned angle is
|
||||
\a atan2(dir.y,dir.x). */
|
||||
inline double orientation (const vec3 &loc, const vec3 &dir)
|
||||
{
|
||||
// FIXME: here is still optimization potential
|
||||
if (loc.x==0 && loc.y==0)
|
||||
return (loc.z>0) ? safe_atan2(dir.y,-dir.x) : safe_atan2(dir.y,dir.x);
|
||||
vec3 east (-loc.y, loc.x, 0);
|
||||
vec3 north = crossprod(loc,east);
|
||||
return safe_atan2(-dotprod(dir,east),dotprod(dir,north));
|
||||
}
|
||||
|
||||
/*! Returns the angle between \a v1 and \a v2 in radians. */
|
||||
inline double v_angle (const vec3 &v1, const vec3 &v2)
|
||||
{ return atan2 (crossprod(v1,v2).Length(), dotprod(v1,v2)); }
|
||||
|
||||
#endif
|
15
external/healpix/cxxsupport/levels_facilities.h
vendored
Normal file
15
external/healpix/cxxsupport/levels_facilities.h
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef LEVELS_FACILITIES_H
|
||||
#define LEVELS_FACILITIES_H
|
||||
|
||||
int syn_alm_cxx_module (int argc, const char **argv);
|
||||
int alm2map_cxx_module (int argc, const char **argv);
|
||||
int anafast_cxx_module (int argc, const char **argv);
|
||||
int calc_powspec_module (int argc, const char **argv);
|
||||
int hotspots_cxx_module (int argc, const char **argv);
|
||||
int map2tga_module (int argc, const char **argv);
|
||||
int median_filter_cxx_module (int argc, const char **argv);
|
||||
int mult_alm_module (int argc, const char **argv);
|
||||
int smoothing_cxx_module (int argc, const char **argv);
|
||||
int udgrade_cxx_module (int argc, const char **argv);
|
||||
|
||||
#endif
|
219
external/healpix/cxxsupport/ls_image.cc
vendored
Normal file
219
external/healpix/cxxsupport/ls_image.cc
vendored
Normal file
|
@ -0,0 +1,219 @@
|
|||
/*
|
||||
* This file is part of libcxxsupport.
|
||||
*
|
||||
* libcxxsupport is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libcxxsupport is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libcxxsupport; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Classes for creation and output of image files
|
||||
*
|
||||
* Copyright (C) 2003 Max-Planck-Society
|
||||
* Author: Martin Reinecke
|
||||
*/
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include "ls_image.h"
|
||||
#include "bstream.h"
|
||||
#include "font_data.inc"
|
||||
|
||||
using namespace std;
|
||||
|
||||
const Font medium_bold_font = { 0, 128, 7, 13, medium_bold_font_data };
|
||||
const Font giant_font = { 0, 128, 9, 15, giant_font_data };
|
||||
|
||||
void Palette::setPredefined (int num)
|
||||
{
|
||||
fv.clear(); cv.clear();
|
||||
switch(num)
|
||||
{
|
||||
case 0:
|
||||
add(0,Colour(0,0,0));
|
||||
add(1,Colour(1,1,1));
|
||||
break;
|
||||
case 1:
|
||||
add(0,Colour(0,0,0));
|
||||
add(0.4f,Colour(0,0,0.5f));
|
||||
add(0.75f,Colour(0,0.6f,1));
|
||||
add(1,Colour(1,1,1));
|
||||
break;
|
||||
case 4:
|
||||
add(0,Colour(0,0,.5f));
|
||||
add(0.15f,Colour(0,0,1));
|
||||
add(0.4f,Colour(0,1,1));
|
||||
add(0.7f,Colour(1,1,0));
|
||||
add(0.9f,Colour(1,.33f,0));
|
||||
add(1,Colour(.5f,0,0));
|
||||
break;
|
||||
default:
|
||||
planck_fail("Palette #"+dataToString(num)+" not yet supported.");
|
||||
}
|
||||
}
|
||||
|
||||
void LS_Image::write_char (int xpos, int ypos, const Colour &col, char c,
|
||||
int scale)
|
||||
{
|
||||
planck_assert ((c>=font.offset) && (c<font.offset+font.num_chars),
|
||||
"write_char: character out of range");
|
||||
for (int i=0; i<font.xpix; ++i)
|
||||
for (int j=0; j<font.ypix; ++j)
|
||||
{
|
||||
int ofs = (c-font.offset)*font.xpix*font.ypix + j*font.xpix + i;
|
||||
if (font.data[ofs]!=' ')
|
||||
for (int m=0; m<scale; ++m)
|
||||
for (int n=0; n<scale; ++n)
|
||||
put_pixel(xpos+scale*i+m,ypos+scale*j+n,col);
|
||||
}
|
||||
}
|
||||
|
||||
LS_Image::LS_Image ()
|
||||
: font(medium_bold_font) {}
|
||||
|
||||
LS_Image::LS_Image (int xres, int yres)
|
||||
: font(medium_bold_font), pixel(xres,yres,Colour(0,0,0)) {}
|
||||
|
||||
void LS_Image::annotate (int xpos, int ypos, const Colour &col,
|
||||
const string &text, int scale)
|
||||
{
|
||||
for (tsize m=0; m<text.length(); ++m)
|
||||
write_char(xpos+m*scale*font.xpix, ypos, col, text[m],scale);
|
||||
}
|
||||
|
||||
void LS_Image::annotate_centered (int xpos, int ypos, const Colour &col,
|
||||
const string &text, int scale)
|
||||
{
|
||||
xpos-=(scale*text.length()*font.xpix)/2;
|
||||
ypos-=scale*font.ypix/2;
|
||||
annotate (xpos,ypos,col,text,scale);
|
||||
}
|
||||
|
||||
void LS_Image::set_font (const Font &fnt)
|
||||
{ font = fnt; }
|
||||
|
||||
void LS_Image::write_TGA (const string &file) const
|
||||
{
|
||||
ofstream out(file.c_str(), ios_base::out | ios_base::binary);
|
||||
planck_assert(out, "could not create file '" + file + "'");
|
||||
|
||||
tsize xres=pixel.size1(), yres=pixel.size2();
|
||||
|
||||
bostream bo(out);
|
||||
const uint8 header[18] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
uint8(xres%256), uint8(xres/256), uint8(yres%256), uint8(yres/256), 24, 32};
|
||||
|
||||
bo.put (header, 18);
|
||||
|
||||
for (tsize j=0; j<yres; ++j)
|
||||
for (tsize i=0; i<xres; ++i)
|
||||
bo << pixel[i][j].b << pixel[i][j].g << pixel[i][j].r;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void write_equal_range (const arr<Colour8> &px, tsize begin, tsize end,
|
||||
bostream &file)
|
||||
{
|
||||
chunkMaker cm (end-begin,128);
|
||||
uint64 cbeg, csz;
|
||||
while (cm.getNext(cbeg,csz))
|
||||
{
|
||||
file << uint8(csz-1+128);
|
||||
file << px[begin].b << px[begin].g << px[begin].r;
|
||||
}
|
||||
}
|
||||
void write_unequal_range (const arr<Colour8> &px, tsize begin, tsize end,
|
||||
bostream &file)
|
||||
{
|
||||
chunkMaker cm (end-begin,128);
|
||||
uint64 cbeg, csz;
|
||||
while (cm.getNext(cbeg,csz))
|
||||
{
|
||||
file << uint8(csz-1);
|
||||
for (tsize cnt=begin+cbeg; cnt< begin+cbeg+csz; ++cnt)
|
||||
file << px[cnt].b << px[cnt].g << px[cnt].r;
|
||||
}
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
void LS_Image::write_TGA_rle(const string &file) const
|
||||
{
|
||||
ofstream out(file.c_str(), ios_base::out | ios_base::binary);
|
||||
planck_assert(out, "could not create file '" + file + "'");
|
||||
|
||||
tsize xres=pixel.size1(), yres=pixel.size2();
|
||||
|
||||
bostream bo(out);
|
||||
const uint8 header[18] = { 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
xres%256, xres/256, yres%256, yres/256, 24, 32 };
|
||||
|
||||
bo.put(header,18);
|
||||
for (tsize y=0; y<yres; ++y)
|
||||
{
|
||||
arr<Colour8> px(xres);
|
||||
for (tsize x=0; x<xres; ++x) px[x] = pixel[x][y];
|
||||
tsize xstart=0;
|
||||
while (xstart<xres)
|
||||
{
|
||||
if (xstart==xres-1)
|
||||
{
|
||||
write_unequal_range (px,xstart,xstart+1,bo);
|
||||
xstart=xres;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (px[xstart+1]==px[xstart]) // range of equal pixels
|
||||
{
|
||||
tsize xend=xstart+2;
|
||||
while ((xend<xres) && (px[xend]==px[xstart])) ++xend;
|
||||
write_equal_range (px,xstart,xend,bo);
|
||||
xstart=xend;
|
||||
}
|
||||
else
|
||||
{
|
||||
tsize xend=xstart+2;
|
||||
while ((xend<xres) && (px[xend]!=px[xend-1])) ++xend;
|
||||
write_unequal_range (px,xstart,xend,bo);
|
||||
xstart=xend;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LS_Image::write_PPM (const string &file) const
|
||||
{
|
||||
ofstream out(file.c_str(), ios_base::out | ios_base::binary);
|
||||
planck_assert(out, "could not create file '" + file + "'");
|
||||
|
||||
tsize xres=pixel.size1(), yres=pixel.size2();
|
||||
|
||||
bostream bo(out);
|
||||
|
||||
ostringstream header;
|
||||
header << "P6" << endl << xres << endl << yres << endl << 255 << endl;
|
||||
string hdrdata = header.str();
|
||||
bo.put(hdrdata.c_str(),hdrdata.size());
|
||||
|
||||
for (tsize j=0; j<yres; ++j)
|
||||
for (tsize i=0; i<xres; ++i)
|
||||
bo << pixel[i][j].r << pixel[i][j].g << pixel[i][j].b;
|
||||
}
|
192
external/healpix/cxxsupport/ls_image.h
vendored
Normal file
192
external/healpix/cxxsupport/ls_image.h
vendored
Normal file
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
* This file is part of libcxxsupport.
|
||||
*
|
||||
* libcxxsupport is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libcxxsupport is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libcxxsupport; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*! \file ls_image.h
|
||||
* Classes for creation and output of image files
|
||||
*
|
||||
* Copyright (C) 2003-2010 Max-Planck-Society
|
||||
* \author Martin Reinecke, David Larson
|
||||
*/
|
||||
|
||||
#ifndef PLANCK_LS_IMAGE_H
|
||||
#define PLANCK_LS_IMAGE_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include "arr.h"
|
||||
#include "datatypes.h"
|
||||
|
||||
/*! \defgroup imagegroup Image creation */
|
||||
/*! \{ */
|
||||
|
||||
/*! A very simple class for storing RGB colours. */
|
||||
class Colour
|
||||
{
|
||||
public:
|
||||
float r, /*!< the red component */
|
||||
g, /*!< the green component */
|
||||
b; /*!< the blue component */
|
||||
|
||||
/*! Default constructor. Does not initialize \a r, \a g and \a b. */
|
||||
Colour() {}
|
||||
/*! Initializes the colour with \a R, \a G and \a B. */
|
||||
Colour (float R, float G, float B) : r(R), g(G), b(B) {}
|
||||
/*! Multiplies all components with \a fact. */
|
||||
const Colour &operator*= (float fact)
|
||||
{ r*=fact; g*=fact; b*=fact; return *this; }
|
||||
/*! Returns the sum colour of \a *this and \a c2. */
|
||||
const Colour operator+ (const Colour &c2) const
|
||||
{ return Colour(r+c2.r, g+c2.g, b+c2.b); }
|
||||
/*! Returns \a *this, scaled by \a f. */
|
||||
const Colour operator* (double f) const
|
||||
{ return Colour(float(r*f), float(g*f), float(b*f)); }
|
||||
};
|
||||
|
||||
/*! A class for mapping floting-point values into colours. */
|
||||
class Palette
|
||||
{
|
||||
private:
|
||||
std::vector<Colour> cv;
|
||||
std::vector<float> fv;
|
||||
|
||||
public:
|
||||
/*! Adds a new data point \a f, with the corresponding colour \a c.
|
||||
The additions must be done in the order of ascending \a f. */
|
||||
void add (float f, const Colour &c)
|
||||
{
|
||||
fv.push_back(f);
|
||||
cv.push_back(c);
|
||||
}
|
||||
/*! Sets the palette to the predefined palette \a num. */
|
||||
void setPredefined(int num);
|
||||
/*! Returns the colour corresponding to the value \a f. The colour is
|
||||
determined by linear interpolation between neighbouring data points. */
|
||||
Colour Get_Colour (float f) const
|
||||
{
|
||||
if (f<=fv[0]) return cv[0];
|
||||
if (f>=fv[fv.size()-1]) return cv[cv.size()-1];
|
||||
int i=0;
|
||||
while (f>fv[i]) ++i;
|
||||
return cv[i-1]*((fv[i]-f)/(fv[i]-fv[i-1]))
|
||||
+ cv[i]*((f-fv[i-1])/(fv[i]-fv[i-1]));
|
||||
}
|
||||
};
|
||||
|
||||
class Colour8
|
||||
{
|
||||
private:
|
||||
void import (const Colour &col)
|
||||
{
|
||||
using namespace std;
|
||||
r = uint8(max(0,min(255,int(col.r*256))));
|
||||
g = uint8(max(0,min(255,int(col.g*256))));
|
||||
b = uint8(max(0,min(255,int(col.b*256))));
|
||||
}
|
||||
|
||||
public:
|
||||
uint8 r,g,b;
|
||||
|
||||
Colour8() {}
|
||||
Colour8 (uint8 R, uint8 G, uint8 B)
|
||||
: r(R), g(G), b(B) {}
|
||||
Colour8 (const Colour &col)
|
||||
{ import (col); }
|
||||
const Colour8 &operator= (const Colour &col)
|
||||
{ import (col); return *this; }
|
||||
bool operator== (const Colour8 &that)
|
||||
{ return (r == that.r) && (g == that.g) && (b == that.b); }
|
||||
bool operator!= (const Colour8 &that)
|
||||
{ return (r != that.r) || (g != that.g) || (b != that.b); }
|
||||
};
|
||||
|
||||
class Font
|
||||
{
|
||||
public:
|
||||
int offset, num_chars, xpix, ypix;
|
||||
const char *data;
|
||||
};
|
||||
|
||||
extern const Font medium_bold_font;
|
||||
extern const Font giant_font;
|
||||
|
||||
/*! Class for creating and storing image files. */
|
||||
class LS_Image
|
||||
{
|
||||
private:
|
||||
Font font;
|
||||
arr2<Colour8> pixel;
|
||||
|
||||
void write_char (int xpos, int ypos, const Colour &col, char c,
|
||||
int scale=1);
|
||||
|
||||
public:
|
||||
/*! */
|
||||
LS_Image ();
|
||||
/*! Creates an image object with a resolution of \a xres by \a yres. */
|
||||
LS_Image (int xres, int yres);
|
||||
/*! */
|
||||
~LS_Image () {}
|
||||
|
||||
/*! Fills the entire image with colour \a col. */
|
||||
void fill (const Colour &col) { pixel.fill(col); }
|
||||
/*! Sets the font used for annotations to \a fnt. */
|
||||
void set_font (const Font &fnt);
|
||||
/*! Outputs the string \a text in colour \a col.
|
||||
\a xpos, \a ypos is the lower left corner;
|
||||
the font is scaled by \a scale. */
|
||||
void annotate (int xpos, int ypos, const Colour &col,
|
||||
const std::string &text, int scale=1);
|
||||
/*! Outputs the string \a text centered at position \a xpos, \a ypos
|
||||
in colour \a col. The font is scaled by \a scale. */
|
||||
void annotate_centered (int xpos, int ypos, const Colour &col,
|
||||
const std::string &text, int scale=1);
|
||||
/*! Sets the pixel \a i, \a j, to the colour \a col. */
|
||||
void put_pixel (tsize i, tsize j, const Colour &col)
|
||||
{
|
||||
if ((i<pixel.size1()) && (j<pixel.size2()))
|
||||
pixel[i][j] = col;
|
||||
}
|
||||
/*! Returns the colour of the pixel \a i, \a j, or black if the pixel
|
||||
lies outside of the image. */
|
||||
Colour8 get_pixel (tsize i, tsize j)
|
||||
{
|
||||
return ((i<pixel.size1()) && (j<pixel.size2())) ?
|
||||
pixel[i][j] : Colour8(0, 0, 0);
|
||||
}
|
||||
|
||||
/*! Writes the image to \a file in uncompressed TGA format. */
|
||||
void write_TGA (const std::string &file) const;
|
||||
|
||||
/*! Writes the image to \a file in run-length encoded TGA format. */
|
||||
void write_TGA_rle (const std::string &file) const;
|
||||
|
||||
/*! Writes the image to \a file in binary PPM format. */
|
||||
void write_PPM (const std::string &file) const;
|
||||
};
|
||||
|
||||
/*! \} */
|
||||
|
||||
#endif
|
93
external/healpix/cxxsupport/lsconstants.h
vendored
Normal file
93
external/healpix/cxxsupport/lsconstants.h
vendored
Normal file
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* This file is part of libcxxsupport.
|
||||
*
|
||||
* libcxxsupport is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libcxxsupport is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libcxxsupport; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*! \file lsconstants.h
|
||||
* Mathematical, physical and technical constants for LevelS.
|
||||
*/
|
||||
|
||||
#ifndef PLANCK_CONSTANTS_H
|
||||
#define PLANCK_CONSTANTS_H
|
||||
|
||||
/*! \defgroup mathconstgroup Mathematical constants */
|
||||
/*! \{ */
|
||||
|
||||
const double pi=3.141592653589793238462643383279502884197;
|
||||
const double twopi=6.283185307179586476925286766559005768394;
|
||||
const double inv_twopi=1.0/twopi;
|
||||
const double fourpi=12.56637061435917295385057353311801153679;
|
||||
const double halfpi=1.570796326794896619231321691639751442099;
|
||||
const double inv_halfpi=0.6366197723675813430755350534900574;
|
||||
const double inv_sqrt4pi = 0.2820947917738781434740397257803862929220;
|
||||
|
||||
const double ln2 = 0.6931471805599453094172321214581766;
|
||||
const double inv_ln2 = 1.4426950408889634073599246810018921;
|
||||
const double ln10 = 2.3025850929940456840179914546843642;
|
||||
|
||||
const double onethird=1.0/3.0;
|
||||
const double twothird=2.0/3.0;
|
||||
const double fourthird=4.0/3.0;
|
||||
|
||||
const double degr2rad=pi/180.0;
|
||||
const double arcmin2rad=degr2rad/60;
|
||||
const double rad2degr=180.0/pi;
|
||||
|
||||
//! Ratio between FWHM and sigma of a Gauss curve (\f$\sqrt{8\ln2}\f$).
|
||||
const double sigma2fwhm=2.3548200450309493; // sqrt(8*log(2.))
|
||||
const double fwhm2sigma=1/sigma2fwhm;
|
||||
|
||||
/*! \} */
|
||||
|
||||
/*! \defgroup physconstgroup Physical constants */
|
||||
/*! \{ */
|
||||
|
||||
const double Jansky2SI=1.0e-26;
|
||||
const double SI2Jansky=1.0e+26;
|
||||
|
||||
//! Light speed in m/s (CODATA 2006)
|
||||
const double speedOfLight=2.99792458e8;
|
||||
|
||||
//! Boltzmann's constant in J/K (CODATA 2006)
|
||||
const double kBoltzmann=1.3806504e-23;
|
||||
|
||||
//! Stefan-Boltzmann constant in W/m^2/K^4 (CODATA 2006)
|
||||
const double sigmaStefanBoltzmann=5.6704e-8;
|
||||
|
||||
//! Planck's constant in J s (CODATA 2006)
|
||||
const double hPlanck=6.62606896e-34;
|
||||
|
||||
//! Astronomical unit in m
|
||||
const double astronomicalUnit=1.49597870691e11;
|
||||
|
||||
//! Solar constant in W/m^2
|
||||
const double solarConstant=1368.0;
|
||||
|
||||
//! Average CMB temperature in K (Mather et al. 1999, ApJ 512, 511)
|
||||
const double tcmb = 2.725;
|
||||
|
||||
//! offset (in seconds) between Jan 1, 1958 and Jan 1, 1970
|
||||
const double sec_58_70 = 378691200.;
|
||||
|
||||
/*! \} */
|
||||
|
||||
#endif
|
89
external/healpix/cxxsupport/openmp_support.h
vendored
Normal file
89
external/healpix/cxxsupport/openmp_support.h
vendored
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* This file is part of libcxxsupport.
|
||||
*
|
||||
* libcxxsupport is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libcxxsupport is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libcxxsupport; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005, 2006, 2007, 2009, 2010 Max-Planck-Society
|
||||
* \author Martin Reinecke
|
||||
*/
|
||||
|
||||
#ifndef PLANCK_OPENMP_SUPPORT_H
|
||||
#define PLANCK_OPENMP_SUPPORT_H
|
||||
|
||||
#ifdef _OPENMP
|
||||
#include <omp.h>
|
||||
#endif
|
||||
|
||||
#include "cxxutils.h"
|
||||
|
||||
inline bool openmp_enabled()
|
||||
{
|
||||
#ifdef _OPENMP
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline int openmp_max_threads ()
|
||||
{
|
||||
#ifdef _OPENMP
|
||||
return omp_get_max_threads();
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline int openmp_num_threads ()
|
||||
{
|
||||
#ifdef _OPENMP
|
||||
return omp_get_num_threads();
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline int openmp_thread_num ()
|
||||
{
|
||||
#ifdef _OPENMP
|
||||
return omp_get_thread_num();
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*! Calculates the range of indices between \a glo and \a ghi which
|
||||
must be processed by this thread and returns it in \a lo and \a hi.
|
||||
|
||||
The indices \a ghi and \a hi are "one past the last real index",
|
||||
in analogy to the STL iterators. */
|
||||
inline void openmp_calc_share (int64 glo, int64 ghi, int64 &lo, int64 &hi)
|
||||
{
|
||||
#ifdef _OPENMP
|
||||
calcShareGeneral (glo,ghi,omp_get_num_threads(),omp_get_thread_num(),lo,hi);
|
||||
#else
|
||||
lo=glo; hi=ghi;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
116
external/healpix/cxxsupport/paramfile.h
vendored
Normal file
116
external/healpix/cxxsupport/paramfile.h
vendored
Normal file
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* This file is part of libcxxsupport.
|
||||
*
|
||||
* libcxxsupport is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libcxxsupport is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libcxxsupport; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Class for parsing parameter files
|
||||
*
|
||||
* Copyright (C) 2003, 2004, 2005, 2008, 2009, 2010 Max-Planck-Society
|
||||
* Authors: Martin Reinecke, Reinhard Hell
|
||||
*/
|
||||
|
||||
#ifndef PLANCK_PARAMFILE_H
|
||||
#define PLANCK_PARAMFILE_H
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include "cxxutils.h"
|
||||
|
||||
class paramfile
|
||||
{
|
||||
private:
|
||||
typedef std::map<std::string,std::string> params_type;
|
||||
params_type params;
|
||||
mutable std::set<std::string> read_params;
|
||||
bool verbose;
|
||||
|
||||
std::string get_valstr(const std::string &key) const
|
||||
{
|
||||
params_type::const_iterator loc=params.find(key);
|
||||
if (loc!=params.end()) return loc->second;
|
||||
planck_fail ("Cannot find the key '" + key + "'.");
|
||||
}
|
||||
|
||||
bool param_unread (const std::string &key) const
|
||||
{ return (read_params.find(key)==read_params.end()); }
|
||||
|
||||
public:
|
||||
paramfile (const std::string &filename, bool verbose_=true)
|
||||
: verbose(verbose_)
|
||||
{ parse_file (filename, params); }
|
||||
|
||||
paramfile (const params_type &par, bool verbose_=true)
|
||||
: params (par), verbose(verbose_)
|
||||
{}
|
||||
|
||||
~paramfile ()
|
||||
{
|
||||
if (verbose)
|
||||
for (params_type::const_iterator loc=params.begin();
|
||||
loc!=params.end(); ++loc)
|
||||
if (param_unread(loc->first))
|
||||
std::cout << "Parser warning: unused parameter '"
|
||||
<< loc->first << "'" << std::endl;
|
||||
}
|
||||
|
||||
void setVerbosity (bool verbose_)
|
||||
{ verbose = verbose_; }
|
||||
|
||||
bool getVerbosity () const
|
||||
{ return verbose; }
|
||||
|
||||
bool param_present(const std::string &key) const
|
||||
{ return (params.find(key)!=params.end()); }
|
||||
|
||||
template<typename T> T find (const std::string &key) const
|
||||
{
|
||||
T result;
|
||||
stringToData(get_valstr(key),result);
|
||||
std::string output = dataToString(result);
|
||||
if (planckType<T>()==PLANCK_STRING) output = "'"+output+"'";
|
||||
if (verbose && param_unread(key))
|
||||
std::cout << "Parser: " << key << " = " << output << std::endl;
|
||||
read_params.insert(key);
|
||||
return result;
|
||||
}
|
||||
template<typename T> T find
|
||||
(const std::string &key, const T &deflt)
|
||||
{
|
||||
if (param_present(key)) return find<T>(key);
|
||||
std::string output = dataToString(deflt);
|
||||
if (planckType<T>()==PLANCK_STRING) output = "'"+output+"'";
|
||||
if (verbose && param_unread(key))
|
||||
std::cout << "Parser: " << key << " = " << output
|
||||
<< " <default>" << std::endl;
|
||||
params[key]=dataToString(deflt);
|
||||
read_params.insert(key);
|
||||
return deflt;
|
||||
}
|
||||
|
||||
const params_type &getParams() const
|
||||
{ return params; }
|
||||
};
|
||||
|
||||
#endif
|
22
external/healpix/cxxsupport/planck.make
vendored
Normal file
22
external/healpix/cxxsupport/planck.make
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
PKG:=cxxsupport
|
||||
|
||||
SD:=$(SRCROOT)/$(PKG)
|
||||
OD:=$(BLDROOT)/$(PKG)
|
||||
|
||||
FULL_INCLUDE+= -I$(SD)
|
||||
|
||||
HDR_$(PKG):=$(SD)/*.h
|
||||
LIB_$(PKG):=$(LIBDIR)/libcxxsupport.a
|
||||
OBJ:=cxxutils.o fitshandle.o rotmatrix.o trafos.o ls_image.o error_handling.o wigner.o
|
||||
OBJ:=$(OBJ:%=$(OD)/%)
|
||||
|
||||
ODEP:=$(HDR_$(PKG)) $(HDR_libfftpack) $(HDR_c_utils)
|
||||
|
||||
$(OBJ): $(ODEP) | $(OD)_mkdir
|
||||
$(LIB_$(PKG)): $(OBJ)
|
||||
|
||||
$(OD)/fitshandle.o: $(HDR_libcfitsio)
|
||||
$(OD)/ls_image.o: $(SD)/font_data.inc
|
||||
|
||||
all_hdr+=$(HDR_$(PKG))
|
||||
all_lib+=$(LIB_$(PKG))
|
154
external/healpix/cxxsupport/planck_rng.h
vendored
Normal file
154
external/healpix/cxxsupport/planck_rng.h
vendored
Normal file
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* This file is part of libcxxsupport.
|
||||
*
|
||||
* libcxxsupport is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libcxxsupport is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libcxxsupport; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*! \file planck_rng.h
|
||||
* This file contains the random number generator
|
||||
* used by the Planck LevelS package.
|
||||
* The generator is a C++ port of the xorshift generator xor128() described
|
||||
* in Marsaglia, Journal of Statistical Software 2003, vol 8.
|
||||
* It has a period of 2^128 - 1.
|
||||
*
|
||||
* Copyright (C) 2003, 2004, 2005 Max-Planck-Society
|
||||
* \author Martin Reinecke
|
||||
*/
|
||||
|
||||
#ifndef PLANCK_RNG_H
|
||||
#define PLANCK_RNG_H
|
||||
|
||||
#include <cmath>
|
||||
#include "error_handling.h"
|
||||
|
||||
/*! C++ port of the xorshift generator xor128() described in Marsaglia,
|
||||
Journal of Statistical Software 2003, vol 8.
|
||||
It has a period of 2^128 - 1. */
|
||||
class planck_rng
|
||||
{
|
||||
private:
|
||||
unsigned int x,y,z,w;
|
||||
double small, gset;
|
||||
bool empty;
|
||||
|
||||
void twiddle (unsigned int &v)
|
||||
{
|
||||
for (int i=0; i<9; ++i)
|
||||
{
|
||||
v ^= v<<13;
|
||||
v ^= v>>17;
|
||||
v ^= v<<5;
|
||||
}
|
||||
}
|
||||
|
||||
void init_rng ()
|
||||
{
|
||||
// avoid zero seeds
|
||||
if (x==0) x = 123456789;
|
||||
if (y==0) y = 362436069;
|
||||
if (z==0) z = 521288629;
|
||||
if (w==0) w = 88675123;
|
||||
|
||||
// shuffle the bits of the seeds
|
||||
twiddle(x); twiddle(y); twiddle(z); twiddle(w);
|
||||
|
||||
// burn in the RNG
|
||||
for (int i=0; i<16; ++i)
|
||||
int_rand_uni();
|
||||
}
|
||||
|
||||
public:
|
||||
/*! Initializes the generator with 0 to 4 seed values. */
|
||||
planck_rng (unsigned int x1=123456789, unsigned int y1=362436069,
|
||||
unsigned int z1=521288629, unsigned int w1=88675123)
|
||||
: x(x1), y(y1), z(z1), w(w1),
|
||||
small(1./(1.+double(0xFFFFFFFF))), gset(0.), empty(true)
|
||||
{
|
||||
planck_assert (sizeof(unsigned int)==4, "wrong integer size for RNG");
|
||||
init_rng();
|
||||
}
|
||||
|
||||
/*! Re-initializes the generator with 0 to 4 seed values. */
|
||||
void seed (unsigned int x1=123456789, unsigned int y1=362436069,
|
||||
unsigned int z1=521288629, unsigned int w1=88675123)
|
||||
{
|
||||
x = x1; y = y1; z = z1; w = w1;
|
||||
empty = true;
|
||||
init_rng();
|
||||
}
|
||||
|
||||
/*! Returns uniformly distributed random integer numbers from the
|
||||
interval [0;0xFFFFFFFF]. */
|
||||
unsigned int int_rand_uni()
|
||||
{
|
||||
unsigned int t = x^(x<<11);
|
||||
x = y;
|
||||
y = z;
|
||||
z = w;
|
||||
|
||||
return w=(w^(w>>19))^(t^(t>>8));
|
||||
}
|
||||
|
||||
//! Returns uniformly distributed random numbers from the interval [0;1[.
|
||||
double rand_uni()
|
||||
{
|
||||
return small*int_rand_uni();
|
||||
}
|
||||
|
||||
//! Returns random numbers with Gaussian distribution (mean=0, sigma=1).
|
||||
/*! Uses rand_uni() internally. */
|
||||
double rand_gauss()
|
||||
{
|
||||
using namespace std;
|
||||
if (empty)
|
||||
{
|
||||
double v1,v2,rsq;
|
||||
do
|
||||
{
|
||||
v1=2*rand_uni()-1.;
|
||||
v2=2*rand_uni()-1.;
|
||||
rsq=v1*v1+v2*v2;
|
||||
}
|
||||
while ((rsq>=1) || (rsq==0));
|
||||
double fac=sqrt(-2*log(rsq)/rsq);
|
||||
gset=v1*fac;
|
||||
empty=false;
|
||||
return v2*fac;
|
||||
}
|
||||
else
|
||||
{
|
||||
empty=true;
|
||||
return gset;
|
||||
}
|
||||
}
|
||||
|
||||
//! Returns exponentially distributed random numbers (mean=1, nonnegative)
|
||||
/*! Uses rand_uni() internally. */
|
||||
double rand_exp()
|
||||
{
|
||||
using namespace std;
|
||||
double val=rand_uni();
|
||||
if (val==0.) val=1.;
|
||||
return -log(val);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
106
external/healpix/cxxsupport/pointing.h
vendored
Normal file
106
external/healpix/cxxsupport/pointing.h
vendored
Normal file
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* This file is part of libcxxsupport.
|
||||
*
|
||||
* libcxxsupport is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libcxxsupport is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libcxxsupport; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*! \file pointing.h
|
||||
* Class representing a direction in 3D space
|
||||
*
|
||||
* Copyright (C) 2003-2010 Max-Planck-Society
|
||||
* \author Martin Reinecke
|
||||
*/
|
||||
|
||||
#ifndef PLANCK_POINTING_H
|
||||
#define PLANCK_POINTING_H
|
||||
|
||||
#include <cmath>
|
||||
#include "vec3.h"
|
||||
#include "cxxutils.h"
|
||||
|
||||
/*! \defgroup pointinggroup Pointings */
|
||||
/*! \{ */
|
||||
|
||||
/*! Class representing a direction in 3D space or a location on the
|
||||
unit sphere. All angles in radians. */
|
||||
class pointing
|
||||
{
|
||||
public:
|
||||
/*! Colatitude of the pointing (i.e. the North pole is at \a theta=0). */
|
||||
double theta;
|
||||
/*! Longitude of the pointing. */
|
||||
double phi;
|
||||
|
||||
/*! Default constructor. \a theta and \a phi are not initialized. */
|
||||
pointing() {}
|
||||
/*! Creates a pointing with \a Theta and \a Phi. */
|
||||
pointing (double Theta, double Phi) : theta(Theta), phi(Phi) {}
|
||||
|
||||
// FIXME: should become "explicit" some time
|
||||
/*! Creates a pointing from the vector \a inp. \a inp need not be
|
||||
normalized. */
|
||||
pointing (const vec3 &inp)
|
||||
{ from_vec3(inp); }
|
||||
// FIXME: should be removed some time
|
||||
/*! Returns a normalized vector pointing in the same direction. */
|
||||
operator vec3() const
|
||||
{ return to_vec3(); }
|
||||
/*! Returns a normalized vector pointing in the same direction. */
|
||||
vec3 to_vec3() const
|
||||
{
|
||||
double st=sin(theta);
|
||||
return vec3 (st*cos(phi), st*sin(phi), cos(theta));
|
||||
}
|
||||
/*! Converts \a inp to \a ptg. \a inp need not be normalized. */
|
||||
void from_vec3 (const vec3 &inp)
|
||||
{
|
||||
using namespace std;
|
||||
const double twopi_=6.283185307179586476925286766559005768394;
|
||||
theta = atan2(sqrt(inp.x*inp.x+inp.y*inp.y),inp.z);
|
||||
phi = safe_atan2 (inp.y,inp.x);
|
||||
if (phi<0.) phi += twopi_;
|
||||
}
|
||||
/*! Changes the angles so that \a 0<=theta<=pi and \a 0<=phi<2*pi. */
|
||||
void normalize()
|
||||
{
|
||||
const double pi_=3.141592653589793238462643383279502884197;
|
||||
const double twopi_=6.283185307179586476925286766559005768394;
|
||||
theta=fmodulo(theta,twopi_);
|
||||
if (theta>pi_)
|
||||
{
|
||||
phi+=pi_;
|
||||
theta=twopi_-theta;
|
||||
}
|
||||
phi=fmodulo(phi,twopi_);
|
||||
}
|
||||
};
|
||||
|
||||
/*! Writes \a p to \a os.
|
||||
\relates pointing */
|
||||
inline std::ostream &operator<< (std::ostream &os, const pointing &p)
|
||||
{
|
||||
os << p.theta << ", " << p.phi << std::endl;
|
||||
return os;
|
||||
}
|
||||
|
||||
/*! \} */
|
||||
|
||||
#endif
|
177
external/healpix/cxxsupport/rotmatrix.cc
vendored
Normal file
177
external/healpix/cxxsupport/rotmatrix.cc
vendored
Normal file
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* This file is part of libcxxsupport.
|
||||
*
|
||||
* libcxxsupport is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libcxxsupport is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libcxxsupport; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Class for rotation transforms in 3D space
|
||||
*
|
||||
* Copyright (C) 2003 Max-Planck-Society
|
||||
* Author: Martin Reinecke
|
||||
*/
|
||||
|
||||
#include "rotmatrix.h"
|
||||
#include "vec3.h"
|
||||
#include "lsconstants.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
rotmatrix::rotmatrix (const vec3 &a, const vec3 &b, const vec3 &c)
|
||||
{
|
||||
entry[0][0]=a.x; entry[0][1]=b.x; entry[0][2]=c.x;
|
||||
entry[1][0]=a.y; entry[1][1]=b.y; entry[1][2]=c.y;
|
||||
entry[2][0]=a.z; entry[2][1]=b.z; entry[2][2]=c.z;
|
||||
}
|
||||
|
||||
void rotmatrix::SetToIdentity ()
|
||||
{
|
||||
entry[0][0] = entry[1][1] = entry[2][2] = 1.;
|
||||
entry[0][1] = entry[1][0] = entry[0][2] =
|
||||
entry[2][0] = entry[1][2] = entry[2][1] = 0.;
|
||||
}
|
||||
|
||||
void rotmatrix::SetToZero ()
|
||||
{
|
||||
for (int m=0; m<3; ++m)
|
||||
entry[m][0] = entry[m][1] = entry[m][2] = 0;
|
||||
}
|
||||
|
||||
void rotmatrix::Transpose ()
|
||||
{
|
||||
swap(entry[0][1], entry[1][0]);
|
||||
swap(entry[0][2], entry[2][0]);
|
||||
swap(entry[1][2], entry[2][1]);
|
||||
}
|
||||
|
||||
void rotmatrix::toAxisAngle (vec3 &axis, double &angle) const
|
||||
{
|
||||
double c2 = entry[0][0] + entry[1][1] + entry[2][2] - 1;
|
||||
axis.x = entry[2][1] - entry[1][2];
|
||||
axis.y = entry[0][2] - entry[2][0];
|
||||
axis.z = entry[1][0] - entry[0][1];
|
||||
|
||||
double s2 = axis.Length();
|
||||
|
||||
if (s2>0)
|
||||
{
|
||||
angle = atan2(s2,c2);
|
||||
axis *= 1/s2;
|
||||
return;
|
||||
}
|
||||
|
||||
if (c2>=2) // angle is 0
|
||||
{
|
||||
axis = vec3(1,0,0);
|
||||
angle = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
angle = pi;
|
||||
|
||||
int choice = 0; // assume entry[0][0] is the largest
|
||||
if ((entry[1][1]>entry[0][0]) && (entry[1][1]>entry[2][2])) choice=1;
|
||||
if ((entry[2][2]>entry[0][0]) && (entry[2][2]>entry[1][1])) choice=2;
|
||||
|
||||
if (choice==0)
|
||||
{
|
||||
axis.x = 0.5*sqrt(entry[0][0]-entry[1][1]-entry[2][2]+1);
|
||||
double half_inv = 0.5/axis.x;
|
||||
axis.y = half_inv*entry[0][1];
|
||||
axis.z = half_inv*entry[0][2];
|
||||
return;
|
||||
}
|
||||
if (choice==1)
|
||||
{
|
||||
axis.y = 0.5*sqrt(entry[1][1]-entry[0][0]-entry[2][2]+1);
|
||||
double half_inv = 0.5/axis.y;
|
||||
axis.x = half_inv*entry[0][1];
|
||||
axis.z = half_inv*entry[1][2];
|
||||
return;
|
||||
}
|
||||
|
||||
axis.z = 0.5*sqrt(entry[2][2]-entry[0][0]-entry[1][1]+1);
|
||||
double half_inv = 0.5/axis.z;
|
||||
axis.x = half_inv*entry[0][2];
|
||||
axis.y = half_inv*entry[1][2];
|
||||
}
|
||||
|
||||
void rotmatrix::Make_CPAC_Euler_Matrix
|
||||
(double alpha, double beta, double gamma)
|
||||
{
|
||||
double ca=cos(alpha), cb=cos(beta), cg=cos(gamma);
|
||||
double sa=sin(alpha), sb=sin(beta), sg=sin(gamma);
|
||||
|
||||
entry[0][0]= ca*cb*cg-sa*sg; entry[0][1]=-ca*cb*sg-sa*cg; entry[0][2]= ca*sb;
|
||||
entry[1][0]= sa*cb*cg+ca*sg; entry[1][1]=-sa*cb*sg+ca*cg; entry[1][2]= sa*sb;
|
||||
entry[2][0]=-sb*cg; entry[2][1]= sb*sg; entry[2][2]= cb;
|
||||
}
|
||||
|
||||
void rotmatrix::Extract_CPAC_Euler_Angles
|
||||
(double &alpha, double &beta, double &gamma) const
|
||||
{
|
||||
double cb = entry[2][2];
|
||||
double sb = sqrt(entry[0][2]*entry[0][2] + entry[1][2]*entry[1][2]);
|
||||
beta=atan2(sb,cb);
|
||||
if (abs(sb)<=1e-6)
|
||||
{
|
||||
alpha=0;
|
||||
if (cb>0)
|
||||
gamma=atan2(entry[1][0],entry[0][0]);
|
||||
else
|
||||
gamma=atan2(entry[0][1],-entry[0][0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
alpha=atan2(entry[1][2],entry[0][2]);
|
||||
gamma=atan2(entry[2][1],-entry[2][0]);
|
||||
}
|
||||
}
|
||||
|
||||
rotmatrix operator* (const rotmatrix &a, const rotmatrix &b)
|
||||
{
|
||||
rotmatrix res;
|
||||
for (int i=0; i<3; ++i)
|
||||
for (int j=0; j<3; ++j)
|
||||
res.entry[i][j] = a.entry[i][0] * b.entry[0][j]
|
||||
+ a.entry[i][1] * b.entry[1][j]
|
||||
+ a.entry[i][2] * b.entry[2][j];
|
||||
return res;
|
||||
}
|
||||
|
||||
void TransposeTimes (const rotmatrix &a, const rotmatrix &b, rotmatrix &res)
|
||||
{
|
||||
for (int i=0; i<3; ++i)
|
||||
for (int j=0; j<3; ++j)
|
||||
res.entry[i][j] = a.entry[0][i] * b.entry[0][j]
|
||||
+ a.entry[1][i] * b.entry[1][j]
|
||||
+ a.entry[2][i] * b.entry[2][j];
|
||||
}
|
||||
|
||||
ostream &operator<< (ostream &os, const rotmatrix &mat)
|
||||
{
|
||||
for (int i=0;i<3;++i)
|
||||
os << mat.entry[i][0] << ' '
|
||||
<< mat.entry[i][1] << ' '
|
||||
<< mat.entry[i][2] << endl;
|
||||
return os;
|
||||
}
|
158
external/healpix/cxxsupport/rotmatrix.h
vendored
Normal file
158
external/healpix/cxxsupport/rotmatrix.h
vendored
Normal file
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* This file is part of libcxxsupport.
|
||||
*
|
||||
* libcxxsupport is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libcxxsupport is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libcxxsupport; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*! \file rotmatrix.h
|
||||
* Class for rotation transforms in 3D space
|
||||
*
|
||||
* Copyright (C) 2003 Max-Planck-Society
|
||||
* \author Martin Reinecke
|
||||
*/
|
||||
|
||||
#ifndef PLANCK_ROTMATRIX_H
|
||||
#define PLANCK_ROTMATRIX_H
|
||||
|
||||
#include <iostream>
|
||||
#include "cxxutils.h"
|
||||
#include "vec3.h"
|
||||
|
||||
/*! \defgroup rotmatrixgroup Rotation matrices */
|
||||
/*! \{ */
|
||||
|
||||
/*! Class for rotation transforms in 3D space */
|
||||
class rotmatrix
|
||||
{
|
||||
public:
|
||||
double entry[3][3];
|
||||
|
||||
rotmatrix () {}
|
||||
|
||||
/*! Constructs a rotation matrix from its nine entries */
|
||||
rotmatrix (double a00, double a01, double a02,
|
||||
double a10, double a11, double a12,
|
||||
double a20, double a21, double a22)
|
||||
{
|
||||
entry[0][0]=a00; entry[0][1]=a01; entry[0][2]=a02;
|
||||
entry[1][0]=a10; entry[1][1]=a11; entry[1][2]=a12;
|
||||
entry[2][0]=a20; entry[2][1]=a21; entry[2][2]=a22;
|
||||
}
|
||||
|
||||
/*! Constructs a rotation matrix so that \a a is the first column,
|
||||
\a b is the second column and \a c is the third column.
|
||||
\note The vectors \a a, \a b and \a c must form an orthonormal system!
|
||||
*/
|
||||
rotmatrix (const vec3 &a, const vec3 &b, const vec3 &c);
|
||||
|
||||
/*! Sets the matrix to the identity matrix. */
|
||||
void SetToIdentity ();
|
||||
/*! Sets all matrix elements to zero. */
|
||||
void SetToZero ();
|
||||
/*! Transposes the matrix. */
|
||||
void Transpose ();
|
||||
|
||||
/*! Extracts a unit-length rotation axis \a axis and a rotation angle
|
||||
\a angle from the matrix. */
|
||||
void toAxisAngle (vec3 &axis, double &angle) const;
|
||||
|
||||
/*! Constructs a matrix which causes a rotation by \a angle around
|
||||
\a axis. \a axis must have unit length. */
|
||||
void Make_Axis_Rotation_Transform (const vec3 &axis, double angle)
|
||||
{
|
||||
double sa=sin(angle), ca=cos(angle);
|
||||
double ica=1-ca;
|
||||
entry[0][0] = axis.x*axis.x*ica + ca;
|
||||
entry[1][1] = axis.y*axis.y*ica + ca;
|
||||
entry[2][2] = axis.z*axis.z*ica + ca;
|
||||
double t1 = axis.x*axis.y*ica, t2 = axis.z*sa;
|
||||
entry[1][0] = t1 + t2;
|
||||
entry[0][1] = t1 - t2;
|
||||
t1 = axis.x*axis.z*ica; t2 = axis.y*sa;
|
||||
entry[2][0] = t1 - t2;
|
||||
entry[0][2] = t1 + t2;
|
||||
t1 = axis.y*axis.z*ica; t2 = axis.x*sa;
|
||||
entry[1][2] = t1 - t2;
|
||||
entry[2][1] = t1 + t2;
|
||||
}
|
||||
|
||||
/*! Creates a rotation matrix \a A, which performs the following operations
|
||||
on a vector \a v, when \a Av is calculated:
|
||||
-# rotate \a v around the z-axis by \a gamma,
|
||||
-# rotate \a v' around the y-axis by \a beta,
|
||||
-# rotate \a v'' around the z-axis by \a alpha.
|
||||
|
||||
\note \a alpha, \a beta and \a gamma are given in radians,
|
||||
the rotations are right handed.
|
||||
|
||||
\note This transformation rotates the \e vectors, not the coordinate
|
||||
axes! */
|
||||
void Make_CPAC_Euler_Matrix (double alpha, double beta, double gamma);
|
||||
|
||||
/*! Extracts the Euler angles \a alpha, \a beta and \a gamma from the
|
||||
matrix. For their definition see Make_CPAC_Euler_Matrix().
|
||||
|
||||
\note In case of ambiguity \a alpha will be 0. */
|
||||
void Extract_CPAC_Euler_Angles
|
||||
(double &alpha, double &beta, double &gamma) const;
|
||||
|
||||
/*! Returns the vector \a vec, transformed by the matrix. */
|
||||
vec3 Transform (const vec3 &vec) const
|
||||
{
|
||||
return vec3
|
||||
(vec.x*entry[0][0] + vec.y*entry[0][1] + vec.z*entry[0][2],
|
||||
vec.x*entry[1][0] + vec.y*entry[1][1] + vec.z*entry[1][2],
|
||||
vec.x*entry[2][0] + vec.y*entry[2][1] + vec.z*entry[2][2]);
|
||||
}
|
||||
/*! Returns the vector \a vec, transformed by the matrix, in \a vec2. */
|
||||
void Transform (const vec3 &vec, vec3 &vec2) const
|
||||
{
|
||||
vec2.x = vec.x*entry[0][0] + vec.y*entry[0][1] + vec.z*entry[0][2];
|
||||
vec2.y = vec.x*entry[1][0] + vec.y*entry[1][1] + vec.z*entry[1][2];
|
||||
vec2.z = vec.x*entry[2][0] + vec.y*entry[2][1] + vec.z*entry[2][2];
|
||||
}
|
||||
};
|
||||
|
||||
/*! Returns \a a * \a b.
|
||||
\relates rotmatrix */
|
||||
rotmatrix operator* (const rotmatrix &a, const rotmatrix &b);
|
||||
/*! Returns \a a * \a b in \a res.
|
||||
\relates rotmatrix */
|
||||
inline void matmult (const rotmatrix &a, const rotmatrix &b, rotmatrix &res)
|
||||
{
|
||||
for (int i=0; i<3; ++i)
|
||||
for (int j=0; j<3; ++j)
|
||||
res.entry[i][j] = a.entry[i][0] * b.entry[0][j]
|
||||
+ a.entry[i][1] * b.entry[1][j]
|
||||
+ a.entry[i][2] * b.entry[2][j];
|
||||
}
|
||||
|
||||
/*! Returns \a a^T * \a b in \a res.
|
||||
\relates rotmatrix */
|
||||
void TransposeTimes (const rotmatrix &a, const rotmatrix &b, rotmatrix &res);
|
||||
|
||||
/*! Writes \a mat to \a os.
|
||||
\relates rotmatrix */
|
||||
std::ostream &operator<< (std::ostream &os, const rotmatrix &mat);
|
||||
|
||||
/*! \} */
|
||||
|
||||
#endif
|
92
external/healpix/cxxsupport/safe_cast.h
vendored
Normal file
92
external/healpix/cxxsupport/safe_cast.h
vendored
Normal file
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* This file is part of libcxxsupport.
|
||||
*
|
||||
* libcxxsupport is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libcxxsupport is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libcxxsupport; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*! \file safe_cast.h
|
||||
* Numerical cast operator with additional checks that the value is preserved.
|
||||
*
|
||||
* Copyright (C) 2009 Max-Planck-Society
|
||||
* Author: Martin Reinecke
|
||||
*/
|
||||
|
||||
#ifndef PLANCK_SAFE_CAST_H
|
||||
#define PLANCK_SAFE_CAST_H
|
||||
|
||||
#include <limits>
|
||||
#include "error_handling.h"
|
||||
|
||||
template<typename T1, typename T2, bool s1, bool s2> struct safe_cast_helper__
|
||||
{};
|
||||
|
||||
template<typename T1, typename T2> struct safe_cast_helper__ <T1,T2,true,true>
|
||||
{
|
||||
static T1 cast (const T2 &arg)
|
||||
{
|
||||
T1 res = T1(arg);
|
||||
planck_assert(T2(res)==arg, "safe_cast: value changed during cast");
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T1, typename T2> struct safe_cast_helper__ <T1,T2,false,false>
|
||||
{
|
||||
static T1 cast (const T2 &arg)
|
||||
{
|
||||
T1 res = T1(arg);
|
||||
planck_assert(T2(res)==arg, "safe_cast: value changed during cast");
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T1, typename T2> struct safe_cast_helper__ <T1,T2,true,false>
|
||||
{
|
||||
static T1 cast (const T2 &arg)
|
||||
{
|
||||
T1 res = T1(arg);
|
||||
planck_assert((res>=0) && (T2(res)==arg),
|
||||
"safe_cast: value changed during cast");
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T1, typename T2> struct safe_cast_helper__ <T1,T2,false,true>
|
||||
{
|
||||
static T1 cast (const T2 &arg)
|
||||
{
|
||||
T1 res = T1(arg);
|
||||
planck_assert((arg>=0) && (T2(res)==arg),
|
||||
"safe_cast: value changed during cast");
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
/*! Tries to cast \a arg from its type to a variable of type \c T1.
|
||||
If this conversion leads to a change of the actual value (e.g. due to
|
||||
overflow or truncation), an exception is thrown. */
|
||||
template<typename T1, typename T2> inline T1 safe_cast(const T2 &arg)
|
||||
{
|
||||
return safe_cast_helper__<T1,T2,std::numeric_limits<T1>::is_signed,
|
||||
std::numeric_limits<T2>::is_signed>::cast(arg);
|
||||
}
|
||||
|
||||
#endif
|
158
external/healpix/cxxsupport/trafos.cc
vendored
Normal file
158
external/healpix/cxxsupport/trafos.cc
vendored
Normal file
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* This file is part of libcxxsupport.
|
||||
*
|
||||
* libcxxsupport is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libcxxsupport is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libcxxsupport; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*! \file trafos.cc
|
||||
* Celestial coordinate transformations.
|
||||
*
|
||||
* Copyright (C) 2005 Max-Planck-Society
|
||||
* \author Martin Reinecke
|
||||
*/
|
||||
|
||||
#include "trafos.h"
|
||||
#include "lsconstants.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
vec3 Trafo::xcc_dp_precess (const vec3 &iv, double iepoch,
|
||||
double oepoch)
|
||||
{
|
||||
// Z-axis rotation by OBL_LONG:
|
||||
double Tm = ((oepoch+iepoch)*0.5 - 1900.) *0.01;
|
||||
double gp_long = degr2rad * ((oepoch-iepoch) * (50.2564+0.0222*Tm) / 3600.);
|
||||
double obl_long =
|
||||
degr2rad * (180. - (173. + (57.06+54.77*Tm) / 60.)) + gp_long*0.5;
|
||||
double dco = cos(obl_long), dso = sin(obl_long);
|
||||
vec3 ov (iv.x*dco-iv.y*dso, iv.x*dso+iv.y*dco, iv.z);
|
||||
|
||||
// X-axis rotation by dE:
|
||||
double dE = degr2rad * ((oepoch-iepoch) * (0.4711-0.0007*Tm) / 3600.);
|
||||
double dce = cos(dE), dse = sin(dE);
|
||||
double temp = ov.y*dce - ov.z*dse;
|
||||
ov.z = ov.y*dse + ov.z*dce;
|
||||
ov.y = temp;
|
||||
|
||||
// Z-axis rotation by GP_LONG - OBL_LONG:
|
||||
double dL = gp_long - obl_long;
|
||||
double dcl = cos(dL), dsl = sin(dL);
|
||||
temp = ov.x*dcl - ov.y*dsl;
|
||||
ov.y = ov.x*dsl + ov.y*dcl;
|
||||
ov.x = temp;
|
||||
|
||||
return ov;
|
||||
}
|
||||
|
||||
double Trafo::get_epsilon (double epoch)
|
||||
{
|
||||
double T = (epoch - 1900.) * 0.01;
|
||||
return
|
||||
degr2rad * (23.452294 - 0.0130125*T - 1.63889e-6*T*T + 5.02778e-7*T*T*T);
|
||||
}
|
||||
|
||||
/*! Routine to convert from ecliptic coordinates to equatorial (celestial)
|
||||
coordinates at the given epoch. Adapted from the COBLIB routine by Dr.
|
||||
E. Wright. */
|
||||
vec3 Trafo::xcc_dp_e_to_q (const vec3 &iv, double epoch)
|
||||
{
|
||||
double epsilon=get_epsilon(epoch);
|
||||
double dc = cos(epsilon), ds = sin(epsilon);
|
||||
return vec3 (iv.x, dc*iv.y-ds*iv.z, dc*iv.z+ds*iv.y);
|
||||
}
|
||||
|
||||
vec3 Trafo::xcc_dp_q_to_e (const vec3 &iv, double epoch)
|
||||
{
|
||||
double epsilon=-get_epsilon(epoch);
|
||||
double dc = cos(epsilon), ds = sin(epsilon);
|
||||
return vec3 (iv.x, dc*iv.y-ds*iv.z, dc*iv.z+ds*iv.y);
|
||||
}
|
||||
|
||||
/*! Routine to convert galactic coordinates to ecliptic (celestial)
|
||||
coordinates at the given epoch. First the conversion to ecliptic
|
||||
2000 is done, then if necessary the results are precessed. */
|
||||
vec3 Trafo::xcc_dp_g_to_e (const vec3 &iv, double epoch)
|
||||
{
|
||||
static const rotmatrix T (-0.054882486, 0.494116468, -0.867661702,
|
||||
-0.993821033, -0.110993846, -0.000346354,
|
||||
-0.096476249, 0.862281440, 0.497154957);
|
||||
vec3 hv=T.Transform(iv);
|
||||
|
||||
if (!approx(epoch,2000.))
|
||||
hv=xcc_dp_precess(hv,2000.,epoch);
|
||||
|
||||
return hv;
|
||||
}
|
||||
|
||||
/*! Routine to convert ecliptic (celestial) coordinates at the given
|
||||
epoch to galactic coordinates. The ecliptic coordinates are first
|
||||
precessed to 2000.0, then converted. */
|
||||
vec3 Trafo::xcc_dp_e_to_g (const vec3 &iv, double epoch)
|
||||
{
|
||||
static const rotmatrix T (-0.054882486, -0.993821033, -0.096476249,
|
||||
0.494116468, -0.110993846, 0.862281440,
|
||||
-0.867661702, -0.000346354, 0.497154957);
|
||||
vec3 hv=iv;
|
||||
if (!approx(epoch,2000.))
|
||||
hv=xcc_dp_precess(hv,epoch,2000.);
|
||||
|
||||
return T.Transform(hv);
|
||||
}
|
||||
|
||||
/*! Function to convert between standard coordinate systems, including
|
||||
precession. */
|
||||
vec3 Trafo::xcc_v_convert(const vec3 &iv, double iepoch, double oepoch,
|
||||
coordsys isys,coordsys osys)
|
||||
{
|
||||
vec3 xv;
|
||||
if (isys == Ecliptic)
|
||||
xv=iv;
|
||||
else if (isys == Equatorial)
|
||||
xv = xcc_dp_q_to_e(iv,iepoch);
|
||||
else if (isys == Galactic)
|
||||
xv = xcc_dp_g_to_e(iv,iepoch);
|
||||
else
|
||||
planck_fail("Unsupported input coordinate system");
|
||||
|
||||
vec3 yv = approx(iepoch,oepoch) ? xv : xcc_dp_precess(xv,iepoch,oepoch);
|
||||
|
||||
vec3 ov;
|
||||
if (osys == Ecliptic)
|
||||
ov = yv;
|
||||
else if (osys == Equatorial)
|
||||
ov = xcc_dp_e_to_q(yv,oepoch);
|
||||
else if (osys == Galactic)
|
||||
ov = xcc_dp_e_to_g(yv,oepoch);
|
||||
else
|
||||
planck_fail("Unsupported output coordinate system");
|
||||
|
||||
return ov;
|
||||
}
|
||||
|
||||
void Trafo::coordsys2matrix (double iepoch, double oepoch,
|
||||
coordsys isys, coordsys osys, rotmatrix &matrix)
|
||||
{
|
||||
vec3 v1p = xcc_v_convert(vec3(1,0,0),iepoch,oepoch,isys,osys),
|
||||
v2p = xcc_v_convert(vec3(0,1,0),iepoch,oepoch,isys,osys),
|
||||
v3p = xcc_v_convert(vec3(0,0,1),iepoch,oepoch,isys,osys);
|
||||
v1p.Normalize(); v2p.Normalize(); v3p.Normalize();
|
||||
matrix=rotmatrix(v1p,v2p,v3p);
|
||||
}
|
103
external/healpix/cxxsupport/trafos.h
vendored
Normal file
103
external/healpix/cxxsupport/trafos.h
vendored
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* This file is part of libcxxsupport.
|
||||
*
|
||||
* libcxxsupport is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libcxxsupport is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libcxxsupport; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*! \file trafos.h
|
||||
* Celestial coordinate transformations.
|
||||
*
|
||||
* Copyright (C) 2005 Max-Planck-Society
|
||||
* \author Martin Reinecke
|
||||
*/
|
||||
#ifndef PLANCK_TRAFOS_H
|
||||
#define PLANCK_TRAFOS_H
|
||||
|
||||
#include "vec3.h"
|
||||
#include "pointing.h"
|
||||
#include "rotmatrix.h"
|
||||
#include "cxxutils.h"
|
||||
#include "geom_utils.h"
|
||||
|
||||
enum coordsys { Ecliptic, Equatorial, Galactic };
|
||||
|
||||
/*! Class for celestial coordinate transformations. */
|
||||
class Trafo
|
||||
{
|
||||
private:
|
||||
rotmatrix mat;
|
||||
|
||||
static vec3 xcc_dp_precess (const vec3 &iv, double iepoch, double oepoch);
|
||||
static double get_epsilon (double epoch);
|
||||
static vec3 xcc_dp_e_to_q (const vec3 &iv, double epoch);
|
||||
static vec3 xcc_dp_q_to_e (const vec3 &iv, double epoch);
|
||||
static vec3 xcc_dp_g_to_e (const vec3 &iv, double epoch);
|
||||
static vec3 xcc_dp_e_to_g (const vec3 &iv, double epoch);
|
||||
static vec3 xcc_v_convert(const vec3 &iv, double iepoch, double oepoch,
|
||||
coordsys isys,coordsys osys);
|
||||
static void coordsys2matrix (double iepoch, double oepoch, coordsys isys,
|
||||
coordsys osys, rotmatrix &matrix);
|
||||
|
||||
public:
|
||||
/*! Creates a \a Trafo for transformation from \a iepoch and \a isys
|
||||
to \a oepoch and \a osys. */
|
||||
Trafo (double iepoch, double oepoch, coordsys isys, coordsys osys)
|
||||
{ coordsys2matrix (iepoch, oepoch, isys, osys, mat); }
|
||||
|
||||
/*! Transforms the vector \a vec and returns the result. */
|
||||
vec3 operator() (const vec3 &vec) const
|
||||
{ return mat.Transform(vec); }
|
||||
|
||||
/*! Transforms the pointing \a ptg and returns the result. */
|
||||
pointing operator() (const pointing &ptg) const
|
||||
{ return pointing(operator()(vec3(ptg))); }
|
||||
|
||||
/*! Transforms the pointing \a ptg and returns it in \a newptg.
|
||||
On exit, \a delta_psi holds the change in orientation. */
|
||||
void rotatefull (const pointing &ptg, pointing &newptg,
|
||||
double &delta_psi) const
|
||||
{
|
||||
const double halfpi_=1.570796326794896619231321691639751442099;
|
||||
vec3 vec (ptg);
|
||||
vec3 east (-vec.y,vec.x,0.);
|
||||
vec3 newvec = operator()(vec);
|
||||
vec3 neweast = operator()(east);
|
||||
delta_psi = orientation(newvec,neweast)+halfpi_;
|
||||
newptg = newvec;
|
||||
}
|
||||
|
||||
/*! Transforms the vector \a vec and returns it in \a newvec.
|
||||
On exit, \a delta_psi holds the change in orientation. */
|
||||
void rotatefull (const vec3 &vec, vec3 &newvec, double &delta_psi) const
|
||||
{
|
||||
const double halfpi_=1.570796326794896619231321691639751442099;
|
||||
vec3 east (-vec.y,vec.x,0.);
|
||||
newvec = operator()(vec);
|
||||
vec3 neweast = operator()(east);
|
||||
delta_psi = orientation(newvec,neweast)+halfpi_;
|
||||
}
|
||||
|
||||
/*! Returns the internally used rotation matrix. */
|
||||
const rotmatrix &Matrix() const
|
||||
{ return mat; }
|
||||
};
|
||||
|
||||
#endif
|
149
external/healpix/cxxsupport/vec3.h
vendored
Normal file
149
external/healpix/cxxsupport/vec3.h
vendored
Normal file
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* This file is part of libcxxsupport.
|
||||
*
|
||||
* libcxxsupport is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libcxxsupport is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libcxxsupport; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*! \file vec3.h
|
||||
* Class representing 3D cartesian vectors
|
||||
*
|
||||
* Copyright (C) 2003, 2006 Max-Planck-Society
|
||||
* \author Martin Reinecke
|
||||
*/
|
||||
|
||||
#ifndef PLANCK_VEC3_H
|
||||
#define PLANCK_VEC3_H
|
||||
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include "datatypes.h"
|
||||
|
||||
/*! \defgroup vec3group 3D vectors */
|
||||
/*! \{ */
|
||||
|
||||
/*! Class representing a 3D cartesian vector. */
|
||||
template<typename T>class vec3_t
|
||||
{
|
||||
public:
|
||||
T x, /*!< x-coordinate */
|
||||
y, /*!< y-coordinate */
|
||||
z; /*!< z-coordinate */
|
||||
|
||||
/*! Default constructor. Does not initialize \a x, \a y, and \a z. */
|
||||
vec3_t () {}
|
||||
/*! Creates a vector with the coordinates \a xc, \a yc, and \a zc. */
|
||||
vec3_t (T xc, T yc, T zc)
|
||||
: x(xc), y(yc), z(zc) {}
|
||||
template<typename T2> explicit vec3_t (const vec3_t<T2> &orig)
|
||||
: x(orig.x), y(orig.y), z(orig.z) {}
|
||||
|
||||
/*! Sets the vector components to \a xc, \a yc, and \a zc. */
|
||||
void Set (T xc, T yc, T zc)
|
||||
{ x=xc; y=yc; z=zc; }
|
||||
/*! Creates a unit vector from a z coordinate and an azimuthal angle. */
|
||||
void set_z_phi (T z_, T phi)
|
||||
{
|
||||
using namespace std;
|
||||
T sintheta = sqrt((T(1)-z_)*(T(1)+z_));
|
||||
x = sintheta*cos(phi);
|
||||
y = sintheta*sin(phi);
|
||||
z = z_;
|
||||
}
|
||||
|
||||
/*! Normalizes the vector to length 1. */
|
||||
void Normalize ()
|
||||
{
|
||||
using namespace std;
|
||||
T l = T(1)/sqrt (x*x + y*y + z*z);
|
||||
x*=l; y*=l; z*=l;
|
||||
}
|
||||
|
||||
vec3_t Norm() const
|
||||
{
|
||||
vec3_t res(*this);
|
||||
res.Normalize();
|
||||
return res;
|
||||
}
|
||||
|
||||
/*! Returns the length of the vector. */
|
||||
T Length () const
|
||||
{ return sqrt (x*x + y*y + z*z); }
|
||||
|
||||
/*! Returns the squared length of the vector. */
|
||||
T SquaredLength () const
|
||||
{ return (x*x + y*y + z*z); }
|
||||
/*! Returns the vector with the signs of all coordinates flipped. */
|
||||
const vec3_t operator- () const
|
||||
{ return vec3_t (-x, -y, -z); }
|
||||
/*! Flips the signs of all coordinates. */
|
||||
void Flip ()
|
||||
{ x=-x; y=-y; z=-z; }
|
||||
/*! Returns (\a *this + \a vec). */
|
||||
const vec3_t operator+ (const vec3_t &vec) const
|
||||
{ return vec3_t (x+vec.x, y+vec.y, z+vec.z); }
|
||||
/*! Adds \a vec to \a *this. */
|
||||
vec3_t &operator+= (const vec3_t &vec)
|
||||
{ x+=vec.x; y+=vec.y; z+=vec.z; return *this; }
|
||||
/*! Returns (\a *this - \a vec). */
|
||||
const vec3_t operator- (const vec3_t &vec) const
|
||||
{ return vec3_t (x-vec.x, y-vec.y, z-vec.z); }
|
||||
/*! Subtracts \a vec from \a *this. */
|
||||
vec3_t &operator-= (const vec3_t &vec)
|
||||
{ x-=vec.x; y-=vec.y; z-=vec.z; return *this; }
|
||||
/*! Returns the vector scaled by \a fact. */
|
||||
const vec3_t operator* (T fact) const
|
||||
{ return vec3_t (x*fact, y*fact, z*fact); }
|
||||
/*! Returns the vector scaled by \a 1/fact. */
|
||||
const vec3_t operator/ (T fact) const
|
||||
{ T xfact = T(1)/fact; return vec3_t (x*xfact, y*xfact, z*xfact); }
|
||||
/*! Scales the vector by \a fact. */
|
||||
vec3_t &operator*= (T fact)
|
||||
{ x*=fact; y*=fact; z*=fact; return *this; }
|
||||
};
|
||||
|
||||
/*! Returns the dot product of \a v1 and \a v2.
|
||||
\relates vec3_t */
|
||||
template<typename T> inline T dotprod(const vec3_t<T> &v1, const vec3_t<T> &v2)
|
||||
{ return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z; }
|
||||
|
||||
/*! Returns the cross product of \a a and \a b.
|
||||
\relates vec3_t */
|
||||
template<typename T> inline vec3_t<T> crossprod
|
||||
(const vec3_t<T> &a, const vec3_t<T> &b)
|
||||
{ return vec3_t<T>(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x); }
|
||||
|
||||
/*! Writes \a v to \a os.
|
||||
\relates vec3_t */
|
||||
template<typename T> inline std::ostream &operator<<
|
||||
(std::ostream &os, const vec3_t<T> &v)
|
||||
{
|
||||
os << v.x << ", " << v.y << ", " << v.z << std::endl;
|
||||
return os;
|
||||
}
|
||||
|
||||
/*! Specialisation of vec3_t for 64-bit floating point components */
|
||||
typedef vec3_t<float64> vec3;
|
||||
/*! Specialisation of vec3_t for 32-bit floating point components */
|
||||
typedef vec3_t<float32> vec3f;
|
||||
|
||||
/*! \} */
|
||||
|
||||
#endif
|
583
external/healpix/cxxsupport/wigner.cc
vendored
Normal file
583
external/healpix/cxxsupport/wigner.cc
vendored
Normal file
|
@ -0,0 +1,583 @@
|
|||
/*
|
||||
* This file is part of libcxxsupport.
|
||||
*
|
||||
* libcxxsupport is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libcxxsupport is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libcxxsupport; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*! \file wigner.cc
|
||||
* Several C++ classes for calculating Wigner matrices
|
||||
*
|
||||
* Copyright (C) 2009,2010 Max-Planck-Society
|
||||
* \author Martin Reinecke and others (see individual classes)
|
||||
*/
|
||||
|
||||
#include "wigner.h"
|
||||
#include "lsconstants.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void wigner_d_halfpi_risbo_scalar::do_line0 (double *l1, int j)
|
||||
{
|
||||
double xj = pq/j;
|
||||
for (int i=n; i>=1; --i)
|
||||
l1[i] = xj*sqt[j]*(sqt[j-i]*l1[i] - sqt[i]*l1[i-1]);
|
||||
l1[0] = pq*l1[0];
|
||||
}
|
||||
void wigner_d_halfpi_risbo_scalar::do_line (const double *l1, double *l2,
|
||||
int j, int k)
|
||||
{
|
||||
double xj = pq/j;
|
||||
double t1 = xj*sqt[j-k];
|
||||
double t2 = xj*sqt[k];
|
||||
for (int i=n; i>=1; --i)
|
||||
l2[i] = t1 * (sqt[j-i]*l2[i] - sqt[i]*l2[i-1])
|
||||
+t2 * (sqt[j-i]*l1[i] + sqt[i]*l1[i-1]);
|
||||
l2[0] = sqt[j] * (t2*l1[0]+t1*l2[0]);
|
||||
}
|
||||
|
||||
wigner_d_halfpi_risbo_scalar::wigner_d_halfpi_risbo_scalar(int lmax)
|
||||
: pq(.5*sqrt(2.)), sqt(2*lmax+1), d(lmax+2,lmax+2), n(-1)
|
||||
{ for (tsize m=0; m<sqt.size(); ++m) sqt[m] = sqrt(double(m)); }
|
||||
|
||||
const arr2<double> &wigner_d_halfpi_risbo_scalar::recurse ()
|
||||
{
|
||||
++n;
|
||||
if (n==0)
|
||||
d[0][0] = 1;
|
||||
else if (n==1)
|
||||
{
|
||||
d[0][0] = .5; d[0][1] =-pq;
|
||||
d[1][0] = pq; d[1][1] = 0.;
|
||||
}
|
||||
else
|
||||
{
|
||||
//padding
|
||||
int flip = 1;
|
||||
for (int i=0; i<n; ++i)
|
||||
{
|
||||
d[i][n]=flip*d[i][n-2];
|
||||
d[n][i]=flip*d[n-2][i];
|
||||
flip=-flip;
|
||||
}
|
||||
d[n][n]=flip*d[n-2][n];
|
||||
|
||||
do_line (d[n-1],d[n],2*n-1,n);
|
||||
for (int k=n; k>=2; --k)
|
||||
{
|
||||
do_line (d[k-2],d[k-1],2*n-1,k-1);
|
||||
do_line (d[k-1],d[k],2*n,k);
|
||||
}
|
||||
do_line0 (d[0],2*n-1);
|
||||
do_line (d[0],d[1],2*n,1);
|
||||
do_line0 (d[0],2*n);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
void wigner_d_risbo_scalar::do_line0 (double *l1, int j)
|
||||
{
|
||||
double xj = 1./j;
|
||||
l1[j] = -p*l1[j-1];
|
||||
for (int i=j-1; i>=1; --i)
|
||||
l1[i] = xj*sqt[j]*(q*sqt[j-i]*l1[i] - p*sqt[i]*l1[i-1]);
|
||||
l1[0] = q*l1[0];
|
||||
}
|
||||
void wigner_d_risbo_scalar::do_line (const double *l1, double *l2, int j, int k)
|
||||
{
|
||||
double xj = 1./j;
|
||||
double t1 = xj*sqt[j-k]*q, t2 = xj*sqt[j-k]*p;
|
||||
double t3 = xj*sqt[k]*p, t4 = xj*sqt[k]*q;
|
||||
l2[j] = sqt[j] * (t4*l1[j-1]-t2*l2[j-1]);
|
||||
for (int i=j-1; i>=1; --i)
|
||||
l2[i] = t1*sqt[j-i]*l2[i] - t2*sqt[i]*l2[i-1]
|
||||
+t3*sqt[j-i]*l1[i] + t4*sqt[i]*l1[i-1];
|
||||
l2[0] = sqt[j] * (t3*l1[0]+t1*l2[0]);
|
||||
}
|
||||
|
||||
wigner_d_risbo_scalar::wigner_d_risbo_scalar(int lmax, double ang)
|
||||
: p(sin(ang/2)), q(cos(ang/2)), sqt(2*lmax+1),
|
||||
d(lmax+1,2*lmax+1), n(-1)
|
||||
{ for (tsize m=0; m<sqt.size(); ++m) sqt[m] = sqrt(double(m)); }
|
||||
|
||||
const arr2<double> &wigner_d_risbo_scalar::recurse ()
|
||||
{
|
||||
++n;
|
||||
if (n==0)
|
||||
d[0][0] = 1;
|
||||
else if (n==1)
|
||||
{
|
||||
d[0][0] = q*q; d[0][1] = -p*q*sqt[2]; d[0][2] = p*p;
|
||||
d[1][0] = -d[0][1]; d[1][1] = q*q-p*p; d[1][2] = d[0][1];
|
||||
}
|
||||
else
|
||||
{
|
||||
// padding
|
||||
int sign = (n&1)? -1 : 1;
|
||||
for (int i=0; i<=2*n-2; ++i)
|
||||
{
|
||||
d[n][i] = sign*d[n-2][2*n-2-i];
|
||||
sign=-sign;
|
||||
}
|
||||
do_line (d[n-1],d[n],2*n-1,n);
|
||||
for (int k=n; k>=2; --k)
|
||||
{
|
||||
do_line (d[k-2],d[k-1],2*n-1,k-1);
|
||||
do_line (d[k-1],d[k],2*n,k);
|
||||
}
|
||||
do_line0 (d[0],2*n-1);
|
||||
do_line (d[0],d[1],2*n,1);
|
||||
do_line0 (d[0],2*n);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
wigner_d_halfpi_risbo_openmp::wigner_d_halfpi_risbo_openmp(int lmax)
|
||||
: pq(.5*sqrt(2.)), sqt(2*lmax+1), d(lmax+2,lmax+2),
|
||||
dd(lmax+2,lmax+2), n(-1)
|
||||
{ for (tsize m=0; m<sqt.size(); ++m) sqt[m] = sqrt(double(m)); }
|
||||
|
||||
const arr2<double> &wigner_d_halfpi_risbo_openmp::recurse ()
|
||||
{
|
||||
++n;
|
||||
if (n==0)
|
||||
d[0][0] = 1;
|
||||
else if (n==1)
|
||||
{
|
||||
d.fast_alloc(3,3);
|
||||
d[0][0] = .5; d[0][1] =-pq;
|
||||
d[1][0] = pq; d[1][1] = 0.;
|
||||
}
|
||||
else
|
||||
{
|
||||
//padding
|
||||
int flip = 1;
|
||||
for (int i=0; i<n; ++i)
|
||||
{
|
||||
d[i][n]=flip*d[i][n-2];
|
||||
d[n][i]=flip*d[n-2][i];
|
||||
flip=-flip;
|
||||
}
|
||||
d[n][n]=flip*d[n-2][n];
|
||||
|
||||
for (int j=2*n-1; j<=2*n; ++j)
|
||||
{
|
||||
dd.fast_alloc(n+2,n+2);
|
||||
double tmpx1 = pq/j;
|
||||
dd[0][0] = pq*d[0][0];
|
||||
for (int i=1;i<=n; ++i)
|
||||
dd[0][i] = tmpx1*sqt[j]*(sqt[j-i]*d[0][i] - sqt[i]*d[0][i-1]);
|
||||
#pragma omp parallel
|
||||
{
|
||||
int k;
|
||||
#pragma omp for schedule(static)
|
||||
for (k=1; k<=n; ++k)
|
||||
{
|
||||
double stmp1=sqt[j-k]*tmpx1;
|
||||
double stmp2=sqt[k]*tmpx1;
|
||||
double save1 = stmp1*d[k][0], save2 = stmp2*d[k-1][0];
|
||||
dd[k][0] = sqt[j]*(save1+save2);
|
||||
for (int i=1; i<=n; ++i)
|
||||
{
|
||||
dd[k][i] = sqt[i]*(save2-save1);
|
||||
save1 = stmp1*d[k][i];
|
||||
save2 = stmp2*d[k-1][i];
|
||||
dd[k][i] += sqt[j-i]*(save1+save2);
|
||||
}
|
||||
}
|
||||
}
|
||||
dd.swap(d);
|
||||
}
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
wigner_d_risbo_openmp::wigner_d_risbo_openmp(int lmax, double ang)
|
||||
: p(sin(ang/2)), q(cos(ang/2)), sqt(2*lmax+1),
|
||||
d(lmax+1,2*lmax+1), dd(lmax+1,2*lmax+1), n(-1)
|
||||
{ for (tsize m=0; m<sqt.size(); ++m) sqt[m] = sqrt(double(m)); }
|
||||
|
||||
const arr2<double> &wigner_d_risbo_openmp::recurse ()
|
||||
{
|
||||
++n;
|
||||
if (n==0)
|
||||
d[0][0] = 1;
|
||||
else if (n==1)
|
||||
{
|
||||
d[0][0] = q*q; d[0][1] = -p*q*sqt[2]; d[0][2] = p*p;
|
||||
d[1][0] = -d[0][1]; d[1][1] = q*q-p*p; d[1][2] = d[0][1];
|
||||
}
|
||||
else
|
||||
{
|
||||
// padding
|
||||
int sign = (n&1)? -1 : 1;
|
||||
for (int i=0; i<=2*n-2; ++i)
|
||||
{
|
||||
d[n][i] = sign*d[n-2][2*n-2-i];
|
||||
sign=-sign;
|
||||
}
|
||||
for (int j=2*n-1; j<=2*n; ++j)
|
||||
{
|
||||
double xj = 1./j;
|
||||
dd[0][0] = q*d[0][0];
|
||||
for (int i=1;i<j; ++i)
|
||||
dd[0][i] = xj*sqt[j]*(q*sqt[j-i]*d[0][i] - p*sqt[i]*d[0][i-1]);
|
||||
dd[0][j] = -p*d[0][j-1];
|
||||
#pragma omp parallel
|
||||
{
|
||||
int k;
|
||||
#pragma omp for schedule(static)
|
||||
for (k=1; k<=n; ++k)
|
||||
{
|
||||
double t1 = xj*sqt[j-k]*q, t2 = xj*sqt[j-k]*p;
|
||||
double t3 = xj*sqt[k ]*p, t4 = xj*sqt[k ]*q;
|
||||
dd[k][0] = xj*sqt[j]*(q*sqt[j-k]*d[k][0] + p*sqt[k]*d[k-1][0]);
|
||||
for (int i=1; i<j; ++i)
|
||||
dd[k][i] = t1*sqt[j-i]*d[k ][i] - t2*sqt[i]*d[k ][i-1]
|
||||
+ t3*sqt[j-i]*d[k-1][i] + t4*sqt[i]*d[k-1][i-1];
|
||||
dd[k][j] = -t2*sqt[j]*d[k][j-1] + t4*sqt[j]*d[k-1][j-1];
|
||||
}
|
||||
}
|
||||
dd.swap(d);
|
||||
}
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
wignergen::wignergen (int lmax_, const arr<double> &thetas, double epsilon)
|
||||
: eps(epsilon), lmax(lmax_),
|
||||
logsum(2*lmax+1), lc05(thetas.size()), ls05(thetas.size()),
|
||||
flm1(2*lmax+1), flm2(2*lmax+1),
|
||||
cf(maxscale+1-minscale), costh(thetas.size()), xl(lmax+1),
|
||||
thetaflip(thetas.size()),
|
||||
m1(-1234567890), m2(-1234567890), am1(-1234567890), am2(-1234567890),
|
||||
mlo(-1234567890), mhi(-1234567890),
|
||||
fx(lmax+2), result(lmax+1)
|
||||
#ifdef PLANCK_HAVE_SSE2
|
||||
, result2(lmax+1)
|
||||
#endif
|
||||
{
|
||||
planck_assert(lmax>0,"lmax too small");
|
||||
logsum[0] = 0.;
|
||||
for (tsize m=1; m<logsum.size(); ++m)
|
||||
logsum[m] = logsum[m-1]+log(static_cast<long double>(m));
|
||||
for (tsize lm=0; lm<flm1.size(); ++lm)
|
||||
{
|
||||
flm1[lm] = sqrt(1./(lm+1.));
|
||||
flm2[lm] = sqrt(lm/(lm+1.));
|
||||
}
|
||||
for (tsize i=0; i<cf.size(); ++i)
|
||||
cf[i] = ldexp(1.,(int(i)+minscale)*large_exponent2);
|
||||
|
||||
fsmall = ldexp(1.,-large_exponent2);
|
||||
fbig = ldexp(1.,large_exponent2);
|
||||
|
||||
for (tsize i=0; i<thetas.size(); ++i)
|
||||
{
|
||||
double theta=fmodulo(thetas[i],twopi);
|
||||
if (theta>pi) theta-=twopi;
|
||||
thetaflip[i]=(theta<0);
|
||||
theta=abs(theta); // now theta is in (0; pi)
|
||||
// tiny adjustments to make sure cos and sin (theta/2) are positive
|
||||
if (theta==0.) theta=1e-16;
|
||||
if (abs_approx(theta,pi,1e-15)) theta=pi-1e-15;
|
||||
costh[i]=cos(theta);
|
||||
lc05[i]=log(cos(0.5L*theta));
|
||||
ls05[i]=log(sin(0.5L*theta));
|
||||
}
|
||||
xl[0]=0;
|
||||
for (tsize l=1; l<xl.size(); ++l) xl[l]=1./l;
|
||||
|
||||
for (tsize l=0; l<fx.size(); ++l)
|
||||
fx[l][0]=fx[l][1]=fx[l][2]=0.;
|
||||
}
|
||||
|
||||
void wignergen::prepare (int m1_, int m2_)
|
||||
{
|
||||
if ((m1_==m1) && (m2_==m2)) return;
|
||||
|
||||
int mlo_=abs(m1_), mhi_=abs(m2_);
|
||||
if (mhi_<mlo_) swap(mhi_,mlo_);
|
||||
bool ms_similar = ((mhi==mhi_) && (mlo==mlo_));
|
||||
bool flip_m_sign = ((m1*m2)!=(m1_*m2_));
|
||||
|
||||
m1=m1_; m2=m2_;
|
||||
mlo=am1=abs(m1); mhi=am2=abs(m2);
|
||||
if (mhi<mlo) swap(mhi,mlo);
|
||||
|
||||
if (ms_similar)
|
||||
{
|
||||
if (flip_m_sign)
|
||||
for (int l=mhi; l<lmax; ++l)
|
||||
fx[l+1][1]=-fx[l+1][1];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int l=mhi; l<lmax; ++l)
|
||||
{
|
||||
double t = flm1[l+m1]*flm1[l-m1]*flm1[l+m2]*flm1[l-m2];
|
||||
double lt = 2*l+1;
|
||||
double l1 = l+1;
|
||||
fx[l+1][0]=l1*lt*t;
|
||||
fx[l+1][1]=m1*m2*xl[l]*xl[l+1];
|
||||
t = flm2[l+m1]*flm2[l-m1]*flm2[l+m2]*flm2[l-m2];
|
||||
fx[l+1][2]=t*l1*xl[l];
|
||||
}
|
||||
}
|
||||
|
||||
prefactor = 0.5L*(logsum[2*mhi]-logsum[mhi+mlo]-logsum[mhi-mlo]);
|
||||
|
||||
preMinus = false;
|
||||
if (mhi==am1)
|
||||
{
|
||||
cosPow = mhi-m2; sinPow = mhi+m2;
|
||||
if (m1>=0)
|
||||
{ swap(cosPow, sinPow); preMinus=((mhi-m2)&1); }
|
||||
}
|
||||
else
|
||||
{
|
||||
cosPow = mhi+m1; sinPow = mhi-m1;
|
||||
if (m2<0)
|
||||
{ swap(cosPow, sinPow); preMinus=((mhi+m1)&1); }
|
||||
}
|
||||
}
|
||||
|
||||
const arr<double> &wignergen::calc (int nth, int &firstl)
|
||||
{
|
||||
int l=mhi;
|
||||
const dbl3 *fy = &fx[0];
|
||||
const double cth = costh[nth];
|
||||
double *res = &result[0];
|
||||
long double logval = prefactor + lc05[nth]*cosPow + ls05[nth]*sinPow;
|
||||
logval *= inv_ln2;
|
||||
int scale = int (logval/large_exponent2)-minscale;
|
||||
double rec1 = 0.;
|
||||
double rec2 = double(exp(ln2*(logval-(scale+minscale)*large_exponent2)));
|
||||
if (preMinus ^ (thetaflip[nth] && ((am1+am2)&1))) rec2 = -rec2;
|
||||
|
||||
while(scale<0) // iterate until we reach the realm of IEEE numbers
|
||||
{
|
||||
if (++l>lmax) break;
|
||||
rec1 = (cth - fy[l][1])*fy[l][0]*rec2 - fy[l][2]*rec1;
|
||||
if (++l>lmax) break;
|
||||
rec2 = (cth - fy[l][1])*fy[l][0]*rec1 - fy[l][2]*rec2;
|
||||
|
||||
while (abs(rec2)>fbig)
|
||||
{
|
||||
rec1 *= fsmall;
|
||||
rec2 *= fsmall;
|
||||
++scale;
|
||||
}
|
||||
}
|
||||
|
||||
if (scale<0) { firstl=lmax+1; return result; }
|
||||
rec1 *= cf[scale];
|
||||
rec2 *= cf[scale];
|
||||
|
||||
for (;l<lmax-1;l+=2) // iterate until we cross the eps threshold
|
||||
{
|
||||
if (abs(rec2)>eps) break;
|
||||
rec1 = (cth - fy[l+1][1])*fy[l+1][0]*rec2 - fy[l+1][2]*rec1;
|
||||
if (abs(rec1)>eps) { swap(rec1,rec2); ++l; break; }
|
||||
rec2 = (cth - fy[l+2][1])*fy[l+2][0]*rec1 - fy[l+2][2]*rec2;
|
||||
}
|
||||
if ((abs(rec2)<=eps) && (++l<=lmax))
|
||||
{
|
||||
rec1 = (cth - fy[l][1])*fy[l][0]*rec2 - fy[l][2]*rec1;
|
||||
swap (rec1,rec2);
|
||||
}
|
||||
|
||||
firstl = l;
|
||||
if (l>lmax) return result;
|
||||
|
||||
res[l]=rec2;
|
||||
|
||||
for (;l<lmax-1;l+=2)
|
||||
{
|
||||
res[l+1] = rec1 = (cth - fy[l+1][1])*fy[l+1][0]*rec2 - fy[l+1][2]*rec1;
|
||||
res[l+2] = rec2 = (cth - fy[l+2][1])*fy[l+2][0]*rec1 - fy[l+2][2]*rec2;
|
||||
}
|
||||
while (true)
|
||||
{
|
||||
if (++l>lmax) break;
|
||||
res[l] = rec1 = (cth - fy[l][1])*fy[l][0]*rec2 - fy[l][2]*rec1;
|
||||
if (++l>lmax) break;
|
||||
res[l] = rec2 = (cth - fy[l][1])*fy[l][0]*rec1 - fy[l][2]*rec2;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef PLANCK_HAVE_SSE2
|
||||
|
||||
#define RENORMALIZE \
|
||||
do \
|
||||
{ \
|
||||
double rec1a, rec1b, rec2a, rec2b, cfa, cfb; \
|
||||
read_v2df (rec1, &rec1a, &rec1b); read_v2df (rec2, &rec2a, &rec2b); \
|
||||
read_v2df (corfac, &cfa, &cfb); \
|
||||
while (abs(rec2a)>fbig) \
|
||||
{ \
|
||||
rec1a*=fsmall; rec2a*=fsmall; ++scale1; \
|
||||
cfa = (scale1<0) ? 0. : cf[scale1]; \
|
||||
} \
|
||||
while (abs(rec2b)>fbig) \
|
||||
{ \
|
||||
rec1b*=fsmall; rec2b*=fsmall; ++scale2; \
|
||||
cfb = (scale2<0) ? 0. : cf[scale2]; \
|
||||
} \
|
||||
rec1=build_v2df(rec1a,rec1b); rec2=build_v2df(rec2a,rec2b); \
|
||||
corfac=build_v2df(cfa,cfb); \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
#define GETPRE(prea,preb,lv) \
|
||||
prea=_mm_mul_pd(_mm_sub_pd(cth,_mm_set1_pd(fy[lv][1])),_mm_set1_pd(fy[lv][0])); \
|
||||
preb=_mm_set1_pd(fy[lv][2]);
|
||||
|
||||
#define NEXTSTEP(prea,preb,prec,pred,reca,recb,lv) \
|
||||
{ \
|
||||
prec = _mm_set1_pd(fy[lv][1]); \
|
||||
preb = _mm_mul_pd(preb,reca); \
|
||||
prea = _mm_mul_pd(prea,recb); \
|
||||
v2df t0 = _mm_set1_pd(fy[lv][0]); \
|
||||
prec = _mm_sub_pd(cth,prec); \
|
||||
pred = _mm_set1_pd(fy[lv][2]); \
|
||||
reca = _mm_sub_pd(prea,preb); \
|
||||
prec = _mm_mul_pd(prec,t0); \
|
||||
}
|
||||
|
||||
const arr_align<v2df,16> &wignergen::calc (int nth1, int nth2, int &firstl)
|
||||
{
|
||||
int l=mhi;
|
||||
const dbl3 *fy = &fx[0];
|
||||
const v2df cth = build_v2df(costh[nth1],costh[nth2]);
|
||||
v2df *res = &result2[0];
|
||||
long double logval1 = prefactor + lc05[nth1]*cosPow + ls05[nth1]*sinPow,
|
||||
logval2 = prefactor + lc05[nth2]*cosPow + ls05[nth2]*sinPow;
|
||||
logval1 *= inv_ln2;
|
||||
logval2 *= inv_ln2;
|
||||
int scale1 = int (logval1/large_exponent2)-minscale,
|
||||
scale2 = int (logval2/large_exponent2)-minscale;
|
||||
v2df rec1 = _mm_setzero_pd();
|
||||
double tr1 = double(exp(ln2*(logval1-(scale1+minscale)*large_exponent2))),
|
||||
tr2 = double(exp(ln2*(logval2-(scale2+minscale)*large_exponent2)));
|
||||
if (preMinus ^ (thetaflip[nth1] && ((am1+am2)&1))) tr1 = -tr1;
|
||||
if (preMinus ^ (thetaflip[nth2] && ((am1+am2)&1))) tr2 = -tr2;
|
||||
v2df rec2 = build_v2df(tr1,tr2);
|
||||
v2df corfac = build_v2df ( (scale1<0) ? 0. : cf[scale1],
|
||||
(scale2<0) ? 0. : cf[scale2]);
|
||||
|
||||
v2df eps2=build_v2df(eps,eps);
|
||||
v2df fbig2=build_v2df(fbig,fbig);
|
||||
|
||||
v2df pre0,pre1,pre2,pre3;
|
||||
|
||||
GETPRE(pre0,pre1,l+1)
|
||||
if ((scale1<0) && (scale2<0))
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (++l>lmax) break;
|
||||
NEXTSTEP(pre0,pre1,pre2,pre3,rec1,rec2,l+1)
|
||||
if (++l>lmax) break;
|
||||
NEXTSTEP(pre2,pre3,pre0,pre1,rec2,rec1,l+1)
|
||||
if (v2df_any_gt(rec2,fbig2))
|
||||
{
|
||||
RENORMALIZE;
|
||||
if ((scale1>=0) || (scale2>=0)) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (l<=lmax)
|
||||
{
|
||||
GETPRE(pre0,pre1,l+1)
|
||||
while (true)
|
||||
{
|
||||
v2df t1;
|
||||
res[l]=t1=_mm_mul_pd(rec2,corfac);
|
||||
if (v2df_any_gt(t1,eps2))
|
||||
break;
|
||||
|
||||
if (++l>lmax) break;
|
||||
NEXTSTEP(pre0,pre1,pre2,pre3,rec1,rec2,l+1)
|
||||
|
||||
res[l]=t1=_mm_mul_pd(rec1,corfac);
|
||||
if (v2df_any_gt(t1,eps2))
|
||||
{ swap(rec1,rec2); break; }
|
||||
|
||||
if (++l>lmax) break;
|
||||
NEXTSTEP(pre2,pre3,pre0,pre1,rec2,rec1,l+1)
|
||||
|
||||
if (v2df_any_gt(rec2,fbig2))
|
||||
RENORMALIZE;
|
||||
}
|
||||
}
|
||||
firstl=l;
|
||||
if (l>lmax) return result2;
|
||||
|
||||
GETPRE(pre0,pre1,l+1)
|
||||
while (true)
|
||||
{
|
||||
v2df t1;
|
||||
res[l]=t1=_mm_mul_pd(rec2,corfac);
|
||||
if (v2df_all_ge(t1,eps2))
|
||||
break;
|
||||
|
||||
if (++l>lmax) break;
|
||||
NEXTSTEP(pre0,pre1,pre2,pre3,rec1,rec2,l+1)
|
||||
|
||||
res[l]=t1=_mm_mul_pd(rec1,corfac);
|
||||
if (v2df_all_ge(t1,eps2))
|
||||
{ swap(rec1,rec2); break; }
|
||||
|
||||
if (++l>lmax) break;
|
||||
NEXTSTEP(pre2,pre3,pre0,pre1,rec2,rec1,l+1)
|
||||
|
||||
if (v2df_any_gt(rec2,fbig2))
|
||||
RENORMALIZE;
|
||||
}
|
||||
|
||||
if (l>lmax) return result2;
|
||||
rec1 = _mm_mul_pd (rec1,corfac);
|
||||
rec2 = _mm_mul_pd (rec2,corfac);
|
||||
|
||||
GETPRE(pre0,pre1,l+1)
|
||||
for (;l<lmax-1;l+=2)
|
||||
{
|
||||
res[l] = rec2;
|
||||
NEXTSTEP(pre0,pre1,pre2,pre3,rec1,rec2,l+2)
|
||||
res[l+1] = rec1;
|
||||
NEXTSTEP(pre2,pre3,pre0,pre1,rec2,rec1,l+3)
|
||||
}
|
||||
|
||||
res[l] = rec2;
|
||||
if (++l<=lmax)
|
||||
{
|
||||
NEXTSTEP(pre0,pre1,pre2,pre3,rec1,rec2,l+1)
|
||||
res[l] = rec1;
|
||||
}
|
||||
|
||||
return result2;
|
||||
}
|
||||
|
||||
#endif /* PLANCK_HAVE_SSE2 */
|
169
external/healpix/cxxsupport/wigner.h
vendored
Normal file
169
external/healpix/cxxsupport/wigner.h
vendored
Normal file
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* This file is part of libcxxsupport.
|
||||
*
|
||||
* libcxxsupport is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libcxxsupport is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libcxxsupport; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*! \file wigner.h
|
||||
* Several C++ classes for calculating Wigner matrices
|
||||
*
|
||||
* Copyright (C) 2009,2010 Max-Planck-Society
|
||||
* \author Martin Reinecke and others (see individual classes)
|
||||
*/
|
||||
|
||||
#ifndef PLANCK_WIGNER_H
|
||||
#define PLANCK_WIGNER_H
|
||||
|
||||
#include <cmath>
|
||||
#include "arr.h"
|
||||
|
||||
#include "sse_utils.h"
|
||||
|
||||
/*! Class for calculation of the Wigner matrix at pi/2, using Risbo recursion
|
||||
in a way that cannot easily be parallelised, but is fairly efficient on
|
||||
scalar machines. */
|
||||
class wigner_d_halfpi_risbo_scalar
|
||||
{
|
||||
private:
|
||||
double pq;
|
||||
arr<double> sqt;
|
||||
arr2<double> d;
|
||||
int n;
|
||||
|
||||
void do_line0 (double *l1, int j);
|
||||
void do_line (const double *l1, double *l2, int j, int k);
|
||||
|
||||
public:
|
||||
wigner_d_halfpi_risbo_scalar(int lmax);
|
||||
|
||||
const arr2<double> &recurse ();
|
||||
};
|
||||
|
||||
/*! Class for calculation of the Wigner matrix at arbitrary angles, using Risbo
|
||||
recursion in a way that cannot easily be parallelised, but is fairly
|
||||
efficient on scalar machines. */
|
||||
class wigner_d_risbo_scalar
|
||||
{
|
||||
private:
|
||||
double p,q;
|
||||
arr<double> sqt;
|
||||
arr2<double> d;
|
||||
int n;
|
||||
|
||||
void do_line0 (double *l1, int j);
|
||||
void do_line (const double *l1, double *l2, int j, int k);
|
||||
|
||||
public:
|
||||
wigner_d_risbo_scalar(int lmax, double ang);
|
||||
|
||||
const arr2<double> &recurse ();
|
||||
};
|
||||
|
||||
/*! Class for calculation of the Wigner matrix at pi/2, using Risbo recursion
|
||||
in a way that can be OpenMP-parallelised. This approach uses more memory
|
||||
and is slightly slower than wigner_d_halfpi_risbo_scalar. */
|
||||
class wigner_d_halfpi_risbo_openmp
|
||||
{
|
||||
private:
|
||||
double pq;
|
||||
arr<double> sqt;
|
||||
arr2<double> d,dd;
|
||||
int n;
|
||||
|
||||
public:
|
||||
wigner_d_halfpi_risbo_openmp(int lmax);
|
||||
|
||||
const arr2<double> &recurse ();
|
||||
};
|
||||
|
||||
/*! Class for calculation of the Wigner matrix at arbitrary angles, using Risbo
|
||||
recursion in a way that can be OpenMP-parallelised. This approach uses more
|
||||
memory and is slightly slower than wigner_d_risbo_scalar. */
|
||||
class wigner_d_risbo_openmp
|
||||
{
|
||||
private:
|
||||
double p,q;
|
||||
arr<double> sqt;
|
||||
arr2<double> d, dd;
|
||||
int n;
|
||||
|
||||
public:
|
||||
wigner_d_risbo_openmp(int lmax, double ang);
|
||||
|
||||
const arr2<double> &recurse ();
|
||||
};
|
||||
|
||||
/*! Class for calculation of the Wigner matrix elements by l-recursion.
|
||||
For details, see Prezeau & Reinecke 2010, http://arxiv.org/pdf/1002.1050 */
|
||||
class wignergen
|
||||
{
|
||||
private:
|
||||
typedef double dbl3[3];
|
||||
|
||||
// members set in the constructor and kept fixed afterwards
|
||||
double fsmall, fbig, eps;
|
||||
int lmax;
|
||||
arr<long double> logsum, lc05, ls05;
|
||||
arr<double> flm1, flm2, cf, costh, xl;
|
||||
arr<bool> thetaflip;
|
||||
|
||||
// members depending on m and m'
|
||||
int m1, m2, am1, am2, mlo, mhi, cosPow, sinPow;
|
||||
long double prefactor;
|
||||
arr<dbl3> fx;
|
||||
bool preMinus;
|
||||
|
||||
// members depending on theta
|
||||
arr<double> result;
|
||||
#ifdef PLANCK_HAVE_SSE2
|
||||
arr_align<v2df,16> result2;
|
||||
#endif
|
||||
|
||||
enum { large_exponent2=90, minscale=-4, maxscale=14 };
|
||||
|
||||
public:
|
||||
/*! Constructs an object that can compute Wigner matrix elements up
|
||||
to a maximum \a l value of \a lmax_, at the colatitudes provided
|
||||
in \a thetas. The generator will be allowed to regard values with
|
||||
absolute magnitudes smaller than \a epsilon as zero; a typical value
|
||||
is 1e-30. */
|
||||
wignergen (int lmax_, const arr<double> &thetas, double epsilon);
|
||||
|
||||
/*! Prepares the object to produce Wigner matrix elements with \a m=m1_
|
||||
and \a m'=m2_ in subsequent calls to calc(). This operation is not cheap
|
||||
so it is recommended to use calc() for many different colatitudes after
|
||||
every call to prepare(), if possible. */
|
||||
void prepare (int m1_, int m2_);
|
||||
|
||||
/*! Computes the Wigner matrix elements for the values of \a m and \a m'
|
||||
set by the preceding call to prepare(), for all \a l up to \a lmax
|
||||
(set in the constructor), and for the \a nth colatitude passed to the
|
||||
constructor. On return, \a firstl contains the index of the first
|
||||
matrix element larger than \a epsilon; all values with smaller indices
|
||||
in the result array are undefined. */
|
||||
const arr<double> &calc (int nth, int &firstl);
|
||||
|
||||
#ifdef PLANCK_HAVE_SSE2
|
||||
const arr_align<v2df,16> &calc (int nth1, int nth2, int &firstl);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
208
external/healpix/cxxsupport/xcomplex.h
vendored
Normal file
208
external/healpix/cxxsupport/xcomplex.h
vendored
Normal file
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
* This file is part of libcxxsupport.
|
||||
*
|
||||
* libcxxsupport is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libcxxsupport is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libcxxsupport; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*! \file xcomplex.h
|
||||
* Class for representing complex numbers, strongly inspired by C++'s
|
||||
* std::complex
|
||||
*
|
||||
* Copyright (C) 2003-2010 Max-Planck-Society
|
||||
* \author Martin Reinecke
|
||||
*/
|
||||
|
||||
#ifndef PLANCK_XCOMPLEX_H
|
||||
#define PLANCK_XCOMPLEX_H
|
||||
|
||||
#include <iostream>
|
||||
#include <complex>
|
||||
|
||||
/*! \defgroup complexgroup Complex number support */
|
||||
/*! \{ */
|
||||
|
||||
/*! A class for representing complex numbers.
|
||||
|
||||
This template is intended as an (under-encapsulated) replacement for
|
||||
the (over-encapsulated) std::complex<>. The goal is to include the
|
||||
whole functionality of std::complex<>, with some additional methods
|
||||
that allow higher performance.
|
||||
|
||||
The (known and intentional) differences between xcomplex<> and
|
||||
std::complex<> are:
|
||||
- the default constructor of xcomplex<> does nothing, in contrast to
|
||||
std::complex<>, which initialises its members to zero.
|
||||
- xcomplex<> implements the methods real() and imag() according
|
||||
to defect report DR387
|
||||
*/
|
||||
template<typename T> class xcomplex
|
||||
{
|
||||
public:
|
||||
T re, /*!< real part */
|
||||
im; /*!< imaginary part */
|
||||
|
||||
/*! Default constructor. \a re and \a im are not initialised. */
|
||||
xcomplex () {}
|
||||
/*! Creates the complex number (\a re_, \a im_). */
|
||||
xcomplex (const T &re_, const T &im_)
|
||||
: re(re_), im(im_) {}
|
||||
/*! Creates the complex number (\a re_, 0). */
|
||||
xcomplex (const T &re_)
|
||||
: re(re_), im(0) {}
|
||||
/*! Creates an xcomplex from a std::complex of identical precision. */
|
||||
xcomplex (const std::complex<T> &orig)
|
||||
: re(orig.real()), im(orig.imag()) {}
|
||||
/*! Creates a complex number as a copy of \a orig. */
|
||||
template<typename U> explicit xcomplex (const xcomplex<U> &orig)
|
||||
: re(T(orig.re)), im(T(orig.im)) {}
|
||||
|
||||
/*! Conversion operator to std::complex<T> */
|
||||
operator std::complex<T> () const
|
||||
{ return std::complex<T>(re,im); }
|
||||
|
||||
/*! Returns the real part as lvalue. */
|
||||
T &real() { return re; }
|
||||
/*! Returns the real part. */
|
||||
const T &real() const { return re; }
|
||||
/*! Returns the imaginary part as lvalue. */
|
||||
T &imag() { return im; }
|
||||
/*! Returns the imaginary part. */
|
||||
const T &imag() const { return im; }
|
||||
|
||||
/*! Sets the number to (\a re_, \a im_). */
|
||||
void Set (const T &re_, const T &im_)
|
||||
{ re = re_; im = im_; }
|
||||
|
||||
/*! Sets the number to \a orig. */
|
||||
xcomplex &operator= (const xcomplex &orig)
|
||||
{ re=orig.re; im=orig.im; return *this; }
|
||||
/*! Sets the number to \a orig. */
|
||||
xcomplex &operator= (const std::complex<T> &orig)
|
||||
{ re=orig.real(); im=orig.imag(); return *this; }
|
||||
/*! Sets the number to (\a orig, 0). */
|
||||
xcomplex &operator= (const T &orig)
|
||||
{ re=orig; im=0; return *this; }
|
||||
/*! Adds \a b to \a *this. */
|
||||
xcomplex &operator+= (const xcomplex &b)
|
||||
{ re+=b.re; im+=b.im; return *this; }
|
||||
/*! Subtracts \a b from \a *this. */
|
||||
xcomplex &operator-= (const xcomplex &b)
|
||||
{ re-=b.re; im-=b.im; return *this; }
|
||||
/*! Multiplies \a *this by \a b. */
|
||||
xcomplex &operator*= (const xcomplex &b)
|
||||
{
|
||||
T tmp=re;
|
||||
re=tmp*b.re-im*b.im; im=tmp*b.im+im*b.re;
|
||||
return *this;
|
||||
}
|
||||
/*! Divides \a *this by \a b. */
|
||||
xcomplex &operator/= (const xcomplex &b)
|
||||
{
|
||||
std::complex<T> tmp=*this;
|
||||
std::complex<T> tmp2=b;
|
||||
tmp /= tmp2;
|
||||
*this=tmp;
|
||||
return *this;
|
||||
}
|
||||
/*! Multiplies \a *this by \a fact. */
|
||||
xcomplex &operator*= (const T &fact)
|
||||
{ re*=fact; im*=fact; return *this; }
|
||||
/*! Divides \a *this by \a div. */
|
||||
xcomplex &operator/= (const T &div)
|
||||
{ re/=div; im/=div; return *this; }
|
||||
/*! Returns \a *this * \a fact. */
|
||||
xcomplex operator* (const T &fact) const
|
||||
{ return xcomplex (re*fact,im*fact); }
|
||||
/*! Returns \a *this * \a b. */
|
||||
xcomplex operator* (const xcomplex &b) const
|
||||
{ return xcomplex (re*b.re-im*b.im, re*b.im+im*b.re); }
|
||||
/*! Returns \a *this / \a b. */
|
||||
xcomplex operator/ (const xcomplex &b) const
|
||||
{ return xcomplex(std::complex<T>(*this)/std::complex<T>(b)); }
|
||||
/*! Returns \a *this / \a div. */
|
||||
xcomplex operator/ (const T &div) const
|
||||
{ return xcomplex (re/div,im/div); }
|
||||
/*! Returns \a *this + \a b. */
|
||||
xcomplex operator+ (const xcomplex &b) const
|
||||
{ return xcomplex (re+b.re, im+b.im); }
|
||||
/*! Returns \a *this - \a b. */
|
||||
xcomplex operator- (const xcomplex &b) const
|
||||
{ return xcomplex (re-b.re, im-b.im); }
|
||||
/*! Returns \a -(*this) */
|
||||
xcomplex operator- () const
|
||||
{ return xcomplex (-re,-im); }
|
||||
|
||||
/*! Flips the signs of both components. */
|
||||
void Negate()
|
||||
{ re=-re; im=-im; }
|
||||
/*! Flips the signs of the imaginary component. */
|
||||
void Conjugate()
|
||||
{ im=-im; }
|
||||
/*! Multiplies the number by exp(i*\a angle) */
|
||||
void Rotate(T angle)
|
||||
{
|
||||
T ca=cos(angle), sa=sin(angle);
|
||||
T tmp=re;
|
||||
re=tmp*ca-im*sa; im=tmp*sa+im*ca;
|
||||
}
|
||||
/*! Returns the complex conjugate of \a *this. */
|
||||
xcomplex conj() const
|
||||
{ return xcomplex (re,-im); }
|
||||
|
||||
/*! Returns the norm of \a *this. */
|
||||
T norm() const
|
||||
{ return re*re + im*im; }
|
||||
};
|
||||
|
||||
/*! Returns the complex conjugate of \a num.
|
||||
\relates xcomplex */
|
||||
template <typename T> inline xcomplex<T> conj (const xcomplex<T> &num)
|
||||
{ return xcomplex<T> (num.re, -num.im); }
|
||||
/*! Returns the norm of \a num.
|
||||
\relates xcomplex */
|
||||
template <typename T> inline T norm (const xcomplex<T> &num)
|
||||
{ return num.re*num.re + num.im*num.im; }
|
||||
/*! Returns the absolute value of \a num.
|
||||
\relates xcomplex */
|
||||
template <typename T> inline T abs (const xcomplex<T> &num)
|
||||
{
|
||||
using namespace std;
|
||||
return abs(complex<T>(num));
|
||||
}
|
||||
/*! Returns \a f1*f2.
|
||||
\relates xcomplex */
|
||||
template <typename T> inline xcomplex<T> operator*
|
||||
(const T &f1, const xcomplex<T> &f2)
|
||||
{ return xcomplex<T> (f1*f2.re, f1*f2.im); }
|
||||
/*! Returns \a f1/f2.
|
||||
\relates xcomplex */
|
||||
template <typename T> inline xcomplex<T> operator/
|
||||
(const T &f1, const xcomplex<T> &f2)
|
||||
{ return xcomplex<T>(f1)/f2; }
|
||||
/*! Writes \a val to \a os.
|
||||
\relates xcomplex */
|
||||
template<typename T>
|
||||
inline std::ostream &operator<< (std::ostream &os, const xcomplex<T> &val)
|
||||
{ os << "(" << val.re << "," << val.im << ")"; return os; }
|
||||
|
||||
/*! \} */
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue