LSST Applications g070148d5b3+33e5256705,g0d53e28543+25c8b88941,g0da5cf3356+2dd1178308,g1081da9e2a+62d12e78cb,g17e5ecfddb+7e422d6136,g1c76d35bf8+ede3a706f7,g295839609d+225697d880,g2e2c1a68ba+cc1f6f037e,g2ffcdf413f+853cd4dcde,g38293774b4+62d12e78cb,g3b44f30a73+d953f1ac34,g48ccf36440+885b902d19,g4b2f1765b6+7dedbde6d2,g5320a0a9f6+0c5d6105b6,g56b687f8c9+ede3a706f7,g5c4744a4d9+ef6ac23297,g5ffd174ac0+0c5d6105b6,g6075d09f38+66af417445,g667d525e37+2ced63db88,g670421136f+2ced63db88,g71f27ac40c+2ced63db88,g774830318a+463cbe8d1f,g7876bc68e5+1d137996f1,g7985c39107+62d12e78cb,g7fdac2220c+0fd8241c05,g96f01af41f+368e6903a7,g9ca82378b8+2ced63db88,g9d27549199+ef6ac23297,gabe93b2c52+e3573e3735,gb065e2a02a+3dfbe639da,gbc3249ced9+0c5d6105b6,gbec6a3398f+0c5d6105b6,gc9534b9d65+35b9f25267,gd01420fc67+0c5d6105b6,geee7ff78d7+a14128c129,gf63283c776+ede3a706f7,gfed783d017+0c5d6105b6,w.2022.47
LSST Data Management Base Package
Loading...
Searching...
No Matches
Namespaces | Classes | Typedefs | Functions | Variables
lsst::sphgeom Namespace Reference

Namespaces

namespace  _healpixPixelization
 
namespace  _yaml
 
namespace  detail
 
namespace  pixelization_abc
 
namespace  python
 
namespace  version
 

Classes

class  Angle
 Angle represents an angle in radians. More...
 
class  AngleInterval
 AngleInterval represents closed intervals of arbitrary angles. More...
 
class  BigInteger
 BigInteger is an arbitrary precision signed integer class. More...
 
class  Box
 Box represents a rectangle in spherical coordinate space that contains its boundary. More...
 
class  Box3d
 Box3d represents a box in ℝ³. More...
 
class  Chunker
 Chunker subdivides the unit sphere into longitude-latitude boxes. More...
 
class  Circle
 Circle is a circular region on the unit sphere that contains its boundary. More...
 
class  CompoundRegion
 CompoundRegion is an intermediate base class for spherical regions that are comprised of a point-set operation on other nested regions. More...
 
class  ConvexPolygon
 ConvexPolygon is a closed convex polygon on the unit sphere. More...
 
class  Ellipse
 Ellipse is an elliptical region on the sphere. More...
 
class  HtmPixelization
 HtmPixelization provides HTM indexing of points and regions. More...
 
class  IntersectionRegion
 IntersectionRegion is a lazy point-set inersection of its operands. More...
 
class  Interval
 Interval represents a closed interval of the real numbers by its upper and lower bounds. More...
 
class  Interval1d
 Interval1d represents closed intervals of ℝ. More...
 
class  LonLat
 LonLat represents a spherical coordinate (longitude/latitude angle) pair. More...
 
class  Matrix3d
 A 3x3 matrix with real entries stored in double precision. More...
 
class  Mq3cPixelization
 Mq3cPixelization provides modified Q3C indexing of points and regions. More...
 
class  NormalizedAngle
 NormalizedAngle is an angle that lies in the range [0, 2π), with one exception - a NormalizedAngle can be NaN. More...
 
class  NormalizedAngleInterval
 NormalizedAngleInterval represents closed intervals of normalized angles, i.e. More...
 
class  Pixelization
 A Pixelization (or partitioning) of the sphere is a mapping between points on the sphere and a set of pixels (a.k.a. More...
 
class  Q3cPixelization
 Q3cPixelization provides Q3C indexing of points and regions. More...
 
class  RangeSet
 A RangeSet is a set of unsigned 64 bit integers. More...
 
class  Region
 Region is a minimal interface for 2-dimensional regions on the unit sphere. More...
 
struct  SubChunks
 SubChunks represents a set of sub-chunks of a particular chunk. More...
 
class  UnionRegion
 UnionRegion is a lazy point-set union of its operands. More...
 
class  UnitVector3d
 UnitVector3d is a unit vector in ℝ³ with components stored in double precision. More...
 
class  Vector3d
 Vector3d is a vector in ℝ³ with components stored in double precision. More...
 

Typedefs

using Relationship = std::bitset< 3 >
 Relationship describes how two sets are related. More...
 

Functions

Angle operator* (double a, Angle const &b)
 
std::ostreamoperator<< (std::ostream &, Angle const &)
 
double sin (Angle const &a)
 
double cos (Angle const &a)
 
double tan (Angle const &a)
 
Angle abs (Angle const &a)
 
std::ostreamoperator<< (std::ostream &, AngleInterval const &)
 
std::ostreamoperator<< (std::ostream &, Box const &)
 
std::ostreamoperator<< (std::ostream &, Box3d const &)
 
std::ostreamoperator<< (std::ostream &, Circle const &)
 
void encodeDouble (double item, std::vector< uint8_t > &buffer)
 encodeDouble appends an IEEE double in little-endian byte order to the end of buffer. More...
 
double decodeDouble (uint8_t const *buffer)
 decodeDouble extracts an IEEE double from the 8 byte little-endian byte sequence in buffer. More...
 
void encodeU64 (std::uint64_t item, std::vector< uint8_t > &buffer)
 encodeU64 appends an uint64 in little-endian byte order to the end of buffer. More...
 
std::uint64_t decodeU64 (uint8_t const *buffer)
 decodeU64 extracts an uint64 from the 8 byte little-endian byte sequence in buffer. More...
 
std::ostreamoperator<< (std::ostream &, ConvexPolygon const &)
 
uint64_t mortonIndex (uint32_t x, uint32_t y)
 mortonIndex interleaves the bits of x and y. More...
 
std::tuple< uint32_t, uint32_t > mortonIndexInverse (uint64_t z)
 mortonIndexInverse separates the even and odd bits of z. More...
 
uint64_t mortonToHilbert (uint64_t z, int m)
 mortonToHilbert converts the 2m-bit Morton index z to the corresponding Hilbert index. More...
 
uint64_t hilbertToMorton (uint64_t h, int m)
 hilbertToMorton converts the 2m-bit Hilbert index h to the corresponding Morton index. More...
 
uint64_t hilbertIndex (uint32_t x, uint32_t y, int m)
 hilbertIndex returns the index of (x, y) in a 2-D Hilbert curve. More...
 
std::tuple< uint32_t, uint32_t > hilbertIndexInverse (uint64_t h, int m)
 hilbertIndexInverse returns the point (x, y) with Hilbert index h, where x and y are m bit integers. More...
 
std::ostreamoperator<< (std::ostream &, Ellipse const &)
 
std::ostreamoperator<< (std::ostream &, Interval1d const &)
 
std::ostreamoperator<< (std::ostream &, LonLat const &)
 
std::ostreamoperator<< (std::ostream &, Matrix3d const &)
 
NormalizedAngle const & abs (NormalizedAngle const &a)
 
std::ostreamoperator<< (std::ostream &, NormalizedAngleInterval const &)
 
int orientationExact (Vector3d const &a, Vector3d const &b, Vector3d const &c)
 orientationExact computes and returns the orientations of 3 vectors a, b and c, which need not be normalized but are assumed to have finite components. More...
 
int orientation (UnitVector3d const &a, UnitVector3d const &b, UnitVector3d const &c)
 orientation computes and returns the orientations of 3 unit vectors a, b and c. More...
 
int orientationX (UnitVector3d const &b, UnitVector3d const &c)
 orientationX(b, c) is equivalent to orientation(UnitVector3d::X(), b, c). More...
 
int orientationY (UnitVector3d const &b, UnitVector3d const &c)
 orientationY(b, c) is equivalent to orientation(UnitVector3d::Y(), b, c). More...
 
int orientationZ (UnitVector3d const &b, UnitVector3d const &c)
 orientationZ(b, c) is equivalent to orientation(UnitVector3d::Z(), b, c). More...
 
template<typename Pybind11Class >
void defineClass (Pybind11Class &cls)
 
void swap (RangeSet &a, RangeSet &b)
 
std::ostreamoperator<< (std::ostream &, RangeSet const &)
 
Relationship invert (Relationship r)
 Given the relationship between two sets A and B (i.e. More...
 
std::ostreamoperator<< (std::ostream &, UnitVector3d const &)
 
double getMinSquaredChordLength (Vector3d const &v, Vector3d const &a, Vector3d const &b, Vector3d const &n)
 Let p be the unit vector closest to v that lies on the plane with normal n in the direction of the cross product of a and b. More...
 
double getMaxSquaredChordLength (Vector3d const &v, Vector3d const &a, Vector3d const &b, Vector3d const &n)
 Let p be the unit vector furthest from v that lies on the plane with normal n in the direction of the cross product of a and b. More...
 
Angle getMinAngleToCircle (Angle x, Angle c)
 getMinAngleToCircle returns the minimum angular separation between a point at latitude x and the points on the circle of constant latitude c. More...
 
Angle getMaxAngleToCircle (Angle x, Angle c)
 getMaxAngleToCircle returns the maximum angular separation between a point at latitude x and the points on the circle of constant latitude c. More...
 
Vector3d getWeightedCentroid (UnitVector3d const &v0, UnitVector3d const &v1, UnitVector3d const &v2)
 getWeightedCentroid returns the center of mass of the given spherical triangle (assuming a uniform mass distribution over the triangle surface), weighted by the triangle area. More...
 
Vector3d operator* (double s, Vector3d const &v)
 
std::ostreamoperator<< (std::ostream &, Vector3d const &)
 
template<>
void defineClass (py::class_< Angle > &cls)
 
template<>
void defineClass (py::class_< AngleInterval, std::shared_ptr< AngleInterval > > &cls)
 
template<>
void defineClass (py::class_< Box, std::unique_ptr< Box >, Region > &cls)
 
template<>
void defineClass (py::class_< Box3d, std::shared_ptr< Box3d > > &cls)
 
template<>
void defineClass (py::class_< Chunker, std::shared_ptr< Chunker > > &cls)
 
template<>
void defineClass (py::class_< Circle, std::unique_ptr< Circle >, Region > &cls)
 
template<>
void defineClass (py::class_< CompoundRegion, std::unique_ptr< CompoundRegion >, Region > &cls)
 
template<>
void defineClass (py::class_< UnionRegion, std::unique_ptr< UnionRegion >, CompoundRegion > &cls)
 
template<>
void defineClass (py::class_< IntersectionRegion, std::unique_ptr< IntersectionRegion >, CompoundRegion > &cls)
 
template<>
void defineClass (py::class_< ConvexPolygon, std::unique_ptr< ConvexPolygon >, Region > &cls)
 
void defineCurve (py::module &mod)
 
template<>
void defineClass (py::class_< Ellipse, std::unique_ptr< Ellipse >, Region > &cls)
 
template<>
void defineClass (py::class_< HtmPixelization, Pixelization > &cls)
 
template<>
void defineClass (py::class_< Interval1d, std::shared_ptr< Interval1d > > &cls)
 
template<>
void defineClass (py::class_< LonLat, std::shared_ptr< LonLat > > &cls)
 
template<>
void defineClass (py::class_< Matrix3d, std::shared_ptr< Matrix3d > > &cls)
 
template<>
void defineClass (py::class_< Mq3cPixelization, Pixelization > &cls)
 
template<>
void defineClass (py::class_< NormalizedAngle > &cls)
 
template<>
void defineClass (py::class_< NormalizedAngleInterval, std::shared_ptr< NormalizedAngleInterval > > &cls)
 
void defineOrientation (py::module &mod)
 
template<>
void defineClass (py::class_< Pixelization > &cls)
 
template<>
void defineClass (py::class_< Q3cPixelization, Pixelization > &cls)
 
template<>
void defineClass (py::class_< RangeSet, std::shared_ptr< RangeSet > > &cls)
 
template<>
void defineClass (py::class_< Region, std::unique_ptr< Region > > &cls)
 
void defineRelationship (py::module &mod)
 
void defineUtils (py::module &)
 
template<>
void defineClass (py::class_< UnitVector3d, std::shared_ptr< UnitVector3d > > &cls)
 
template<>
void defineClass (py::class_< Vector3d, std::shared_ptr< Vector3d > > &cls)
 
uint8_t log2 (uint64_t x)
 
uint8_t log2 (uint32_t x)
 

Variables

constexpr double PI = 3.1415926535897932384626433832795
 
constexpr double ONE_OVER_PI = 0.318309886183790671537767526745
 
constexpr double RAD_PER_DEG = 0.0174532925199432957692369076849
 
constexpr double DEG_PER_RAD = 57.2957795130823208767981548141
 
constexpr double MAX_ASIN_ERROR = 1.5e-8
 
constexpr double MAX_SQUARED_CHORD_LENGTH_ERROR = 2.5e-15
 
constexpr double EPSILON = 1.1102230246251565e-16
 

Typedef Documentation

◆ Relationship

Relationship describes how two sets are related.

Definition at line 35 of file Relationship.h.

Function Documentation

◆ abs() [1/2]

Angle lsst::sphgeom::abs ( Angle const &  a)
inline

Definition at line 106 of file Angle.h.

106{ return Angle(std::fabs(a.asRadians())); }
table::Key< int > a
Angle represents an angle in radians.
Definition: Angle.h:43
T fabs(T... args)

◆ abs() [2/2]

NormalizedAngle const & lsst::sphgeom::abs ( NormalizedAngle const &  a)
inline

Definition at line 152 of file NormalizedAngle.h.

152{ return a; }

◆ cos()

double lsst::sphgeom::cos ( Angle const &  a)
inline

Definition at line 103 of file Angle.h.

103{ return std::cos(a.asRadians()); }
T cos(T... args)

◆ decodeDouble()

double lsst::sphgeom::decodeDouble ( uint8_t const *  buffer)
inline

decodeDouble extracts an IEEE double from the 8 byte little-endian byte sequence in buffer.

Definition at line 69 of file codec.h.

69 {
70#ifdef OPTIMIZED_LITTLE_ENDIAN
71 return *reinterpret_cast<double const *>(buffer);
72#else
73 union { uint64_t u; double d; };
74 u = static_cast<uint64_t>(buffer[0]) +
75 (static_cast<uint64_t>(buffer[1]) << 8) +
76 (static_cast<uint64_t>(buffer[2]) << 16) +
77 (static_cast<uint64_t>(buffer[3]) << 24) +
78 (static_cast<uint64_t>(buffer[4]) << 32) +
79 (static_cast<uint64_t>(buffer[5]) << 40) +
80 (static_cast<uint64_t>(buffer[6]) << 48) +
81 (static_cast<uint64_t>(buffer[7]) << 56);
82 return d;
83#endif
84}

◆ decodeU64()

std::uint64_t lsst::sphgeom::decodeU64 ( uint8_t const *  buffer)
inline

decodeU64 extracts an uint64 from the 8 byte little-endian byte sequence in buffer.

Definition at line 108 of file codec.h.

108 {
109#ifdef OPTIMIZED_LITTLE_ENDIAN
110 return *reinterpret_cast<uint64_t const *>(buffer);
111#else
112 std::uint64_t u = static_cast<uint64_t>(buffer[0]) +
113 (static_cast<uint64_t>(buffer[1]) << 8) +
114 (static_cast<uint64_t>(buffer[2]) << 16) +
115 (static_cast<uint64_t>(buffer[3]) << 24) +
116 (static_cast<uint64_t>(buffer[4]) << 32) +
117 (static_cast<uint64_t>(buffer[5]) << 40) +
118 (static_cast<uint64_t>(buffer[6]) << 48) +
119 (static_cast<uint64_t>(buffer[7]) << 56);
120 return u;
121#endif
122}

◆ defineClass() [1/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< Angle > &  cls)

Definition at line 36 of file _angle.cc.

36 {
37 cls.def_static("nan", &Angle::nan);
38 cls.def_static("fromDegrees", &Angle::fromDegrees);
39 cls.def_static("fromRadians", &Angle::fromRadians);
40
41 cls.def(py::init<>());
42 cls.def(py::init<double>(), "radians"_a);
43 cls.def(py::init<Angle>(), "angle"_a);
44 // Construct an Angle from a NormalizedAngle, enabling implicit
45 // conversion from NormalizedAngle to Angle in python via
46 // py::implicitly_convertible
47 cls.def(py::init(
48 [](NormalizedAngle &a) {
49 return new Angle(a.asRadians());
50 }),
51 "normalizedAngle"_a);
52
53 cls.def("__eq__", &Angle::operator==, py::is_operator());
54 cls.def("__ne__", &Angle::operator!=, py::is_operator());
55 cls.def("__lt__", &Angle::operator<, py::is_operator());
56 cls.def("__gt__", &Angle::operator>, py::is_operator());
57 cls.def("__le__", &Angle::operator<=, py::is_operator());
58 cls.def("__ge__", &Angle::operator>=, py::is_operator());
59
60 cls.def("__neg__", (Angle(Angle::*)() const) & Angle::operator-);
61 cls.def("__add__", &Angle::operator+, py::is_operator());
62 cls.def("__sub__",
63 (Angle(Angle::*)(Angle const &) const) & Angle::operator-,
64 py::is_operator());
65 cls.def("__mul__", &Angle::operator*, py::is_operator());
66 cls.def("__rmul__", &Angle::operator*, py::is_operator());
67 cls.def("__truediv__", (Angle(Angle::*)(double) const) & Angle::operator/,
68 py::is_operator());
69 cls.def("__truediv__",
70 (double (Angle::*)(Angle const &) const) & Angle::operator/,
71 py::is_operator());
72
73 cls.def("__iadd__", &Angle::operator+=);
74 cls.def("__isub__", &Angle::operator-=);
75 cls.def("__imul__", &Angle::operator*=);
76 cls.def("__itruediv__", &Angle::operator/=);
77
78 cls.def("asDegrees", &Angle::asDegrees);
79 cls.def("asRadians", &Angle::asRadians);
80 cls.def("isNormalized", &Angle::isNormalized);
81 cls.def("isNan", &Angle::isNan);
82
83 cls.def("__str__", [](Angle const &self) {
84 return py::str("{!s}").format(self.asRadians());
85 });
86 cls.def("__repr__", [](Angle const &self) {
87 return py::str("Angle({!r})").format(self.asRadians());
88 });
89
90 cls.def("__reduce__", [cls](Angle const &self) {
91 return py::make_tuple(cls, py::make_tuple(self.asRadians()));
92 });
93}
NormalizedAngle is an angle that lies in the range [0, 2π), with one exception - a NormalizedAngle ca...

◆ defineClass() [2/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< AngleInterval, std::shared_ptr< AngleInterval > > &  cls)

Definition at line 36 of file _angleInterval.cc.

37 {
38 python::defineInterval<decltype(cls), AngleInterval, Angle>(cls);
39
40 cls.def_static("fromDegrees", &AngleInterval::fromDegrees, "x"_a, "y"_a);
41 cls.def_static("fromRadians", &AngleInterval::fromRadians, "x"_a, "y"_a);
42 cls.def_static("empty", &AngleInterval::empty);
43 cls.def_static("full", &AngleInterval::full);
44
45 cls.def(py::init<>());
46 cls.def(py::init<Angle>(), "x"_a);
47 cls.def(py::init<Angle, Angle>(), "x"_a, "y"_a);
48 cls.def(py::init<AngleInterval const &>(), "interval"_a);
49
50 cls.def("__str__", [](AngleInterval const &self) {
51 return py::str("[{!s}, {!s}]")
52 .format(self.getA().asRadians(), self.getB().asRadians());
53 });
54 cls.def("__repr__", [](AngleInterval const &self) {
55 return py::str("AngleInterval.fromRadians({!r}, {!r})")
56 .format(self.getA().asRadians(), self.getB().asRadians());
57 });
58}
double asRadians() const
asRadians returns the value of this angle in units of radians.
Definition: Angle.h:85
AngleInterval represents closed intervals of arbitrary angles.
Definition: AngleInterval.h:40
Scalar getA() const
getA returns the lower endpoint of this interval.
Definition: Interval.h:76
Scalar getB() const
getB returns the upper endpoint of this interval.
Definition: Interval.h:80

◆ defineClass() [3/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< Box, std::unique_ptr< Box >, Region > &  cls)

Definition at line 48 of file _box.cc.

48 {
49 cls.attr("TYPE_CODE") = py::int_(Box::TYPE_CODE);
50
51 cls.def_static("fromDegrees", &Box::fromDegrees, "lon1"_a, "lat1"_a,
52 "lon2"_a, "lat2"_a);
53 cls.def_static("fromRadians", &Box::fromRadians, "lon1"_a, "lat1"_a,
54 "lon2"_a, "lat2"_a);
55 cls.def_static("empty", &Box::empty);
56 cls.def_static("full", &Box::full);
57 cls.def_static("halfWidthForCircle", &Box::halfWidthForCircle, "radius"_a,
58 "lat"_a);
59 cls.def_static("allLongitudes", &Box::allLongitudes);
60 cls.def_static("allLatitudes", &Box::allLatitudes);
61
62 cls.def(py::init<>());
63 cls.def(py::init<LonLat const &>(), "point"_a);
64 cls.def(py::init<LonLat const &, LonLat const &>(), "point1"_a, "point2"_a);
65 cls.def(py::init<LonLat const &, Angle, Angle>(), "center"_a, "width"_a,
66 "height"_a);
67 cls.def(py::init<NormalizedAngleInterval const &, AngleInterval const &>(),
68 "lon"_a, "lat"_a);
69 cls.def(py::init<Box const &>(), "box"_a);
70
71 cls.def("__eq__", (bool (Box::*)(Box const &) const) & Box::operator==,
72 py::is_operator());
73 cls.def("__eq__", (bool (Box::*)(LonLat const &) const) & Box::operator==,
74 py::is_operator());
75 cls.def("__ne__", (bool (Box::*)(Box const &) const) & Box::operator!=,
76 py::is_operator());
77 cls.def("__ne__", (bool (Box::*)(LonLat const &) const) & Box::operator!=,
78 py::is_operator());
79 cls.def("__contains__",
80 (bool (Box::*)(LonLat const &) const) & Box::contains,
81 py::is_operator());
82 cls.def("__contains__", (bool (Box::*)(Box const &) const) & Box::contains,
83 py::is_operator());
84 // Rewrap this base class method since there are overloads in this subclass
85 cls.def("__contains__",
86 (bool (Box::*)(UnitVector3d const &) const) & Box::contains,
87 py::is_operator());
88
89 cls.def("getLon", &Box::getLon);
90 cls.def("getLat", &Box::getLat);
91 cls.def("isEmpty", &Box::isEmpty);
92 cls.def("isFull", &Box::isFull);
93 cls.def("getCenter", &Box::getCenter);
94 cls.def("getWidth", &Box::getWidth);
95 cls.def("getHeight", &Box::getHeight);
96 cls.def("contains", (bool (Box::*)(LonLat const &) const) & Box::contains);
97 cls.def("contains", (bool (Box::*)(Box const &) const) & Box::contains);
98 // Rewrap these base class methods since there are overloads in this subclass
99 cls.def("contains",
100 (bool (Box::*)(UnitVector3d const &) const) & Box::contains);
101 cls.def("contains", py::vectorize((bool (Box::*)(double, double, double) const)&Box::contains),
102 "x"_a, "y"_a, "z"_a);
103 cls.def("contains", py::vectorize((bool (Box::*)(double, double) const)&Box::contains),
104 "lon"_a, "lat"_a);
105 cls.def("isDisjointFrom",
106 (bool (Box::*)(LonLat const &) const) & Box::isDisjointFrom);
107 cls.def("isDisjointFrom",
108 (bool (Box::*)(Box const &) const) & Box::isDisjointFrom);
109 cls.def("intersects",
110 (bool (Box::*)(LonLat const &) const) & Box::intersects);
111 cls.def("intersects", (bool (Box::*)(Box const &) const) & Box::intersects);
112 cls.def("isWithin", (bool (Box::*)(LonLat const &) const) & Box::isWithin);
113 cls.def("isWithin", (bool (Box::*)(Box const &) const) & Box::isWithin);
114 cls.def("clipTo", (Box & (Box::*)(LonLat const &)) & Box::clipTo);
115 cls.def("clipTo", (Box & (Box::*)(Box const &)) & Box::clipTo);
116 cls.def("clippedTo", (Box(Box::*)(LonLat const &) const) & Box::clippedTo);
117 cls.def("clippedTo", (Box(Box::*)(Box const &) const) & Box::clippedTo);
118 cls.def("expandTo", (Box & (Box::*)(LonLat const &)) & Box::expandTo);
119 cls.def("expandTo", (Box & (Box::*)(Box const &)) & Box::expandTo);
120 cls.def("expandedTo",
121 (Box(Box::*)(LonLat const &) const) & Box::expandedTo);
122 cls.def("expandedTo", (Box(Box::*)(Box const &) const) & Box::expandedTo);
123 cls.def("dilateBy", (Box & (Box::*)(Angle)) & Box::dilateBy, "angle"_a);
124 cls.def("dilateBy", (Box & (Box::*)(Angle, Angle)) & Box::dilateBy,
125 "width"_a, "height"_a);
126 cls.def("dilatedBy", (Box(Box::*)(Angle) const) & Box::dilatedBy,
127 "angle"_a);
128 cls.def("dilatedBy", (Box(Box::*)(Angle, Angle) const) & Box::dilatedBy,
129 "width"_a, "height"_a);
130 cls.def("erodeBy", (Box & (Box::*)(Angle)) & Box::erodeBy, "angle"_a);
131 cls.def("erodeBy", (Box & (Box::*)(Angle, Angle)) & Box::erodeBy, "width"_a,
132 "height"_a);
133 cls.def("erodedBy", (Box(Box::*)(Angle) const) & Box::erodedBy, "angle"_a);
134 cls.def("erodedBy", (Box(Box::*)(Angle, Angle) const) & Box::erodedBy,
135 "width"_a, "height"_a);
136 cls.def("getArea", &Box::getArea);
137 cls.def("relate",
138 (Relationship(Box::*)(LonLat const &) const) & Box::relate,
139 "point"_a);
140 // Rewrap this base class method since there are overloads in this subclass
141 cls.def("relate",
142 (Relationship(Box::*)(Region const &) const) & Box::relate,
143 "region"_a);
144
145 // Note that the Region interface has already been wrapped.
146
147 cls.def("__str__", [](Box const &self) {
148 return py::str("Box({!s}, {!s})").format(self.getLon(), self.getLat());
149 });
150 cls.def("__repr__", [](Box const &self) {
151 return py::str("Box({!r}, {!r})").format(self.getLon(), self.getLat());
152 });
153 cls.def(py::pickle(&python::encode, &python::decode<Box>));
154}
Box represents a rectangle in spherical coordinate space that contains its boundary.
Definition: Box.h:54
AngleInterval const & getLat() const
getLat returns the latitude interval of this box.
Definition: Box.h:148
NormalizedAngleInterval const & getLon() const
getLon returns the longitude interval of this box.
Definition: Box.h:145
LonLat represents a spherical coordinate (longitude/latitude angle) pair.
Definition: LonLat.h:48
Region is a minimal interface for 2-dimensional regions on the unit sphere.
Definition: Region.h:79
UnitVector3d is a unit vector in ℝ³ with components stored in double precision.
Definition: UnitVector3d.h:55

◆ defineClass() [4/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< Box3d, std::shared_ptr< Box3d > > &  cls)

Definition at line 38 of file _box3d.cc.

38 {
39 cls.def_static("empty", &Box3d::empty);
40 cls.def_static("full", &Box3d::full);
41 cls.def_static("aroundUnitSphere", &Box3d::aroundUnitSphere);
42
43 cls.def(py::init<>());
44 cls.def(py::init<Vector3d const &>(), "vector"_a);
45 cls.def(py::init<Vector3d const &, Vector3d const &>(), "vector1"_a,
46 "vector2"_a);
47 cls.def(py::init<Vector3d const &, double, double, double>(), "center"_a,
48 "halfWidth"_a, "halfHeight"_a, "halfDepth"_a);
49 cls.def(py::init<Interval1d const &, Interval1d const &,
50 Interval1d const &>(),
51 "x"_a, "y"_a, "z"_a);
52 cls.def(py::init<Box3d const &>(), "box3d"_a);
53
54 cls.def("__eq__",
55 (bool (Box3d::*)(Box3d const &) const) & Box3d::operator==,
56 py::is_operator());
57 cls.def("__eq__",
58 (bool (Box3d::*)(Vector3d const &) const) & Box3d::operator==,
59 py::is_operator());
60 cls.def("__ne__",
61 (bool (Box3d::*)(Box3d const &) const) & Box3d::operator!=,
62 py::is_operator());
63 cls.def("__ne__",
64 (bool (Box3d::*)(Vector3d const &) const) & Box3d::operator!=,
65 py::is_operator());
66 cls.def("__contains__",
67 (bool (Box3d::*)(Vector3d const &) const) & Box3d::contains,
68 py::is_operator());
69 cls.def("__contains__",
70 (bool (Box3d::*)(Box3d const &) const) & Box3d::contains,
71 py::is_operator());
72 cls.def("__len__", [](Box3d const &self) { return py::int_(3); });
73 cls.def("__getitem__", [](Box3d const &self, py::int_ row) {
74 return self(static_cast<int>(python::convertIndex(3, row)));
75 });
76
77 cls.def("x", &Box3d::x);
78 cls.def("y", &Box3d::y);
79 cls.def("z", &Box3d::z);
80 cls.def("isEmpty", &Box3d::isEmpty);
81 cls.def("isFull", &Box3d::isFull);
82 cls.def("getCenter", &Box3d::getCenter);
83 cls.def("getWidth", &Box3d::getWidth);
84 cls.def("getHeight", &Box3d::getHeight);
85 cls.def("getDepth", &Box3d::getDepth);
86
87 cls.def("contains",
88 (bool (Box3d::*)(Vector3d const &) const) & Box3d::contains);
89 cls.def("contains",
90 (bool (Box3d::*)(Box3d const &) const) & Box3d::contains);
91 cls.def("contains", py::vectorize((bool (Box3d::*)(double, double, double) const)&Box3d::contains),
92 "x"_a, "y"_a, "z"_a);
93 cls.def("isDisjointFrom",
94 (bool (Box3d::*)(Vector3d const &) const) & Box3d::isDisjointFrom);
95 cls.def("isDisjointFrom",
96 (bool (Box3d::*)(Box3d const &) const) & Box3d::isDisjointFrom);
97 cls.def("intersects",
98 (bool (Box3d::*)(Vector3d const &) const) & Box3d::intersects);
99 cls.def("intersects",
100 (bool (Box3d::*)(Box3d const &) const) & Box3d::intersects);
101 cls.def("isWithin",
102 (bool (Box3d::*)(Vector3d const &) const) & Box3d::isWithin);
103 cls.def("isWithin",
104 (bool (Box3d::*)(Box3d const &) const) & Box3d::isWithin);
105
106 cls.def("clipTo", (Box3d & (Box3d::*)(Vector3d const &)) & Box3d::clipTo);
107 cls.def("clipTo", (Box3d & (Box3d::*)(Box3d const &)) & Box3d::clipTo);
108 cls.def("clippedTo",
109 (Box3d(Box3d::*)(Vector3d const &) const) & Box3d::clippedTo);
110 cls.def("clippedTo",
111 (Box3d(Box3d::*)(Box3d const &) const) & Box3d::clippedTo);
112 cls.def("expandTo",
113 (Box3d & (Box3d::*)(Vector3d const &)) & Box3d::expandTo);
114 cls.def("expandTo", (Box3d & (Box3d::*)(Box3d const &)) & Box3d::expandTo);
115 cls.def("expandedTo",
116 (Box3d(Box3d::*)(Vector3d const &) const) & Box3d::expandedTo);
117 cls.def("expandedTo",
118 (Box3d(Box3d::*)(Box3d const &) const) & Box3d::expandedTo);
119
120 cls.def("dilateBy", (Box3d & (Box3d::*)(double)) & Box3d::dilateBy,
121 "radius"_a);
122 cls.def("dilateBy",
123 (Box3d & (Box3d::*)(double, double, double)) & Box3d::dilateBy,
124 "width"_a, "height"_a, "depth"_a);
125 cls.def("dilatedBy", (Box3d(Box3d::*)(double) const) & Box3d::dilatedBy,
126 "radius"_a);
127 cls.def("dilatedBy",
128 (Box3d(Box3d::*)(double, double, double) const) & Box3d::dilatedBy,
129 "width"_a, "height"_a, "depth"_a);
130 cls.def("erodeBy", (Box3d & (Box3d::*)(double)) & Box3d::erodeBy,
131 "radius"_a);
132 cls.def("erodeBy",
133 (Box3d & (Box3d::*)(double, double, double)) & Box3d::erodeBy,
134 "width"_a, "height"_a, "depth"_a);
135 cls.def("erodedBy", (Box3d(Box3d::*)(double) const) & Box3d::erodedBy,
136 "radius"_a);
137 cls.def("erodedBy",
138 (Box3d(Box3d::*)(double, double, double) const) & Box3d::erodedBy,
139 "width"_a, "height"_a, "depth"_a);
140
141 cls.def("relate",
142 (Relationship(Box3d::*)(Vector3d const &) const) & Box3d::relate);
143 cls.def("relate",
144 (Relationship(Box3d::*)(Box3d const &) const) & Box3d::relate);
145
146 cls.def("__str__", [](Box3d const &self) {
147 return py::str("[{!s},\n"
148 " {!s},\n"
149 " {!s}]")
150 .format(self.x(), self.y(), self.z());
151 });
152 cls.def("__repr__", [](Box3d const &self) {
153 return py::str("Box3d({!r},\n"
154 " {!r},\n"
155 " {!r})")
156 .format(self.x(), self.y(), self.z());
157 });
158 cls.def("__reduce__", [cls](Box3d const &self) {
159 return py::make_tuple(cls,
160 py::make_tuple(self.x(), self.y(), self.z()));
161 });
162}
Box3d represents a box in ℝ³.
Definition: Box3d.h:42
Interval1d represents closed intervals of ℝ.
Definition: Interval1d.h:40
Vector3d is a vector in ℝ³ with components stored in double precision.
Definition: Vector3d.h:44
int row
Definition: CR.cc:145

◆ defineClass() [5/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< Chunker, std::shared_ptr< Chunker > > &  cls)

Definition at line 43 of file _chunker.cc.

43 {
44 cls.def(py::init<int32_t, int32_t>(), "numStripes"_a,
45 "numSubStripesPerStripe"_a);
46
47 cls.def("__eq__", &Chunker::operator==, py::is_operator());
48 cls.def("__ne__", &Chunker::operator!=, py::is_operator());
49
50 cls.def_property_readonly("numStripes", &Chunker::getNumStripes);
51 cls.def_property_readonly("numSubStripesPerStripe",
52 &Chunker::getNumSubStripesPerStripe);
53
54 cls.def("getChunksIntersecting", &Chunker::getChunksIntersecting,
55 "region"_a);
56 cls.def("getSubChunksIntersecting",
57 [](Chunker const &self, Region const &region) {
58 py::list results;
59 for (auto const &sc : self.getSubChunksIntersecting(region)) {
60 results.append(py::make_tuple(sc.chunkId, sc.subChunkIds));
61 }
62 return results;
63 },
64 "region"_a);
65 cls.def("getAllChunks", &Chunker::getAllChunks);
66 cls.def("getAllSubChunks", &Chunker::getAllSubChunks, "chunkId"_a);
67
68 cls.def("getChunkBoundingBox", &Chunker::getChunkBoundingBox, "stripe"_a, "chunk"_a);
69 cls.def("getSubChunkBoundingBox", &Chunker::getSubChunkBoundingBox, "subStripe"_a, "subChunk"_a);
70
71 cls.def("getStripe", &Chunker::getStripe, "chunkId"_a);
72 cls.def("getChunk", &Chunker::getChunk, "chunkId"_a, "stripe"_a);
73
74
75 cls.def("__str__", &toString);
76 cls.def("__repr__", &toString);
77
78 cls.def("__reduce__", [cls](Chunker const &self) {
79 return py::make_tuple(cls,
80 py::make_tuple(self.getNumStripes(),
81 self.getNumSubStripesPerStripe()));
82 });
83}
Chunker subdivides the unit sphere into longitude-latitude boxes.
Definition: Chunker.h:66
std::vector< SubChunks > getSubChunksIntersecting(Region const &r) const
getSubChunksIntersecting returns all the sub-chunks that potentially intersect the given region.
Definition: Chunker.cc:148

◆ defineClass() [6/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< Circle, std::unique_ptr< Circle >, Region > &  cls)

Definition at line 44 of file _circle.cc.

44 {
45 cls.attr("TYPE_CODE") = py::int_(Circle::TYPE_CODE);
46
47 cls.def_static("empty", &Circle::empty);
48 cls.def_static("full", &Circle::full);
49 cls.def_static("squaredChordLengthFor", &Circle::squaredChordLengthFor,
50 "openingAngle"_a);
51 cls.def_static("openingAngleFor", &Circle::openingAngleFor,
52 "squaredChordLength"_a);
53
54 cls.def(py::init<>());
55 cls.def(py::init<UnitVector3d const &>(), "center"_a);
56 cls.def(py::init<UnitVector3d const &, Angle>(), "center"_a, "angle"_a);
57 cls.def(py::init<UnitVector3d const &, double>(), "center"_a,
58 "squaredChordLength"_a);
59 cls.def(py::init<Circle const &>(), "circle"_a);
60
61 cls.def("__eq__", &Circle::operator==, py::is_operator());
62 cls.def("__ne__", &Circle::operator!=, py::is_operator());
63 cls.def("__contains__",
64 (bool (Circle::*)(Circle const &) const) & Circle::contains,
65 py::is_operator());
66 // Rewrap this base class method since there are overloads in this subclass
67 cls.def("__contains__",
68 (bool (Circle::*)(UnitVector3d const &) const) & Circle::contains,
69 py::is_operator());
70
71 cls.def("isEmpty", &Circle::isEmpty);
72 cls.def("isFull", &Circle::isFull);
73 cls.def("getCenter", &Circle::getCenter);
74 cls.def("getSquaredChordLength", &Circle::getSquaredChordLength);
75 cls.def("getOpeningAngle", &Circle::getOpeningAngle);
76 cls.def("contains",
77 (bool (Circle::*)(Circle const &) const) & Circle::contains);
78 // Rewrap these base class methods since there are overloads in this subclass
79 cls.def("contains",
80 (bool (Circle::*)(UnitVector3d const &) const) & Circle::contains);
81 cls.def("contains", py::vectorize((bool (Circle::*)(double, double, double) const)&Circle::contains),
82 "x"_a, "y"_a, "z"_a);
83 cls.def("contains", py::vectorize((bool (Circle::*)(double, double) const)&Circle::contains),
84 "lon"_a, "lat"_a);
85
86 cls.def("isDisjointFrom",
87 (bool (Circle::*)(UnitVector3d const &) const) &
88 Circle::isDisjointFrom);
89 cls.def("isDisjointFrom",
90 (bool (Circle::*)(Circle const &) const) & Circle::isDisjointFrom);
91 cls.def("intersects",
92 (bool (Circle::*)(UnitVector3d const &) const) &
93 Circle::intersects);
94 cls.def("intersects",
95 (bool (Circle::*)(Circle const &) const) & Circle::intersects);
96 cls.def("isWithin",
97 (bool (Circle::*)(UnitVector3d const &) const) & Circle::isWithin);
98 cls.def("isWithin",
99 (bool (Circle::*)(Circle const &) const) & Circle::isWithin);
100 cls.def("clipTo",
101 (Circle & (Circle::*)(UnitVector3d const &)) & Circle::clipTo);
102 cls.def("clipTo", (Circle & (Circle::*)(Circle const &)) & Circle::clipTo);
103 cls.def("clippedTo",
104 (Circle(Circle::*)(UnitVector3d const &) const) &
105 Circle::clippedTo);
106 cls.def("clippedTo",
107 (Circle(Circle::*)(Circle const &) const) & Circle::clippedTo);
108 cls.def("expandTo",
109 (Circle & (Circle::*)(UnitVector3d const &)) & Circle::expandTo);
110 cls.def("expandTo",
111 (Circle & (Circle::*)(Circle const &)) & Circle::expandTo);
112 cls.def("expandedTo",
113 (Circle(Circle::*)(UnitVector3d const &) const) &
114 Circle::expandedTo);
115 cls.def("expandedTo",
116 (Circle(Circle::*)(Circle const &) const) & Circle::expandedTo);
117 cls.def("dilateBy", &Circle::dilateBy, "radius"_a);
118 cls.def("dilatedBy", &Circle::dilatedBy, "radius"_a);
119 cls.def("erodeBy", &Circle::erodeBy, "radius"_a);
120 cls.def("erodedBy", &Circle::erodedBy, "radius"_a);
121 cls.def("getArea", &Circle::getArea);
122 cls.def("complement", &Circle::complement);
123 cls.def("complemented", &Circle::complemented);
124
125 // Note that the Region interface has already been wrapped.
126
127 cls.def("__str__", [](Circle const &self) {
128 return py::str("Circle({!s}, {!s})")
129 .format(self.getCenter(), self.getOpeningAngle());
130 });
131 cls.def("__repr__", [](Circle const &self) {
132 return py::str("Circle({!r}, {!r})")
133 .format(self.getCenter(), self.getOpeningAngle());
134 });
135 cls.def(py::pickle(&python::encode, &python::decode<Circle>));
136}
Circle is a circular region on the unit sphere that contains its boundary.
Definition: Circle.h:46
Angle getOpeningAngle() const
getOpeningAngle returns the opening angle of this circle - that is, the angle between its center vect...
Definition: Circle.h:128
UnitVector3d const & getCenter() const
getCenter returns the center of this circle as a unit vector.
Definition: Circle.h:118

◆ defineClass() [7/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< CompoundRegion, std::unique_ptr< CompoundRegion >, Region > &  cls)

Definition at line 46 of file _compoundRegion.cc.

46 {
47 cls.def(
48 "cloneOperand",
49 [](CompoundRegion const &self, std::ptrdiff_t n) {
50 return self.getOperand(python::convertIndex(2, n)).clone();
51 }
52 );
53}
CompoundRegion is an intermediate base class for spherical regions that are comprised of a point-set ...
Region const & getOperand(std::size_t n) const

◆ defineClass() [8/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< ConvexPolygon, std::unique_ptr< ConvexPolygon >, Region > &  cls)

Definition at line 45 of file _convexPolygon.cc.

46 {
47 cls.attr("TYPE_CODE") = py::int_(ConvexPolygon::TYPE_CODE);
48
49 cls.def_static("convexHull", &ConvexPolygon::convexHull, "points"_a);
50
51 cls.def(py::init<std::vector<UnitVector3d> const &>(), "points"_a);
52 // Do not wrap the two unsafe (3 and 4 vertex) constructors
53 cls.def(py::init<ConvexPolygon const &>(), "convexPolygon"_a);
54
55 cls.def("__eq__", &ConvexPolygon::operator==, py::is_operator());
56 cls.def("__ne__", &ConvexPolygon::operator!=, py::is_operator());
57
58 cls.def("getVertices", &ConvexPolygon::getVertices);
59 cls.def("getCentroid", &ConvexPolygon::getCentroid);
60
61 // Note that much of the Region interface has already been wrapped. Here are bits that have not:
62 // (include overloads from Region that would otherwise be shadowed).
63 cls.def("contains", py::overload_cast<UnitVector3d const &>(&ConvexPolygon::contains, py::const_));
64 cls.def("contains", py::overload_cast<Region const &>(&ConvexPolygon::contains, py::const_));
65 cls.def("contains",
66 py::vectorize((bool (ConvexPolygon::*)(double, double, double) const)&ConvexPolygon::contains),
67 "x"_a, "y"_a, "z"_a);
68 cls.def("contains",
69 py::vectorize((bool (ConvexPolygon::*)(double, double) const)&ConvexPolygon::contains),
70 "lon"_a, "lat"_a);
71 cls.def("isDisjointFrom", &ConvexPolygon::isDisjointFrom);
72 cls.def("intersects", &ConvexPolygon::intersects);
73 cls.def("isWithin", &ConvexPolygon::isWithin);
74
75 cls.def("__repr__", [](ConvexPolygon const &self) {
76 return py::str("ConvexPolygon({!r})").format(self.getVertices());
77 });
78 cls.def(py::pickle(&python::encode, &python::decode<ConvexPolygon>));
79}
ConvexPolygon is a closed convex polygon on the unit sphere.
Definition: ConvexPolygon.h:57
std::vector< UnitVector3d > const & getVertices() const
Definition: ConvexPolygon.h:99

◆ defineClass() [9/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< Ellipse, std::unique_ptr< Ellipse >, Region > &  cls)

Definition at line 44 of file _ellipse.cc.

44 {
45 cls.attr("TYPE_CODE") = py::int_(Ellipse::TYPE_CODE);
46
47 cls.def_static("empty", &Ellipse::empty);
48 cls.def_static("full", &Ellipse::full);
49
50 cls.def(py::init<>());
51 cls.def(py::init<Circle const &>(), "circle"_a);
52 cls.def(py::init<UnitVector3d const &, Angle>(), "center"_a,
53 "angle"_a = Angle(0.0));
54 cls.def(py::init<UnitVector3d const &, UnitVector3d const &, Angle>(),
55 "focus1"_a, "focus2"_a, "alpha"_a);
56 cls.def(py::init<UnitVector3d const &, Angle, Angle, Angle>(), "center"_a,
57 "alpha"_a, "beta"_a, "orientation"_a);
58 cls.def(py::init<Ellipse const &>(), "ellipse"_a);
59
60 cls.def("__eq__", &Ellipse::operator==, py::is_operator());
61 cls.def("__ne__", &Ellipse::operator!=, py::is_operator());
62
63 cls.def("isEmpty", &Ellipse::isEmpty);
64 cls.def("isFull", &Ellipse::isFull);
65 cls.def("isGreatCircle", &Ellipse::isGreatCircle);
66 cls.def("isCircle", &Ellipse::isCircle);
67 cls.def("getTransformMatrix", &Ellipse::getTransformMatrix);
68 cls.def("getCenter", &Ellipse::getCenter);
69 cls.def("getF1", &Ellipse::getF1);
70 cls.def("getF2", &Ellipse::getF2);
71 cls.def("getAlpha", &Ellipse::getAlpha);
72 cls.def("getBeta", &Ellipse::getBeta);
73 cls.def("getGamma", &Ellipse::getGamma);
74 cls.def("complement", &Ellipse::complement);
75 cls.def("complemented", &Ellipse::complemented);
76
77 // Note that the Region interface has already been wrapped.
78
79 cls.def("__str__", [](Ellipse const &self) {
80 return py::str("Ellipse({!s}, {!s}, {!s})")
81 .format(self.getF1(), self.getF2(), self.getAlpha());
82 });
83 cls.def("__repr__", [](Ellipse const &self) {
84 return py::str("Ellipse({!r}, {!r}, {!r})")
85 .format(self.getF1(), self.getF2(), self.getAlpha());
86 });
87 cls.def(py::pickle(&python::encode, &python::decode<Ellipse>));
88}
Ellipse is an elliptical region on the sphere.
Definition: Ellipse.h:170
Angle getAlpha() const
getAlpha returns α, the first semi-axis length of the ellipse.
Definition: Ellipse.h:252
UnitVector3d getF2() const
getF2 returns the second focal point of the ellipse.
Definition: Ellipse.h:244
UnitVector3d getF1() const
getF1 returns the first focal point of the ellipse.
Definition: Ellipse.h:238

◆ defineClass() [10/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< HtmPixelization, Pixelization > &  cls)

Definition at line 35 of file _htmPixelization.cc.

35 {
36 cls.attr("MAX_LEVEL") = py::int_(HtmPixelization::MAX_LEVEL);
37
38 cls.def_static("level", &HtmPixelization::level, "i"_a);
39 cls.def_static("triangle", &HtmPixelization::triangle, "i"_a);
40 cls.def_static("asString", &HtmPixelization::asString, "i"_a);
41
42 cls.def(py::init<int>(), "level"_a);
43 cls.def(py::init<HtmPixelization const &>(), "htmPixelization"_a);
44
45 cls.def("getLevel", &HtmPixelization::getLevel);
46
47 cls.def("__eq__",
48 [](HtmPixelization const &self, HtmPixelization const &other) {
49 return self.getLevel() == other.getLevel();
50 });
51 cls.def("__ne__",
52 [](HtmPixelization const &self, HtmPixelization const &other) {
53 return self.getLevel() != other.getLevel();
54 });
55 cls.def("__repr__", [](HtmPixelization const &self) {
56 return py::str("HtmPixelization({!s})").format(self.getLevel());
57 });
58 cls.def("__reduce__", [cls](HtmPixelization const &self) {
59 return py::make_tuple(cls, py::make_tuple(self.getLevel()));
60 });
61}
HtmPixelization provides HTM indexing of points and regions.
int getLevel() const
getLevel returns the subdivision level of this pixelization.

◆ defineClass() [11/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< IntersectionRegion, std::unique_ptr< IntersectionRegion >, CompoundRegion > &  cls)

Definition at line 64 of file _compoundRegion.cc.

64 {
65 cls.attr("TYPE_CODE") = py::int_(IntersectionRegion::TYPE_CODE);
66 cls.def(py::init<Region const &, Region const &>());
67 cls.def(py::pickle(&python::encode, &python::decode<IntersectionRegion>));
68 cls.def("__repr__", [](CompoundRegion const &self) { return _repr("IntersectionRegion({!r}, {!r})", self); });
69}

◆ defineClass() [12/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< Interval1d, std::shared_ptr< Interval1d > > &  cls)

Definition at line 36 of file _interval1d.cc.

36 {
37 python::defineInterval<decltype(cls), Interval1d, double>(cls);
38
39 cls.def_static("empty", &Interval1d::empty);
40 cls.def_static("full", &Interval1d::full);
41
42 cls.def(py::init<>());
43 cls.def(py::init<double>(), "x"_a);
44 cls.def(py::init<double, double>(), "x"_a, "y"_a);
45 cls.def(py::init<Interval1d const &>(), "interval"_a);
46
47 cls.def("isFull", &Interval1d::isFull);
48
49 cls.def("__str__", [](Interval1d const &self) {
50 return py::str("[{!s}, {!s}]").format(self.getA(), self.getB());
51 });
52 cls.def("__repr__", [](Interval1d const &self) {
53 return py::str("Interval1d({!r}, {!r})")
54 .format(self.getA(), self.getB());
55 });
56}

◆ defineClass() [13/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< LonLat, std::shared_ptr< LonLat > > &  cls)

Definition at line 36 of file _lonLat.cc.

36 {
37 cls.def_static("fromDegrees", &LonLat::fromDegrees);
38 cls.def_static("fromRadians", &LonLat::fromRadians);
39 cls.def_static("latitudeOf", &LonLat::latitudeOf);
40 cls.def_static("longitudeOf", &LonLat::longitudeOf);
41
42 cls.def(py::init<>());
43 cls.def(py::init<LonLat const &>());
44 cls.def(py::init<NormalizedAngle, Angle>(), "lon"_a, "lat"_a);
45 cls.def(py::init<Vector3d const &>(), "vector"_a);
46
47 cls.def("__eq__", &LonLat::operator==, py::is_operator());
48 cls.def("__nq__", &LonLat::operator!=, py::is_operator());
49
50 cls.def("getLon", &LonLat::getLon);
51 cls.def("getLat", &LonLat::getLat);
52
53 cls.def("__len__", [](LonLat const &self) { return py::int_(2); });
54 cls.def("__getitem__", [](LonLat const &self, py::object key) {
55 auto t = py::make_tuple(self.getLon(), self.getLat());
56 return t.attr("__getitem__")(key);
57 });
58 cls.def("__iter__", [](LonLat const &self) {
59 auto t = py::make_tuple(self.getLon(), self.getLat());
60 return t.attr("__iter__")();
61 });
62
63 cls.def("__str__", [](LonLat const &self) {
64 return py::str("[{!s}, {!s}]")
65 .format(self.getLon().asRadians(), self.getLat().asRadians());
66 });
67 cls.def("__repr__", [](LonLat const &self) {
68 return py::str("LonLat.fromRadians({!r}, {!r})")
69 .format(self.getLon().asRadians(), self.getLat().asRadians());
70 });
71 cls.def("__reduce__", [cls](LonLat const &self) {
72 return py::make_tuple(cls,
73 py::make_tuple(self.getLon(), self.getLat()));
74 });
75}

◆ defineClass() [14/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< Matrix3d, std::shared_ptr< Matrix3d > > &  cls)

Definition at line 42 of file _matrix3d.cc.

42 {
43 cls.def(py::init<>());
44 cls.def(py::init<double, double, double, double, double, double, double,
45 double, double>(),
46 "m00"_a, "m01"_a, "m02"_a, "m10"_a, "m11"_a, "m12"_a, "m20"_a,
47 "m21"_a, "m22"_a);
48 cls.def(py::init<Vector3d const &>(), "diagonal"_a);
49 cls.def(py::init<double>(), "scale"_a);
50 cls.def(py::init<Matrix3d const &>(), "matrix"_a);
51
52 cls.def("__eq__", &Matrix3d::operator==, py::is_operator());
53 cls.def("__ne__", &Matrix3d::operator!=, py::is_operator());
54
55 // Add bounds checking to getRow and getColumn
56 cls.def("getRow", &getRow, "row"_a);
57 cls.def("getColumn",
58 [](Matrix3d const &self, py::int_ col) {
59 return self.getColumn(
60 static_cast<int>(python::convertIndex(3, col)));
61 },
62 "col"_a);
63
64 cls.def("__len__", [](Matrix3d const &self) { return py::int_(3); });
65 cls.def("__getitem__", &getRow, py::is_operator());
66 cls.def("__getitem__",
67 [](Matrix3d const &self, py::tuple t) {
68 if (t.size() > 2) {
69 throw py::index_error("Too many indexes for Matrix3d");
70 } else if (t.size() == 0) {
71 return py::cast(self);
72 } else if (t.size() == 1) {
73 return py::cast(getRow(self, t[0].cast<py::int_>()));
74 }
75 return py::cast(
76 self(python::convertIndex(3, t[0].cast<py::int_>()),
77 python::convertIndex(3, t[1].cast<py::int_>())));
78 },
79 py::is_operator());
80
81 cls.def("inner", &Matrix3d::inner, "matrix"_a);
82 cls.def("getSquaredNorm", &Matrix3d::getSquaredNorm);
83 cls.def("getNorm", &Matrix3d::getNorm);
84
85 cls.def("__mul__",
86 (Vector3d(Matrix3d::*)(Vector3d const &) const) &
87 Matrix3d::operator*,
88 "vector"_a, py::is_operator());
89 cls.def("__mul__",
90 (Matrix3d(Matrix3d::*)(Matrix3d const &) const) &
91 Matrix3d::operator*,
92 "matrix"_a, py::is_operator());
93 cls.def("__add__", &Matrix3d::operator+, py::is_operator());
94 cls.def("__sub__", &Matrix3d::operator-, py::is_operator());
95
96 cls.def("cwiseProduct", &Matrix3d::cwiseProduct);
97 cls.def("transpose", &Matrix3d::transpose);
98 cls.def("inverse", &Matrix3d::inverse);
99
100 cls.def("__str__", [](Matrix3d const &self) {
101 return py::str("[[{!s}, {!s}, {!s}],\n"
102 " [{!s}, {!s}, {!s}],\n"
103 " [{!s}, {!s}, {!s}]]")
104 .format(self(0, 0), self(0, 1), self(0, 2), self(1, 0),
105 self(1, 1), self(1, 2), self(2, 0), self(2, 1),
106 self(2, 2));
107 });
108 cls.def("__repr__", [](Matrix3d const &self) {
109 return py::str("Matrix3d({!r}, {!r}, {!r},\n"
110 " {!r}, {!r}, {!r},\n"
111 " {!r}, {!r}, {!r})")
112 .format(self(0, 0), self(0, 1), self(0, 2), self(1, 0),
113 self(1, 1), self(1, 2), self(2, 0), self(2, 1),
114 self(2, 2));
115 });
116 cls.def("__reduce__", [cls](Matrix3d const &self) {
117 auto args = py::make_tuple(self(0, 0), self(0, 1), self(0, 2),
118 self(1, 0), self(1, 1), self(1, 2),
119 self(2, 0), self(2, 1), self(2, 2));
120 return py::make_tuple(cls, args);
121 });
122}
A 3x3 matrix with real entries stored in double precision.
Definition: Matrix3d.h:38
Vector3d const & getColumn(int c) const
getColumn returns the c-th matrix column. Bounds are not checked.
Definition: Matrix3d.h:87
int col
Definition: CR.cc:144

◆ defineClass() [15/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< Mq3cPixelization, Pixelization > &  cls)

Definition at line 35 of file _mq3cPixelization.cc.

35 {
36 cls.attr("MAX_LEVEL") = py::int_(Mq3cPixelization::MAX_LEVEL);
37
38 cls.def_static("level", &Mq3cPixelization::level);
39 cls.def_static("quad", &Mq3cPixelization::quad);
40 cls.def_static("neighborhood", &Mq3cPixelization::neighborhood);
41 cls.def_static("asString", &Mq3cPixelization::asString);
42
43 cls.def(py::init<int>(), "level"_a);
44 cls.def(py::init<Mq3cPixelization const &>(), "mq3cPixelization"_a);
45
46 cls.def("getLevel", &Mq3cPixelization::getLevel);
47
48 cls.def("__eq__",
49 [](Mq3cPixelization const &self, Mq3cPixelization const &other) {
50 return self.getLevel() == other.getLevel();
51 });
52 cls.def("__ne__",
53 [](Mq3cPixelization const &self, Mq3cPixelization const &other) {
54 return self.getLevel() != other.getLevel();
55 });
56 cls.def("__repr__", [](Mq3cPixelization const &self) {
57 return py::str("Mq3cPixelization({!s})").format(self.getLevel());
58 });
59 cls.def("__reduce__", [cls](Mq3cPixelization const &self) {
60 return py::make_tuple(cls, py::make_tuple(self.getLevel()));
61 });
62}
Mq3cPixelization provides modified Q3C indexing of points and regions.
int getLevel() const
getLevel returns the subdivision level of this pixelization.

◆ defineClass() [16/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< NormalizedAngle > &  cls)

Definition at line 37 of file _normalizedAngle.cc.

37 {
38 // Provide the equivalent of the NormalizedAngle to Angle C++ cast
39 // operator in Python
40 py::implicitly_convertible<NormalizedAngle, Angle>();
41
42 cls.def_static("nan", &NormalizedAngle::nan);
43 cls.def_static("fromDegrees", &NormalizedAngle::fromDegrees);
44 cls.def_static("fromRadians", &NormalizedAngle::fromRadians);
45 cls.def_static("between", &NormalizedAngle::between, "a"_a, "b"_a);
46 cls.def_static("center", &NormalizedAngle::center, "a"_a, "b"_a);
47
48 cls.def(py::init<>());
49 cls.def(py::init<NormalizedAngle const &>());
50 cls.def(py::init<Angle const &>());
51 cls.def(py::init<double>(), "radians"_a);
52 cls.def(py::init<LonLat const &, LonLat const &>(), "a"_a, "b"_a);
53 cls.def(py::init<Vector3d const &, Vector3d const &>(), "a"_a, "b"_a);
54
55 cls.def("__eq__", &NormalizedAngle::operator==, py::is_operator());
56 cls.def("__ne__", &NormalizedAngle::operator!=, py::is_operator());
57 cls.def("__lt__", &NormalizedAngle::operator<, py::is_operator());
58 cls.def("__gt__", &NormalizedAngle::operator>, py::is_operator());
59 cls.def("__le__", &NormalizedAngle::operator<=, py::is_operator());
60 cls.def("__ge__", &NormalizedAngle::operator>=, py::is_operator());
61
62 cls.def("__neg__",
63 (Angle(NormalizedAngle::*)() const) & NormalizedAngle::operator-);
64 cls.def("__add__", &NormalizedAngle::operator+, py::is_operator());
65 cls.def("__sub__",
66 (Angle(NormalizedAngle::*)(Angle const &) const) &
67 NormalizedAngle::operator-,
68 py::is_operator());
69 cls.def("__mul__", &NormalizedAngle::operator*, py::is_operator());
70 cls.def("__rmul__", &NormalizedAngle::operator*, py::is_operator());
71 cls.def("__truediv__",
72 (Angle(NormalizedAngle::*)(double) const) &
73 NormalizedAngle::operator/,
74 py::is_operator());
75 cls.def("__truediv__",
76 (double (NormalizedAngle::*)(Angle const &) const) &
77 NormalizedAngle::operator/,
78 py::is_operator());
79
80 cls.def("asDegrees", &NormalizedAngle::asDegrees);
81 cls.def("asRadians", &NormalizedAngle::asRadians);
82 cls.def("isNan", &NormalizedAngle::isNan);
83 cls.def("getAngleTo", &NormalizedAngle::getAngleTo);
84
85 cls.def("__str__", [](NormalizedAngle const &self) {
86 return py::str("{!s}").format(self.asRadians());
87 });
88 cls.def("__repr__", [](NormalizedAngle const &self) {
89 return py::str("NormalizedAngle({!r})").format(self.asRadians());
90 });
91
92 cls.def("__reduce__", [cls](NormalizedAngle const &self) {
93 return py::make_tuple(cls, py::make_tuple(self.asRadians()));
94 });
95}
double asRadians() const
asRadians returns the value of this angle in units of radians.

◆ defineClass() [17/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< NormalizedAngleInterval, std::shared_ptr< NormalizedAngleInterval > > &  cls)

Definition at line 36 of file _normalizedAngleInterval.cc.

37 {
38 python::defineInterval<decltype(cls), NormalizedAngleInterval,
39 NormalizedAngle>(cls);
40
41 cls.def_static("fromDegrees", &NormalizedAngleInterval::fromDegrees, "x"_a,
42 "y"_a);
43 cls.def_static("fromRadians", &NormalizedAngleInterval::fromRadians, "x"_a,
44 "y"_a);
45 cls.def_static("empty", &NormalizedAngleInterval::empty);
46 cls.def_static("full", &NormalizedAngleInterval::full);
47
48 cls.def(py::init<>());
49 cls.def(py::init<Angle>(), "x"_a);
50 cls.def(py::init<NormalizedAngle>(), "x"_a);
51 cls.def(py::init<Angle, Angle>(), "x"_a, "y"_a);
52 cls.def(py::init<NormalizedAngle, NormalizedAngle>(), "x"_a, "y"_a);
53 cls.def(py::init<NormalizedAngleInterval const &>(), "angleInterval"_a);
54
55 cls.def("isEmpty", &NormalizedAngleInterval::isEmpty);
56 cls.def("isFull", &NormalizedAngleInterval::isFull);
57 cls.def("wraps", &NormalizedAngleInterval::wraps);
58
59 cls.def("__str__", [](NormalizedAngleInterval const &self) {
60 return py::str("[{!s}, {!s}]")
61 .format(self.getA().asRadians(), self.getB().asRadians());
62 });
63 cls.def("__repr__", [](NormalizedAngleInterval const &self) {
64 return py::str("NormalizedAngleInterval.fromRadians({!r},"
65 " {!r})")
66 .format(self.getA().asRadians(), self.getB().asRadians());
67 });
68}
NormalizedAngleInterval represents closed intervals of normalized angles, i.e.
NormalizedAngle getA() const
getA returns the first endpoint of this interval.
NormalizedAngle getB() const
getB returns the second endpoint of this interval.

◆ defineClass() [18/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< Pixelization > &  cls)

Definition at line 37 of file _pixelization.cc.

37 {
38 cls.def("universe", &Pixelization::universe);
39 cls.def("pixel", &Pixelization::pixel, "i"_a);
40 cls.def("index", &Pixelization::index, "i"_a);
41 cls.def("toString", &Pixelization::toString, "i"_a);
42 cls.def("envelope", &Pixelization::envelope, "region"_a, "maxRanges"_a = 0);
43 cls.def("interior", &Pixelization::interior, "region"_a, "maxRanges"_a = 0);
44}

◆ defineClass() [19/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< Q3cPixelization, Pixelization > &  cls)

Definition at line 35 of file _q3cPixelization.cc.

35 {
36 cls.attr("MAX_LEVEL") = py::int_(Q3cPixelization::MAX_LEVEL);
37
38 cls.def(py::init<int>(), "level"_a);
39 cls.def(py::init<Q3cPixelization const &>(), "q3cPixelization"_a);
40
41 cls.def("getLevel", &Q3cPixelization::getLevel);
42 cls.def("quad", &Q3cPixelization::quad);
43 cls.def("neighborhood", &Q3cPixelization::neighborhood);
44
45 cls.def("__eq__",
46 [](Q3cPixelization const &self, Q3cPixelization const &other) {
47 return self.getLevel() == other.getLevel();
48 });
49 cls.def("__ne__",
50 [](Q3cPixelization const &self, Q3cPixelization const &other) {
51 return self.getLevel() != other.getLevel();
52 });
53 cls.def("__repr__", [](Q3cPixelization const &self) {
54 return py::str("Q3cPixelization({!s})").format(self.getLevel());
55 });
56 cls.def("__reduce__", [cls](Q3cPixelization const &self) {
57 return py::make_tuple(cls, py::make_tuple(self.getLevel()));
58 });
59}
Q3cPixelization provides Q3C indexing of points and regions.
int getLevel() const
getLevel returns the subdivision level of this pixelization.

◆ defineClass() [20/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< RangeSet, std::shared_ptr< RangeSet > > &  cls)

Definition at line 87 of file _rangeSet.cc.

87 {
88 cls.def(py::init<>());
89 cls.def(py::init<uint64_t>(), "integer"_a);
90 cls.def(py::init([](uint64_t a, uint64_t b) {
91 return new RangeSet(a, b);
92 }),
93 "first"_a, "last"_a);
94 cls.def(py::init<RangeSet const &>(), "rangeSet"_a);
95 cls.def(py::init(
96 [](py::iterable iterable) {
97 return new RangeSet(makeRangeSet(iterable));
98 }),
99 "iterable"_a);
100 cls.def("__eq__", &RangeSet::operator==, py::is_operator());
101 cls.def("__ne__", &RangeSet::operator!=, py::is_operator());
102
103 cls.def("insert", (void (RangeSet::*)(uint64_t)) & RangeSet::insert,
104 "integer"_a);
105 cls.def("insert",
106 (void (RangeSet::*)(uint64_t, uint64_t)) & RangeSet::insert,
107 "first"_a, "last"_a);
108 cls.def("erase", (void (RangeSet::*)(uint64_t)) & RangeSet::erase,
109 "integer"_a);
110 cls.def("erase", (void (RangeSet::*)(uint64_t, uint64_t)) & RangeSet::erase,
111 "first"_a, "last"_a);
112
113 cls.def("complement", &RangeSet::complement);
114 cls.def("complemented", &RangeSet::complemented);
115 cls.def("intersection", &RangeSet::intersection, "rangeSet"_a);
116 // In C++, the set union function is named join because union is a keyword.
117 // Python does not suffer from the same restriction.
118 cls.def("union", &RangeSet::join, "rangeSet"_a);
119 cls.def("difference", &RangeSet::difference, "rangeSet"_a);
120 cls.def("symmetricDifference", &RangeSet::symmetricDifference,
121 "rangeSet"_a);
122 cls.def("__invert__", &RangeSet::operator~, py::is_operator());
123 cls.def("__and__", &RangeSet::operator&, py::is_operator());
124 cls.def("__or__", &RangeSet::operator|, py::is_operator());
125 cls.def("__sub__", &RangeSet::operator-, py::is_operator());
126 cls.def("__xor__", &RangeSet::operator^, py::is_operator());
127 cls.def("__iand__", &RangeSet::operator&=);
128 cls.def("__ior__", &RangeSet::operator|=);
129 cls.def("__isub__", &RangeSet::operator-=);
130 cls.def("__ixor__", &RangeSet::operator^=);
131
132 cls.def("__len__", &RangeSet::size);
133 cls.def("__getitem__", [](RangeSet const &self, py::int_ i) {
134 auto j = python::convertIndex(static_cast<ptrdiff_t>(self.size()), i);
135 return py::cast(self.begin()[j]);
136 });
137
138 cls.def("intersects",
139 (bool (RangeSet::*)(uint64_t) const) & RangeSet::intersects,
140 "integer"_a);
141 cls.def("intersects",
142 (bool (RangeSet::*)(uint64_t, uint64_t) const) &
143 RangeSet::intersects,
144 "first"_a, "last"_a);
145 cls.def("intersects",
146 (bool (RangeSet::*)(RangeSet const &) const) & RangeSet::intersects,
147 "rangeSet"_a);
148
149 cls.def("contains",
150 (bool (RangeSet::*)(uint64_t) const) & RangeSet::contains,
151 "integer"_a);
152 cls.def("contains",
153 (bool (RangeSet::*)(uint64_t, uint64_t) const) & RangeSet::contains,
154 "first"_a, "last"_a);
155 cls.def("contains",
156 (bool (RangeSet::*)(RangeSet const &) const) & RangeSet::contains,
157 "rangeSet"_a);
158 cls.def("__contains__",
159 (bool (RangeSet::*)(uint64_t) const) & RangeSet::contains,
160 "integer"_a, py::is_operator());
161 cls.def("__contains__",
162 (bool (RangeSet::*)(uint64_t, uint64_t) const) & RangeSet::contains,
163 "first"_a, "last"_a, py::is_operator());
164 cls.def("__contains__",
165 (bool (RangeSet::*)(RangeSet const &) const) & RangeSet::contains,
166 "rangeSet"_a, py::is_operator());
167
168 cls.def("isWithin",
169 (bool (RangeSet::*)(uint64_t) const) & RangeSet::isWithin,
170 "integer"_a);
171 cls.def("isWithin",
172 (bool (RangeSet::*)(uint64_t, uint64_t) const) & RangeSet::isWithin,
173 "first"_a, "last"_a);
174 cls.def("isWithin",
175 (bool (RangeSet::*)(RangeSet const &) const) & RangeSet::isWithin,
176 "rangeSet"_a);
177
178 cls.def("isDisjointFrom",
179 (bool (RangeSet::*)(uint64_t) const) & RangeSet::isDisjointFrom,
180 "integer"_a);
181 cls.def("isDisjointFrom",
182 (bool (RangeSet::*)(uint64_t, uint64_t) const) &
183 RangeSet::isDisjointFrom,
184 "first"_a, "last"_a);
185 cls.def("isDisjointFrom",
186 (bool (RangeSet::*)(RangeSet const &) const) &
187 RangeSet::isDisjointFrom,
188 "rangeSet"_a);
189
190 cls.def("simplify", &RangeSet::simplify, "n"_a);
191 cls.def("simplified", &RangeSet::simplified, "n"_a);
192 cls.def("scale", &RangeSet::scale, "factor"_a);
193 cls.def("scaled", &RangeSet::scaled, "factor"_a);
194 cls.def("fill", &RangeSet::fill);
195 cls.def("clear", &RangeSet::clear);
196 cls.def("empty", &RangeSet::empty);
197 cls.def("full", &RangeSet::full);
198 cls.def("size", &RangeSet::size);
199 cls.def("cardinality", &RangeSet::cardinality);
200 // max_size() and swap() are omitted. The former is a C++ container
201 // requirement, and the latter doesn't seem relevant to Python.
202 cls.def("isValid", &RangeSet::cardinality);
203 cls.def("ranges", &ranges);
204
205 cls.def("__str__",
206 [](RangeSet const &self) { return py::str(ranges(self)); });
207 cls.def("__repr__", [](RangeSet const &self) {
208 return py::str("RangeSet({!s})").format(ranges(self));
209 });
210
211 cls.def("__reduce__", [cls](RangeSet const &self) {
212 return py::make_tuple(cls, py::make_tuple(ranges(self)));
213 });
214}
table::Key< int > b
A RangeSet is a set of unsigned 64 bit integers.
Definition: RangeSet.h:99

◆ defineClass() [21/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< Region, std::unique_ptr< Region > > &  cls)

Definition at line 45 of file _region.cc.

45 {
46 cls.def("clone", &Region::clone);
47 cls.def("getBoundingBox", &Region::getBoundingBox);
48 cls.def("getBoundingBox3d", &Region::getBoundingBox3d);
49 cls.def("getBoundingCircle", &Region::getBoundingCircle);
50 cls.def("contains", py::overload_cast<UnitVector3d const &>(&Region::contains, py::const_),
51 "unitVector"_a);
52 cls.def("contains", py::vectorize((bool (Region::*)(double, double, double) const)&Region::contains),
53 "x"_a, "y"_a, "z"_a);
54 cls.def("contains", py::vectorize((bool (Region::*)(double, double) const)&Region::contains),
55 "lon"_a, "lat"_a);
56 cls.def("__contains__", py::overload_cast<UnitVector3d const &>(&Region::contains, py::const_),
57 py::is_operator());
58 // The per-subclass relate() overloads are used to implement
59 // double-dispatch in C++, and are not needed in Python.
60 cls.def("relate",
61 (Relationship(Region::*)(Region const &) const) & Region::relate,
62 "region"_a);
63 cls.def("encode", &python::encode);
64 cls.def_static("decode", &python::decode<Region>, "bytes"_a);
65}

◆ defineClass() [22/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< UnionRegion, std::unique_ptr< UnionRegion >, CompoundRegion > &  cls)

Definition at line 56 of file _compoundRegion.cc.

56 {
57 cls.attr("TYPE_CODE") = py::int_(UnionRegion::TYPE_CODE);
58 cls.def(py::init<Region const &, Region const &>());
59 cls.def(py::pickle(&python::encode, &python::decode<UnionRegion>));
60 cls.def("__repr__", [](CompoundRegion const &self) { return _repr("UnionRegion({!r}, {!r})", self); });
61}

◆ defineClass() [23/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< UnitVector3d, std::shared_ptr< UnitVector3d > > &  cls)

Definition at line 39 of file _unitVector3d.cc.

39 {
40 // Provide the equivalent of the UnitVector3d to Vector3d C++ cast
41 // operator in Python
42 py::implicitly_convertible<UnitVector3d, Vector3d>();
43
44 cls.def_static(
45 "orthogonalTo",
46 (UnitVector3d(*)(Vector3d const &)) & UnitVector3d::orthogonalTo,
47 "vector"_a);
48 cls.def_static("orthogonalTo",
49 (UnitVector3d(*)(Vector3d const &, Vector3d const &)) &
50 UnitVector3d::orthogonalTo,
51 "vector1"_a, "vector2"_a);
52 cls.def_static("orthogonalTo",
53 (UnitVector3d(*)(NormalizedAngle const &)) &
54 UnitVector3d::orthogonalTo,
55 "meridian"_a);
56 cls.def_static("northFrom", &UnitVector3d::northFrom, "vector"_a);
57 cls.def_static("X", &UnitVector3d::X);
58 cls.def_static("Y", &UnitVector3d::Y);
59 cls.def_static("Z", &UnitVector3d::Z);
60 // The fromNormalized static factory functions are not exposed to
61 // Python, as they are easy to misuse and intended only for performance
62 // critical code (i.e. not Python).
63
64 cls.def(py::init<>());
65 cls.def(py::init<UnitVector3d const &>(), "unitVector"_a);
66 cls.def(py::init<Vector3d const &>(), "vector"_a);
67 cls.def(py::init<double, double, double>(), "x"_a, "y"_a, "z"_a);
68 cls.def(py::init<LonLat const &>(), "lonLat"_a);
69 cls.def(py::init<Angle, Angle>(), "lon"_a, "lat"_a);
70
71 cls.def("__eq__", &UnitVector3d::operator==, py::is_operator());
72 cls.def("__ne__", &UnitVector3d::operator!=, py::is_operator());
73 cls.def("__neg__",
74 (UnitVector3d(UnitVector3d::*)() const) & UnitVector3d::operator-);
75 cls.def("__add__", &UnitVector3d::operator+, py::is_operator());
76 cls.def("__sub__",
77 (Vector3d(UnitVector3d::*)(Vector3d const &) const) &
78 UnitVector3d::operator-,
79 py::is_operator());
80 cls.def("__mul__", &UnitVector3d::operator*, py::is_operator());
81 cls.def("__truediv__", &UnitVector3d::operator/, py::is_operator());
82
83 cls.def("x", &UnitVector3d::x);
84 cls.def("y", &UnitVector3d::y);
85 cls.def("z", &UnitVector3d::z);
86 cls.def("x", &UnitVector3d::dot);
87 cls.def("dot", &UnitVector3d::dot);
88 cls.def("cross", &UnitVector3d::cross);
89 cls.def("robustCross", &UnitVector3d::robustCross);
90 cls.def("cwiseProduct", &UnitVector3d::cwiseProduct);
91 cls.def("rotatedAround", &UnitVector3d::rotatedAround, "axis"_a, "angle"_a);
92
93 cls.def("__len__", [](UnitVector3d const &self) { return py::int_(3); });
94 cls.def("__getitem__", [](UnitVector3d const &self, py::int_ i) {
95 return self(python::convertIndex(3, i));
96 });
97
98 cls.def("__str__", [](UnitVector3d const &self) {
99 return py::str("[{!s}, {!s}, {!s}]")
100 .format(self.x(), self.y(), self.z());
101 });
102 cls.def("__repr__", [](UnitVector3d const &self) {
103 return py::str("UnitVector3d({!r}, {!r}, {!r})")
104 .format(self.x(), self.y(), self.z());
105 });
106
107 // Do not implement __reduce__ for pickling. Why? Given:
108 //
109 // u = UnitVector3d(x, y, z)
110 // v = UnitVector3d(u.x(), u.y(), u.z())
111 //
112 // u may not be identical to v, since the constructor normalizes its input
113 // components. Furthermore, UnitVector3d::fromNormalized is not visible to
114 // Python, and even if it were, pybind11 is currently incapable of returning
115 // a picklable reference to it.
116 cls.def(py::pickle([](UnitVector3d const &self) { return py::make_tuple(self.x(), self.y(), self.z()); },
117 [](py::tuple t) {
118 if (t.size() != 3) {
119 throw std::runtime_error("Tuple size = " + std::to_string(t.size()) +
120 "; must be 3 for a UnitVector3d");
121 }
122 return new UnitVector3d(UnitVector3d::fromNormalized(
123 t[0].cast<double>(), t[1].cast<double>(), t[2].cast<double>()));
124 }));
125}
T to_string(T... args)

◆ defineClass() [24/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< Vector3d, std::shared_ptr< Vector3d > > &  cls)

Definition at line 38 of file _vector3d.cc.

38 {
39 cls.def(py::init<>());
40 cls.def(py::init<double, double, double>(), "x"_a, "y"_a, "z"_a);
41 cls.def(py::init<Vector3d const &>(), "vector"_a);
42 // Construct a Vector3d from a UnitVector3d, enabling implicit
43 // conversion from UnitVector3d to Vector3d in python via
44 // py::implicitly_convertible
45 cls.def(py::init([](UnitVector3d const &u) {
46 return new Vector3d(u.x(), u.y(), u.z());
47 }));
48
49 cls.def("__eq__", &Vector3d::operator==, py::is_operator());
50 cls.def("__ne__", &Vector3d::operator!=, py::is_operator());
51 cls.def("__neg__", (Vector3d(Vector3d::*)() const) & Vector3d::operator-);
52 cls.def("__add__", &Vector3d::operator+, py::is_operator());
53 cls.def("__sub__",
54 (Vector3d(Vector3d::*)(Vector3d const &) const) &
55 Vector3d::operator-,
56 py::is_operator());
57 cls.def("__mul__", &Vector3d::operator*, py::is_operator());
58 cls.def("__truediv__", &Vector3d::operator/, py::is_operator());
59
60 cls.def("__iadd__", &Vector3d::operator+=);
61 cls.def("__isub__", &Vector3d::operator-=);
62 cls.def("__imul__", &Vector3d::operator*=);
63 cls.def("__itruediv__", &Vector3d::operator/=);
64
65 cls.def("x", &Vector3d::x);
66 cls.def("y", &Vector3d::y);
67 cls.def("z", &Vector3d::z);
68 cls.def("dot", &Vector3d::dot);
69 cls.def("getSquaredNorm", &Vector3d::getSquaredNorm);
70 cls.def("getNorm", &Vector3d::getNorm);
71 cls.def("isZero", &Vector3d::isZero);
72 cls.def("normalize", &Vector3d::normalize);
73 cls.def("isNormalized", &Vector3d::isNormalized);
74 cls.def("cross", &Vector3d::cross);
75 cls.def("cwiseProduct", &Vector3d::cwiseProduct);
76 cls.def("rotatedAround", &Vector3d::rotatedAround, "axis"_a, "angle"_a);
77
78 cls.def("__len__", [](Vector3d const &self) { return py::int_(3); });
79 cls.def("__getitem__", [](Vector3d const &self, py::int_ i) {
80 return self(python::convertIndex(3, i));
81 });
82
83 cls.def("__str__", [](Vector3d const &self) {
84 return py::str("[{!s}, {!s}, {!s}]")
85 .format(self.x(), self.y(), self.z());
86 });
87 cls.def("__repr__", [](Vector3d const &self) {
88 return py::str("Vector3d({!r}, {!r}, {!r})")
89 .format(self.x(), self.y(), self.z());
90 });
91
92 cls.def("__reduce__", [cls](Vector3d const &self) {
93 return py::make_tuple(cls,
94 py::make_tuple(self.x(), self.y(), self.z()));
95 });
96}

◆ defineClass() [25/25]

template<typename Pybind11Class >
void lsst::sphgeom::defineClass ( Pybind11Class &  cls)

◆ defineCurve()

void lsst::sphgeom::defineCurve ( py::module &  mod)

Definition at line 32 of file _curve.cc.

32 {
33 mod.def("log2", (uint8_t(*)(uint64_t)) & log2);
34 mod.def("mortonIndex", (uint64_t(*)(uint32_t, uint32_t)) & mortonIndex,
35 "x"_a, "y"_a);
36 mod.def("mortonIndexInverse",
37 (std::tuple<uint32_t, uint32_t>(*)(uint64_t)) & mortonIndexInverse,
38 "z"_a);
39 mod.def("mortonToHilbert", &mortonToHilbert, "z"_a, "m"_a);
40 mod.def("hilbertToMorton", &hilbertToMorton, "h"_a, "m"_a);
41 mod.def("hilbertIndex",
42 (uint64_t(*)(uint32_t, uint32_t, int)) & hilbertIndex, "x"_a, "y"_a,
43 "m"_a);
44 mod.def("hilbertIndexInverse",
45 (std::tuple<uint32_t, uint32_t>(*)(uint64_t, int)) &
46 hilbertIndexInverse,
47 "h"_a, "m"_a);
48}

◆ defineOrientation()

void lsst::sphgeom::defineOrientation ( py::module &  mod)

Definition at line 32 of file _orientation.cc.

32 {
33 mod.def("orientationExact", &orientationExact, "a"_a, "b"_a, "c"_a);
34 mod.def("orientation", &orientation, "a"_a, "b"_a, "c"_a);
35 mod.def("orientationX", &orientationX, "b"_a, "c"_a);
36 mod.def("orientationY", &orientationY, "b"_a, "c"_a);
37 mod.def("orientationZ", &orientationZ, "b"_a, "c"_a);
38}

◆ defineRelationship()

void lsst::sphgeom::defineRelationship ( py::module &  mod)

Definition at line 32 of file _relationship.cc.

32 {
33 mod.attr("DISJOINT") = py::cast(DISJOINT.to_ulong());
34 mod.attr("INTERSECTS") = py::cast(INTERSECTS.to_ulong());
35 mod.attr("CONTAINS") = py::cast(CONTAINS.to_ulong());
36 mod.attr("WITHIN") = py::cast(WITHIN.to_ulong());
37
38 mod.def("invert", &invert, "relationship"_a);
39}

◆ defineUtils()

void lsst::sphgeom::defineUtils ( py::module &  mod)

Definition at line 37 of file _utils.cc.

37 {
38 mod.def("getMinSquaredChordLength", &getMinSquaredChordLength, "v"_a, "a"_a,
39 "b"_a, "n"_a);
40 mod.def("getMaxSquaredChordLength", &getMaxSquaredChordLength, "v"_a, "a"_a,
41 "b"_a, "n"_a);
42 mod.def("getMinAngleToCircle", &getMinAngleToCircle, "x"_a, "c"_a);
43 mod.def("getMaxAngleToCircle", &getMaxAngleToCircle, "x"_a, "c"_a);
44 mod.def("getWeightedCentroid", &getWeightedCentroid, "vector0"_a,
45 "vector1"_a, "vector2"_a);
46}

◆ encodeDouble()

void lsst::sphgeom::encodeDouble ( double  item,
std::vector< uint8_t > &  buffer 
)
inline

encodeDouble appends an IEEE double in little-endian byte order to the end of buffer.

Definition at line 49 of file codec.h.

49 {
50#ifdef OPTIMIZED_LITTLE_ENDIAN
51 auto ptr = reinterpret_cast<uint8_t const *>(&item);
52 buffer.insert(buffer.end(), ptr, ptr + 8);
53#else
54 union { uint64_t u; double d; };
55 d = item;
56 buffer.push_back(static_cast<uint8_t>(u));
57 buffer.push_back(static_cast<uint8_t>(u >> 8));
58 buffer.push_back(static_cast<uint8_t>(u >> 16));
59 buffer.push_back(static_cast<uint8_t>(u >> 24));
60 buffer.push_back(static_cast<uint8_t>(u >> 32));
61 buffer.push_back(static_cast<uint8_t>(u >> 40));
62 buffer.push_back(static_cast<uint8_t>(u >> 48));
63 buffer.push_back(static_cast<uint8_t>(u >> 56));
64#endif
65}
uint64_t * ptr
Definition: RangeSet.cc:88
T end(T... args)
T insert(T... args)
T push_back(T... args)

◆ encodeU64()

void lsst::sphgeom::encodeU64 ( std::uint64_t  item,
std::vector< uint8_t > &  buffer 
)
inline

encodeU64 appends an uint64 in little-endian byte order to the end of buffer.

Definition at line 88 of file codec.h.

88 {
89#ifdef OPTIMIZED_LITTLE_ENDIAN
90 auto ptr = reinterpret_cast<uint8_t const *>(&item);
91 buffer.insert(buffer.end(), ptr, ptr + 8);
92#else
93 union { uint64_t u; double d; };
94 d = item;
95 buffer.push_back(static_cast<uint8_t>(u));
96 buffer.push_back(static_cast<uint8_t>(u >> 8));
97 buffer.push_back(static_cast<uint8_t>(u >> 16));
98 buffer.push_back(static_cast<uint8_t>(u >> 24));
99 buffer.push_back(static_cast<uint8_t>(u >> 32));
100 buffer.push_back(static_cast<uint8_t>(u >> 40));
101 buffer.push_back(static_cast<uint8_t>(u >> 48));
102 buffer.push_back(static_cast<uint8_t>(u >> 56));
103#endif
104}

◆ getMaxAngleToCircle()

Angle lsst::sphgeom::getMaxAngleToCircle ( Angle  x,
Angle  c 
)
inline

getMaxAngleToCircle returns the maximum angular separation between a point at latitude x and the points on the circle of constant latitude c.

Definition at line 68 of file utils.h.

68 {
70 if (abs(x) <= abs(c)) {
71 return a + Angle(PI) - 2.0 * abs(c);
72 }
73 if (a < abs(x)) {
74 return Angle(PI) - 2.0 * abs(c) - a;
75 }
76 return Angle(PI) + 2.0 * abs(c) - a;
77}
double x
Angle getMinAngleToCircle(Angle x, Angle c)
getMinAngleToCircle returns the minimum angular separation between a point at latitude x and the poin...
Definition: utils.h:62
Angle abs(Angle const &a)
Definition: Angle.h:106

◆ getMaxSquaredChordLength()

double lsst::sphgeom::getMaxSquaredChordLength ( Vector3d const &  v,
Vector3d const &  a,
Vector3d const &  b,
Vector3d const &  n 
)

Let p be the unit vector furthest from v that lies on the plane with normal n in the direction of the cross product of a and b.

If p is in the interior of the great circle segment from a to b, then this helper function returns the squared chord length between p and v. Otherwise it returns 0 - the minimum squared chord length between any pair of points on the sphere.

Definition at line 58 of file utils.cc.

62{
63 Vector3d vxn = v.cross(n);
64 if (vxn.dot(a) < 0.0 && vxn.dot(b) > 0.0) {
65 // v is in the lune defined by the half great circle passing through
66 // n and -a and the half great circle passing through n and -b, so p
67 // is in the interior of the great circle segment from a to b. The
68 // angle θ between p and v satisfies ‖v‖ ‖n‖ sin θ = |v·n|,
69 // and ‖v‖ ‖n‖ cos θ = -‖v × n‖. The desired squared chord length is
70 // 4 sin²(θ/2).
71 double s = std::fabs(v.dot(n));
72 double c = - vxn.getNorm();
73 double d = std::sin(0.5 * std::atan2(s, c));
74 return 4.0 * d * d;
75 }
76 return 0.0;
77}
T atan2(T... args)
double dot(Vector3d const &v) const
dot returns the inner product of this vector and v.
Definition: Vector3d.h:73
double getNorm() const
getNorm returns the L2 norm of this vector.
Definition: Vector3d.h:81
Vector3d cross(Vector3d const &v) const
cross returns the cross product of this vector and v.
Definition: Vector3d.h:101
T sin(T... args)

◆ getMinAngleToCircle()

Angle lsst::sphgeom::getMinAngleToCircle ( Angle  x,
Angle  c 
)
inline

getMinAngleToCircle returns the minimum angular separation between a point at latitude x and the points on the circle of constant latitude c.

Definition at line 62 of file utils.h.

62 {
63 return abs(x - c);
64}

◆ getMinSquaredChordLength()

double lsst::sphgeom::getMinSquaredChordLength ( Vector3d const &  v,
Vector3d const &  a,
Vector3d const &  b,
Vector3d const &  n 
)

Let p be the unit vector closest to v that lies on the plane with normal n in the direction of the cross product of a and b.

If p is in the interior of the great circle segment from a to b, then this function returns the squared chord length between p and v. Otherwise it returns 4 - the maximum squared chord length between any pair of points on the unit sphere.

Definition at line 36 of file utils.cc.

40{
41 Vector3d vxn = v.cross(n);
42 if (vxn.dot(a) > 0.0 && vxn.dot(b) < 0.0) {
43 // v is in the lune defined by the half great circle passing through
44 // n and a and the half great circle passing through n and b, so p
45 // is in the interior of the great circle segment from a to b. The
46 // angle θ between p and v satisfies ‖v‖ ‖n‖ sin θ = |v·n|,
47 // and ‖v‖ ‖n‖ cos θ = ‖v × n‖. The desired squared chord length is
48 // 4 sin²(θ/2).
49 double s = std::fabs(v.dot(n));
50 double c = vxn.getNorm();
51 double theta = (c == 0.0) ? 0.5 * PI : std::atan(s / c);
52 double d = std::sin(0.5 * theta);
53 return 4.0 * d * d;
54 }
55 return 4.0;
56}
T atan(T... args)

◆ getWeightedCentroid()

Vector3d lsst::sphgeom::getWeightedCentroid ( UnitVector3d const &  v0,
UnitVector3d const &  v1,
UnitVector3d const &  v2 
)

getWeightedCentroid returns the center of mass of the given spherical triangle (assuming a uniform mass distribution over the triangle surface), weighted by the triangle area.

Definition at line 79 of file utils.cc.

82{
83 // For the details, see:
84 //
85 // The centroid and inertia tensor for a spherical triangle
86 // John E. Brock
87 // 1974, Naval Postgraduate School, Monterey Calif.
88 //
89 // https://openlibrary.org/books/OL25493734M/The_centroid_and_inertia_tensor_for_a_spherical_triangle
90
91 Vector3d x01 = v0.robustCross(v1); // twice the cross product of v0 and v1
92 Vector3d x12 = v1.robustCross(v2);
93 Vector3d x20 = v2.robustCross(v0);
94 double s01 = 0.5 * x01.normalize(); // sine of the angle between v0 and v1
95 double s12 = 0.5 * x12.normalize();
96 double s20 = 0.5 * x20.normalize();
97 double c01 = v0.dot(v1); // cosine of the angle between v0 and v1
98 double c12 = v1.dot(v2);
99 double c20 = v2.dot(v0);
100 double a0 = (s12 == 0.0 && c12 == 0.0) ? 0.0 : std::atan2(s12, c12);
101 double a1 = (s20 == 0.0 && c20 == 0.0) ? 0.0 : std::atan2(s20, c20);
102 double a2 = (s01 == 0.0 && c01 == 0.0) ? 0.0 : std::atan2(s01, c01);
103 return 0.5 * (x01 * a2 + x12 * a0 + x20 * a1);
104}
double normalize()
normalize scales this vector to have unit norm and returns its norm prior to scaling.
Definition: Vector3d.cc:41

◆ hilbertIndex()

uint64_t lsst::sphgeom::hilbertIndex ( uint32_t  x,
uint32_t  y,
int  m 
)
inline

hilbertIndex returns the index of (x, y) in a 2-D Hilbert curve.

Only the m least significant bits of x and y are used. Computing the Hilbert index of a point has been measured to take 4 to 15 times as long as computing its Morton index on an Intel Core i7-3820QM CPU. With Xcode 7.3 and -O3, latency is ~19ns per call at a CPU frequency of 3.5 GHz.

Definition at line 349 of file curve.h.

349 {
350 return mortonToHilbert(mortonIndex(x, y), m);
351}
int y
Definition: SpanSet.cc:48
int m
Definition: SpanSet.cc:48
uint64_t mortonIndex(uint32_t x, uint32_t y)
mortonIndex interleaves the bits of x and y.
Definition: curve.h:148
uint64_t mortonToHilbert(uint64_t z, int m)
mortonToHilbert converts the 2m-bit Morton index z to the corresponding Hilbert index.
Definition: curve.h:236

◆ hilbertIndexInverse()

std::tuple< uint32_t, uint32_t > lsst::sphgeom::hilbertIndexInverse ( uint64_t  h,
int  m 
)
inline

hilbertIndexInverse returns the point (x, y) with Hilbert index h, where x and y are m bit integers.

Definition at line 361 of file curve.h.

361 {
363}
std::tuple< uint32_t, uint32_t > mortonIndexInverse(uint64_t z)
mortonIndexInverse separates the even and odd bits of z.
Definition: curve.h:195
uint64_t hilbertToMorton(uint64_t h, int m)
hilbertToMorton converts the 2m-bit Hilbert index h to the corresponding Morton index.
Definition: curve.h:290

◆ hilbertToMorton()

uint64_t lsst::sphgeom::hilbertToMorton ( uint64_t  h,
int  m 
)
inline

hilbertToMorton converts the 2m-bit Hilbert index h to the corresponding Morton index.

Definition at line 290 of file curve.h.

290 {
291 alignas(64) static uint8_t const HILBERT_INVERSE_LUT_3[256] = {
292 0x40, 0x02, 0x03, 0xc1, 0x04, 0x45, 0x47, 0x86,
293 0x0c, 0x4d, 0x4f, 0x8e, 0xcb, 0x89, 0x88, 0x4a,
294 0x20, 0x61, 0x63, 0xa2, 0x68, 0x2a, 0x2b, 0xe9,
295 0x6c, 0x2e, 0x2f, 0xed, 0xa7, 0xe6, 0xe4, 0x25,
296 0x30, 0x71, 0x73, 0xb2, 0x78, 0x3a, 0x3b, 0xf9,
297 0x7c, 0x3e, 0x3f, 0xfd, 0xb7, 0xf6, 0xf4, 0x35,
298 0xdf, 0x9d, 0x9c, 0x5e, 0x9b, 0xda, 0xd8, 0x19,
299 0x93, 0xd2, 0xd0, 0x11, 0x54, 0x16, 0x17, 0xd5,
300 0x00, 0x41, 0x43, 0x82, 0x48, 0x0a, 0x0b, 0xc9,
301 0x4c, 0x0e, 0x0f, 0xcd, 0x87, 0xc6, 0xc4, 0x05,
302 0x50, 0x12, 0x13, 0xd1, 0x14, 0x55, 0x57, 0x96,
303 0x1c, 0x5d, 0x5f, 0x9e, 0xdb, 0x99, 0x98, 0x5a,
304 0x70, 0x32, 0x33, 0xf1, 0x34, 0x75, 0x77, 0xb6,
305 0x3c, 0x7d, 0x7f, 0xbe, 0xfb, 0xb9, 0xb8, 0x7a,
306 0xaf, 0xee, 0xec, 0x2d, 0xe7, 0xa5, 0xa4, 0x66,
307 0xe3, 0xa1, 0xa0, 0x62, 0x28, 0x69, 0x6b, 0xaa,
308 0xff, 0xbd, 0xbc, 0x7e, 0xbb, 0xfa, 0xf8, 0x39,
309 0xb3, 0xf2, 0xf0, 0x31, 0x74, 0x36, 0x37, 0xf5,
310 0x9f, 0xde, 0xdc, 0x1d, 0xd7, 0x95, 0x94, 0x56,
311 0xd3, 0x91, 0x90, 0x52, 0x18, 0x59, 0x5b, 0x9a,
312 0x8f, 0xce, 0xcc, 0x0d, 0xc7, 0x85, 0x84, 0x46,
313 0xc3, 0x81, 0x80, 0x42, 0x08, 0x49, 0x4b, 0x8a,
314 0x60, 0x22, 0x23, 0xe1, 0x24, 0x65, 0x67, 0xa6,
315 0x2c, 0x6d, 0x6f, 0xae, 0xeb, 0xa9, 0xa8, 0x6a,
316 0xbf, 0xfe, 0xfc, 0x3d, 0xf7, 0xb5, 0xb4, 0x76,
317 0xf3, 0xb1, 0xb0, 0x72, 0x38, 0x79, 0x7b, 0xba,
318 0xef, 0xad, 0xac, 0x6e, 0xab, 0xea, 0xe8, 0x29,
319 0xa3, 0xe2, 0xe0, 0x21, 0x64, 0x26, 0x27, 0xe5,
320 0xcf, 0x8d, 0x8c, 0x4e, 0x8b, 0xca, 0xc8, 0x09,
321 0x83, 0xc2, 0xc0, 0x01, 0x44, 0x06, 0x07, 0xc5,
322 0x10, 0x51, 0x53, 0x92, 0x58, 0x1a, 0x1b, 0xd9,
323 0x5c, 0x1e, 0x1f, 0xdd, 0x97, 0xd6, 0xd4, 0x15
324 };
325 uint64_t z = 0;
326 uint64_t i = 0;
327 for (m = 2 * m; m >= 6;) {
328 m -= 6;
329 uint8_t j = HILBERT_INVERSE_LUT_3[i | ((h >> m) & 0x3f)];
330 z = (z << 6) | (j & 0x3f);
331 i = j & 0xc0;
332 }
333 if (m != 0) {
334 // m = 2 or 4
335 int r = 6 - m;
336 uint8_t j = HILBERT_INVERSE_LUT_3[i | ((h << r) & 0x3f)];
337 z = (z << m) | ((j & 0x3f) >> r);
338 }
339 return z;
340}
double z
Definition: Match.cc:44

◆ invert()

Relationship lsst::sphgeom::invert ( Relationship  r)
inline

Given the relationship between two sets A and B (i.e.

the output of A.relate(B)), invert returns the relationship between B and A (B.relate(A)).

Definition at line 55 of file Relationship.h.

55 {
56 // If A is disjoint from B, then B is disjoint from A. But if A contains B
57 // then B is within A, so the corresponding bits must be swapped.
58 return (r & DISJOINT) | ((r & CONTAINS) << 1) | ((r & WITHIN) >> 1);
59}

◆ log2() [1/2]

uint8_t lsst::sphgeom::log2 ( uint32_t  x)
inline

log2 returns the index of the most significant 1 bit in x. If x is 0, the return value is 0.

A beautiful algorithm to find this index is presented in:

‍Using de Bruijn Sequences to Index a 1 in a Computer Word C. E. Leiserson, H. Prokop, and K. H. Randall. http://supertech.csail.mit.edu/papers/debruijn.pdf

Definition at line 125 of file curve.h.

125 {
126 // See https://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn
127 alignas(32) static uint8_t const PERFECT_HASH_TABLE[32] = {
128 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
129 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
130 };
131 uint32_t const DE_BRUIJN_SEQUENCE = UINT32_C(0x07c4acdd);
132 x |= (x >> 1);
133 x |= (x >> 2);
134 x |= (x >> 4);
135 x |= (x >> 8);
136 x |= (x >> 16);
137 return PERFECT_HASH_TABLE[(DE_BRUIJN_SEQUENCE * x) >> 27];
138}

◆ log2() [2/2]

uint8_t lsst::sphgeom::log2 ( uint64_t  x)
inline

log2 returns the index of the most significant 1 bit in x. If x is 0, the return value is 0.

A beautiful algorithm to find this index is presented in:

‍Using de Bruijn Sequences to Index a 1 in a Computer Word C. E. Leiserson, H. Prokop, and K. H. Randall. http://supertech.csail.mit.edu/papers/debruijn.pdf

Definition at line 98 of file curve.h.

98 {
99 alignas(64) static uint8_t const PERFECT_HASH_TABLE[64] = {
100 0, 1, 2, 7, 3, 13, 8, 19, 4, 25, 14, 28, 9, 34, 20, 40,
101 5, 17, 26, 38, 15, 46, 29, 48, 10, 31, 35, 54, 21, 50, 41, 57,
102 63, 6, 12, 18, 24, 27, 33, 39, 16, 37, 45, 47, 30, 53, 49, 56,
103 62, 11, 23, 32, 36, 44, 52, 55, 61, 22, 43, 51, 60, 42, 59, 58
104 };
105 uint64_t const DE_BRUIJN_SEQUENCE = UINT64_C(0x0218a392cd3d5dbf);
106 // First ensure that all bits below the MSB are set.
107 x |= (x >> 1);
108 x |= (x >> 2);
109 x |= (x >> 4);
110 x |= (x >> 8);
111 x |= (x >> 16);
112 x |= (x >> 32);
113 // Then, subtract them away.
114 x = x - (x >> 1);
115 // Multiplication by x is now a shift by the index i of the MSB.
116 //
117 // By definition, the value of the upper 6 bits of a 64-bit De Bruijn
118 // sequence left shifted by i is different for every value of i in
119 // [0, 64). It can therefore be used as an an index into a lookup table
120 // that recovers i. In other words, (DE_BRUIJN_SEQUENCE * x) >> 58 is a
121 // minimal perfect hash function for 64 bit powers of 2.
122 return PERFECT_HASH_TABLE[(DE_BRUIJN_SEQUENCE * x) >> 58];
123}

◆ mortonIndex()

uint64_t lsst::sphgeom::mortonIndex ( uint32_t  x,
uint32_t  y 
)
inline

mortonIndex interleaves the bits of x and y.

The 32 even bits of the return value will be the bits of x, and the 32 odd bits those of y. This is the z-value of (x,y) defined by the Morton order function. See https://en.wikipedia.org/wiki/Z-order_curve for more information.

Definition at line 148 of file curve.h.

148 {
149 // This is just a 64-bit extension of:
150 // http://graphics.stanford.edu/~seander/bithacks.html#InterleaveBMN
151 uint64_t b = y;
152 uint64_t a = x;
153 b = (b | (b << 16)) & UINT64_C(0x0000ffff0000ffff);
154 a = (a | (a << 16)) & UINT64_C(0x0000ffff0000ffff);
155 b = (b | (b << 8)) & UINT64_C(0x00ff00ff00ff00ff);
156 a = (a | (a << 8)) & UINT64_C(0x00ff00ff00ff00ff);
157 b = (b | (b << 4)) & UINT64_C(0x0f0f0f0f0f0f0f0f);
158 a = (a | (a << 4)) & UINT64_C(0x0f0f0f0f0f0f0f0f);
159 b = (b | (b << 2)) & UINT64_C(0x3333333333333333);
160 a = (a | (a << 2)) & UINT64_C(0x3333333333333333);
161 b = (b | (b << 1)) & UINT64_C(0x5555555555555555);
162 a = (a | (a << 1)) & UINT64_C(0x5555555555555555);
163 return a | (b << 1);
164 }

◆ mortonIndexInverse()

std::tuple< uint32_t, uint32_t > lsst::sphgeom::mortonIndexInverse ( uint64_t  z)
inline

mortonIndexInverse separates the even and odd bits of z.

The 32 even bits of z are returned in the first element of the result tuple, and the 32 odd bits in the second. This is the inverse of mortonIndex().

Definition at line 195 of file curve.h.

195 {
196 uint64_t x = z & UINT64_C(0x5555555555555555);
197 uint64_t y = (z >> 1) & UINT64_C(0x5555555555555555);
198 x = (x | (x >> 1)) & UINT64_C(0x3333333333333333);
199 y = (y | (y >> 1)) & UINT64_C(0x3333333333333333);
200 x = (x | (x >> 2)) & UINT64_C(0x0f0f0f0f0f0f0f0f);
201 y = (y | (y >> 2)) & UINT64_C(0x0f0f0f0f0f0f0f0f);
202 x = (x | (x >> 4)) & UINT64_C(0x00ff00ff00ff00ff);
203 y = (y | (y >> 4)) & UINT64_C(0x00ff00ff00ff00ff);
204 x = (x | (x >> 8)) & UINT64_C(0x0000ffff0000ffff);
205 y = (y | (y >> 8)) & UINT64_C(0x0000ffff0000ffff);
206 return std::make_tuple(static_cast<uint32_t>(x | (x >> 16)),
207 static_cast<uint32_t>(y | (y >> 16)));
208 }
T make_tuple(T... args)

◆ mortonToHilbert()

uint64_t lsst::sphgeom::mortonToHilbert ( uint64_t  z,
int  m 
)
inline

mortonToHilbert converts the 2m-bit Morton index z to the corresponding Hilbert index.

Definition at line 236 of file curve.h.

236 {
237 alignas(64) static uint8_t const HILBERT_LUT_3[256] = {
238 0x40, 0xc3, 0x01, 0x02, 0x04, 0x45, 0x87, 0x46,
239 0x8e, 0x8d, 0x4f, 0xcc, 0x08, 0x49, 0x8b, 0x4a,
240 0xfa, 0x3b, 0xf9, 0xb8, 0x7c, 0xff, 0x3d, 0x3e,
241 0xf6, 0x37, 0xf5, 0xb4, 0xb2, 0xb1, 0x73, 0xf0,
242 0x10, 0x51, 0x93, 0x52, 0xde, 0x1f, 0xdd, 0x9c,
243 0x54, 0xd7, 0x15, 0x16, 0x58, 0xdb, 0x19, 0x1a,
244 0x20, 0x61, 0xa3, 0x62, 0xee, 0x2f, 0xed, 0xac,
245 0x64, 0xe7, 0x25, 0x26, 0x68, 0xeb, 0x29, 0x2a,
246 0x00, 0x41, 0x83, 0x42, 0xce, 0x0f, 0xcd, 0x8c,
247 0x44, 0xc7, 0x05, 0x06, 0x48, 0xcb, 0x09, 0x0a,
248 0x50, 0xd3, 0x11, 0x12, 0x14, 0x55, 0x97, 0x56,
249 0x9e, 0x9d, 0x5f, 0xdc, 0x18, 0x59, 0x9b, 0x5a,
250 0xba, 0xb9, 0x7b, 0xf8, 0xb6, 0xb5, 0x77, 0xf4,
251 0x3c, 0x7d, 0xbf, 0x7e, 0xf2, 0x33, 0xf1, 0xb0,
252 0x60, 0xe3, 0x21, 0x22, 0x24, 0x65, 0xa7, 0x66,
253 0xae, 0xad, 0x6f, 0xec, 0x28, 0x69, 0xab, 0x6a,
254 0xaa, 0xa9, 0x6b, 0xe8, 0xa6, 0xa5, 0x67, 0xe4,
255 0x2c, 0x6d, 0xaf, 0x6e, 0xe2, 0x23, 0xe1, 0xa0,
256 0x9a, 0x99, 0x5b, 0xd8, 0x96, 0x95, 0x57, 0xd4,
257 0x1c, 0x5d, 0x9f, 0x5e, 0xd2, 0x13, 0xd1, 0x90,
258 0x70, 0xf3, 0x31, 0x32, 0x34, 0x75, 0xb7, 0x76,
259 0xbe, 0xbd, 0x7f, 0xfc, 0x38, 0x79, 0xbb, 0x7a,
260 0xca, 0x0b, 0xc9, 0x88, 0x4c, 0xcf, 0x0d, 0x0e,
261 0xc6, 0x07, 0xc5, 0x84, 0x82, 0x81, 0x43, 0xc0,
262 0xea, 0x2b, 0xe9, 0xa8, 0x6c, 0xef, 0x2d, 0x2e,
263 0xe6, 0x27, 0xe5, 0xa4, 0xa2, 0xa1, 0x63, 0xe0,
264 0x30, 0x71, 0xb3, 0x72, 0xfe, 0x3f, 0xfd, 0xbc,
265 0x74, 0xf7, 0x35, 0x36, 0x78, 0xfb, 0x39, 0x3a,
266 0xda, 0x1b, 0xd9, 0x98, 0x5c, 0xdf, 0x1d, 0x1e,
267 0xd6, 0x17, 0xd5, 0x94, 0x92, 0x91, 0x53, 0xd0,
268 0x8a, 0x89, 0x4b, 0xc8, 0x86, 0x85, 0x47, 0xc4,
269 0x0c, 0x4d, 0x8f, 0x4e, 0xc2, 0x03, 0xc1, 0x80
270 };
271 uint64_t h = 0;
272 uint64_t i = 0;
273 for (m = 2 * m; m >= 6;) {
274 m -= 6;
275 uint8_t j = HILBERT_LUT_3[i | ((z >> m) & 0x3f)];
276 h = (h << 6) | (j & 0x3f);
277 i = j & 0xc0;
278 }
279 if (m != 0) {
280 // m = 2 or 4
281 int r = 6 - m;
282 uint8_t j = HILBERT_LUT_3[i | ((z << r) & 0x3f)];
283 h = (h << m) | ((j & 0x3f) >> r);
284 }
285 return h;
286}

◆ operator*() [1/2]

Angle lsst::sphgeom::operator* ( double  a,
Angle const &  b 
)
inline

Definition at line 98 of file Angle.h.

98{ return b * a; }

◆ operator*() [2/2]

Vector3d lsst::sphgeom::operator* ( double  s,
Vector3d const &  v 
)
inline

Definition at line 165 of file Vector3d.h.

165{ return v * s; }

◆ operator<<() [1/14]

std::ostream & lsst::sphgeom::operator<< ( std::ostream os,
Angle const &  a 
)

Definition at line 34 of file Angle.cc.

34 {
35 char buf[32];
36 std::snprintf(buf, sizeof(buf), "%.17g", a.asRadians());
37 return os << buf;
38}
std::ostream * os
Definition: Schema.cc:557
T snprintf(T... args)

◆ operator<<() [2/14]

std::ostream & lsst::sphgeom::operator<< ( std::ostream os,
AngleInterval const &  i 
)

Definition at line 34 of file AngleInterval.cc.

34 {
35 return os << '[' << i.getA() << ", " << i.getB() << ']';
36}

◆ operator<<() [3/14]

std::ostream & lsst::sphgeom::operator<< ( std::ostream os,
Box const &  b 
)

Definition at line 475 of file Box.cc.

475 {
476 return os << "{\"Box\": [" << b.getLon() << ", " << b.getLat() << "]}";
477}

◆ operator<<() [4/14]

std::ostream & lsst::sphgeom::operator<< ( std::ostream os,
Box3d const &  b 
)

Definition at line 34 of file Box3d.cc.

34 {
35 return os << "{\"Box3d\": [" << b.x() << ", " << b.y() << ", " << b.z() << "]}";
36}

◆ operator<<() [5/14]

std::ostream & lsst::sphgeom::operator<< ( std::ostream os,
Circle const &  c 
)

Definition at line 362 of file Circle.cc.

362 {
363 char tail[32];
364 std::snprintf(tail, sizeof(tail), ", %.17g]}", c.getSquaredChordLength());
365 return os << "{\"Circle\": [" << c.getCenter() << tail;
366}

◆ operator<<() [6/14]

std::ostream & lsst::sphgeom::operator<< ( std::ostream os,
ConvexPolygon const &  p 
)

Definition at line 382 of file ConvexPolygon.cc.

382 {
383 typedef std::vector<UnitVector3d>::const_iterator VertexIterator;
384 VertexIterator v = p.getVertices().begin();
385 VertexIterator const end = p.getVertices().end();
386 os << "{\"ConvexPolygon\": [" << *v;
387 for (++v; v != end; ++v) { os << ", " << *v; }
388 os << "]}";
389 return os;
390}
int end
T begin(T... args)

◆ operator<<() [7/14]

std::ostream & lsst::sphgeom::operator<< ( std::ostream os,
Ellipse const &  e 
)

Definition at line 388 of file Ellipse.cc.

388 {
389 os << "{\"Ellipse\": [" << e.getTransformMatrix() << ", "
390 << e.getAlpha() << ", " << e.getBeta() << "]}";
391 return os;
392}

◆ operator<<() [8/14]

std::ostream & lsst::sphgeom::operator<< ( std::ostream os,
Interval1d const &  i 
)

Definition at line 35 of file Interval1d.cc.

35 {
36 char buf[64];
37 std::snprintf(buf, sizeof(buf), "[%.17g, %.17g]", i.getA(), i.getB());
38 return os << buf;
39}

◆ operator<<() [9/14]

std::ostream & lsst::sphgeom::operator<< ( std::ostream os,
LonLat const &  p 
)

Definition at line 82 of file LonLat.cc.

82 {
83 return os << '[' << p.getLon() << ", " << p.getLat() << ']';
84}

◆ operator<<() [10/14]

std::ostream & lsst::sphgeom::operator<< ( std::ostream os,
Matrix3d const &  m 
)

Definition at line 35 of file Matrix3d.cc.

35 {
36 return os << '[' << m.getRow(0) << ", " << m.getRow(1) << ", " << m.getRow(2) << ']';
37}

◆ operator<<() [11/14]

std::ostream & lsst::sphgeom::operator<< ( std::ostream os,
NormalizedAngleInterval const &  i 
)

Definition at line 284 of file NormalizedAngleInterval.cc.

286{
287 return os << '[' << i.getA() << ", " << i.getB() << ']';
288}

◆ operator<<() [12/14]

std::ostream & lsst::sphgeom::operator<< ( std::ostream os,
RangeSet const &  s 
)

Definition at line 616 of file RangeSet.cc.

616 {
617 os << "{\"RangeSet\": [";
618 bool first = true;
619 for (auto const & t: s) {
620 if (!first) {
621 os << ", ";
622 }
623 first = false;
624 os << '[' << std::get<0>(t) << ", " << std::get<1>(t) << ']';
625 }
626 os << "]}";
627 return os;
628}

◆ operator<<() [13/14]

std::ostream & lsst::sphgeom::operator<< ( std::ostream os,
UnitVector3d const &  v 
)

Definition at line 73 of file UnitVector3d.cc.

73 {
74 return os << static_cast<Vector3d const &>(v);
75}

◆ operator<<() [14/14]

std::ostream & lsst::sphgeom::operator<< ( std::ostream os,
Vector3d const &  v 
)

Definition at line 133 of file Vector3d.cc.

133 {
134 char buf[128];
135 std::snprintf(buf, sizeof(buf), "[%.17g, %.17g, %.17g]",
136 v.x(), v.y(), v.z());
137 return os << buf;
138}

◆ orientation()

int lsst::sphgeom::orientation ( UnitVector3d const &  a,
UnitVector3d const &  b,
UnitVector3d const &  c 
)

orientation computes and returns the orientations of 3 unit vectors a, b and c.

The return value is +1 if the vectors are in counter-clockwise orientation, 0 if they are coplanar, colinear or identical, and -1 if they are in clockwise orientation.

This is equivalent to computing the sign of the scalar triple product a · (b x c), which is the sign of the determinant of the 3x3 matrix with a, b and c as columns/rows.

The implementation proceeds by first computing a double precision approximation, and then falling back to arbitrary precision arithmetic when necessary. Consequently, the result is exact.

Definition at line 135 of file orientation.cc.

138{
139 // This constant is a little more than 5ε, where ε = 2^-53. When multiplied
140 // by the permanent of |M|, it gives an error bound on the determinant of
141 // M. Here, M is a 3x3 matrix and |M| denotes the matrix obtained by
142 // taking the absolute value of each of its components. The derivation of
143 // this proceeds in the same manner as the derivation of the error bounds
144 // in section 4.3 of:
145 //
146 // Adaptive Precision Floating-Point Arithmetic
147 // and Fast Robust Geometric Predicates,
148 // Jonathan Richard Shewchuk,
149 // Discrete & Computational Geometry 18(3):305–363, October 1997.
150 //
151 // available online at http://www.cs.berkeley.edu/~jrs/papers/robustr.pdf
152 static double const relativeError = 5.6e-16;
153 // Because all 3 unit vectors are normalized, the maximum absolute value of
154 // any vector component, cross product component or dot product term in
155 // the calculation is very close to 1. The permanent of |M| must therefore
156 // be below 3 + c, where c is some small multiple of ε. This constant, a
157 // little larger than 3 * 5ε, is an upper bound on the absolute error in
158 // the determinant calculation.
159 static double const maxAbsoluteError = 1.7e-15;
160 // This constant accounts for floating point underflow (assuming hardware
161 // without gradual underflow, just to be conservative) in the computation
162 // of det(M). It is a little more than 14 * 2^-1022.
163 static double const minAbsoluteError = 4.0e-307;
164
165 double bycz = b.y() * c.z();
166 double bzcy = b.z() * c.y();
167 double bzcx = b.z() * c.x();
168 double bxcz = b.x() * c.z();
169 double bxcy = b.x() * c.y();
170 double bycx = b.y() * c.x();
171 double determinant = a.x() * (bycz - bzcy) +
172 a.y() * (bzcx - bxcz) +
173 a.z() * (bxcy - bycx);
174 if (determinant > maxAbsoluteError) {
175 return 1;
176 } else if (determinant < -maxAbsoluteError) {
177 return -1;
178 }
179 // Expend some more effort on what is hopefully a tighter error bound
180 // before falling back on arbitrary precision arithmetic.
181 double permanent = std::fabs(a.x()) * (std::fabs(bycz) + std::fabs(bzcy)) +
182 std::fabs(a.y()) * (std::fabs(bzcx) + std::fabs(bxcz)) +
183 std::fabs(a.z()) * (std::fabs(bxcy) + std::fabs(bycx));
184 double maxError = relativeError * permanent + minAbsoluteError;
185 if (determinant > maxError) {
186 return 1;
187 } else if (determinant < -maxError) {
188 return -1;
189 }
190 // Avoid the slow path when any two inputs are identical or antipodal.
191 if (a == b || b == c || a == c || a == -b || b == -c || a == -c) {
192 return 0;
193 }
194 return orientationExact(a, b, c);
195}
int orientationExact(Vector3d const &a, Vector3d const &b, Vector3d const &c)
orientationExact computes and returns the orientations of 3 vectors a, b and c, which need not be nor...
Definition: orientation.cc:76

◆ orientationExact()

int lsst::sphgeom::orientationExact ( Vector3d const &  a,
Vector3d const &  b,
Vector3d const &  c 
)

orientationExact computes and returns the orientations of 3 vectors a, b and c, which need not be normalized but are assumed to have finite components.

The return value is +1 if the vectors a, b, and c are in counter-clockwise orientation, 0 if they are coplanar, colinear, or identical, and -1 if they are in clockwise orientation. The implementation uses arbitrary precision arithmetic to avoid floating point rounding error, underflow and overflow.

Definition at line 76 of file orientation.cc.

79{
80 // Product mantissa storage buffers.
81 uint32_t mantissaBuffers[6][6];
82 // Product mantissas.
83 BigInteger mantissas[6] = {
84 BigInteger(mantissaBuffers[0], 6),
85 BigInteger(mantissaBuffers[1], 6),
86 BigInteger(mantissaBuffers[2], 6),
87 BigInteger(mantissaBuffers[3], 6),
88 BigInteger(mantissaBuffers[4], 6),
89 BigInteger(mantissaBuffers[5], 6)
90 };
91 BigFloat products[6] = {
92 BigFloat(&mantissas[0]),
93 BigFloat(&mantissas[1]),
94 BigFloat(&mantissas[2]),
95 BigFloat(&mantissas[3]),
96 BigFloat(&mantissas[4]),
97 BigFloat(&mantissas[5])
98 };
99 // An accumulator and its storage.
100 uint32_t accumulatorBuffer[512];
101 BigInteger accumulator(accumulatorBuffer,
102 sizeof(accumulatorBuffer) / sizeof(uint32_t));
103 // Compute the products in the determinant. Performing all multiplication
104 // up front means that each product mantissa occupies at most 3*53 bits.
105 computeProduct(products[0], a.x(), b.y(), c.z());
106 computeProduct(products[1], a.x(), b.z(), c.y());
107 computeProduct(products[2], a.y(), b.z(), c.x());
108 computeProduct(products[3], a.y(), b.x(), c.z());
109 computeProduct(products[4], a.z(), b.x(), c.y());
110 computeProduct(products[5], a.z(), b.y(), c.x());
111 mantissas[1].negate();
112 mantissas[3].negate();
113 mantissas[5].negate();
114 // Sort the array of products in descending exponent order.
115 std::sort(products, products + 6, [](BigFloat const & a, BigFloat const & b) {
116 return a.exponent > b.exponent;
117 });
118 // First, initialize the accumulator to the product with the highest
119 // exponent, then add the remaining products. Prior to each addition, we
120 // must shift the accumulated value so that its radix point lines up with
121 // the the radix point of the product to add.
122 //
123 // More precisely, at each step we have an accumulated value A·2ʲ and a
124 // product P·2ᵏ, and we update the accumulator to equal (A·2ʲ⁻ᵏ + P)·2ᵏ.
125 // Because the products were sorted beforehand, j ≥ k and 2ʲ⁻ᵏ is an
126 // integer.
127 accumulator = *products[0].mantissa;
128 for (int i = 1; i < 6; ++i) {
129 accumulator.multiplyPow2(products[i - 1].exponent - products[i].exponent);
130 accumulator.add(*products[i].mantissa);
131 }
132 return accumulator.getSign();
133}
BigInteger is an arbitrary precision signed integer class.
Definition: BigInteger.h:45
void negate()
negate multiplies this integer by -1.
Definition: BigInteger.h:103
T sort(T... args)
BigInteger * mantissa
Definition: orientation.cc:40
int exponent
Definition: orientation.cc:41

◆ orientationX()

int lsst::sphgeom::orientationX ( UnitVector3d const &  b,
UnitVector3d const &  c 
)

orientationX(b, c) is equivalent to orientation(UnitVector3d::X(), b, c).

Definition at line 227 of file orientation.cc.

227 {
228 int o = _orientationXYZ(b.y() * c.z(), b.z() * c.y());
229 return (o != 0) ? o : orientationExact(UnitVector3d::X(), b, c);
230}

◆ orientationY()

int lsst::sphgeom::orientationY ( UnitVector3d const &  b,
UnitVector3d const &  c 
)

orientationY(b, c) is equivalent to orientation(UnitVector3d::Y(), b, c).

Definition at line 232 of file orientation.cc.

232 {
233 int o = _orientationXYZ(b.z() * c.x(), b.x() * c.z());
234 return (o != 0) ? o : orientationExact(UnitVector3d::Y(), b, c);
235}

◆ orientationZ()

int lsst::sphgeom::orientationZ ( UnitVector3d const &  b,
UnitVector3d const &  c 
)

orientationZ(b, c) is equivalent to orientation(UnitVector3d::Z(), b, c).

Definition at line 237 of file orientation.cc.

237 {
238 int o = _orientationXYZ(b.x() * c.y(), b.y() * c.x());
239 return (o != 0) ? o : orientationExact(UnitVector3d::Z(), b, c);
240}

◆ sin()

double lsst::sphgeom::sin ( Angle const &  a)
inline

Definition at line 102 of file Angle.h.

102{ return std::sin(a.asRadians()); }

◆ swap()

void lsst::sphgeom::swap ( RangeSet a,
RangeSet b 
)
inline

Definition at line 608 of file RangeSet.h.

608 {
609 a.swap(b);
610}

◆ tan()

double lsst::sphgeom::tan ( Angle const &  a)
inline

Definition at line 104 of file Angle.h.

104{ return std::tan(a.asRadians()); }
T tan(T... args)

Variable Documentation

◆ DEG_PER_RAD

constexpr double lsst::sphgeom::DEG_PER_RAD = 57.2957795130823208767981548141
constexpr

Definition at line 39 of file constants.h.

◆ EPSILON

constexpr double lsst::sphgeom::EPSILON = 1.1102230246251565e-16
constexpr

Definition at line 54 of file constants.h.

◆ MAX_ASIN_ERROR

constexpr double lsst::sphgeom::MAX_ASIN_ERROR = 1.5e-8
constexpr

Definition at line 45 of file constants.h.

◆ MAX_SQUARED_CHORD_LENGTH_ERROR

constexpr double lsst::sphgeom::MAX_SQUARED_CHORD_LENGTH_ERROR = 2.5e-15
constexpr

Definition at line 50 of file constants.h.

◆ ONE_OVER_PI

constexpr double lsst::sphgeom::ONE_OVER_PI = 0.318309886183790671537767526745
constexpr

Definition at line 37 of file constants.h.

◆ PI

constexpr double lsst::sphgeom::PI = 3.1415926535897932384626433832795
constexpr

Definition at line 36 of file constants.h.

◆ RAD_PER_DEG

constexpr double lsst::sphgeom::RAD_PER_DEG = 0.0174532925199432957692369076849
constexpr

Definition at line 38 of file constants.h.