PLaSK library

Loading...
Searching...
No Matches
lateral.hpp
Go to the documentation of this file.
1/*
2 * This file is part of PLaSK (https://plask.app) by Photonics Group at TUL
3 * Copyright (c) 2024 Lodz University of Technology
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14#ifndef PLASK_VECTOR_LATERAL_HPP
15#define PLASK_VECTOR_LATERAL_HPP
16
17#include "../math.hpp"
18#include "../vec.hpp"
19
20 namespace plask {
21
22 template <typename T>
23 struct LateralVec {
24
25 static const int DIMS = 2;
26
27 T c0, c1;
28
29 T& lon() { return c0; }
30 constexpr const T& tran() const { return c0; }
31
32 T& tran() { return c1; }
33 constexpr const T& vert() const { return c1; }
34
38 typedef T* iterator;
39
43 typedef const T* const_iterator;
44
46 LateralVec() {}
47
52 template <typename OtherT>
53 constexpr LateralVec(const LateralVec<OtherT>& p): c0(p.c0), c1(p.c1) {}
54
59 PLASK_NO_CONVERSION_WARNING_BEGIN
60 template <int other_dim, typename OtherT>
61 constexpr LateralVec(const Vec<other_dim,OtherT>& p): c0(p.c0), c1(p.c1) {}
62 PLASK_NO_WARNING_END
63
68 constexpr LateralVec(T c0, T c1): c0(c0), c1(c1) {}
69
74 template <typename T0, typename T1>
75 constexpr LateralVec(const std::pair<T0,T1>& comp): c0(comp.first), c1(comp.second) {}
76
82 template <typename InputIteratorType>
83 static inline LateralVec<T> fromIterator(InputIteratorType inputIt) {
84 LateralVec<T> result;
85 result.c0 = T(*inputIt);
86 result.c1 = T(*++inputIt);
87 return result;
88 }
89
94 iterator begin() { return &c0; }
95
100 const_iterator begin() const { return &c0; }
101
106 iterator end() { return &c0 + 2; }
107
112 const_iterator end() const { return &c0 + 2; }
113
119 template <typename OtherT>
120 constexpr bool operator==(const LateralVec<OtherT>& p) const { return p.c0 == c0 && p.c1 == c1; }
121
128 template <typename OtherT, typename SuprType>
129 constexpr bool equals(const LateralVec< OtherT>& p, const SuprType& abs_supremum) const {
130 return is_zero(p.c0 - c0, abs_supremum) && is_zero(p.c1 - c1, abs_supremum); }
131
137 template <typename OtherT>
138 constexpr bool equals(const LateralVec< OtherT>& p) const {
139 return is_zero(p.c0 - c0) && is_zero(p.c1 - c1); }
140
146 template <typename OtherT>
147 constexpr bool operator!=(const LateralVec<OtherT>& p) const { return p.c0 != c0 || p.c1 != c1; }
148
155 inline T& operator[](size_t i) {
156 assert(i < 2);
157 return *(&c0 + i);
158 }
159
166 inline const T& operator[](size_t i) const {
167 assert(i < 2);
168 return *(&c0 + i);
169 }
170
176 template <typename OtherT>
177 constexpr auto operator+(const LateralVec<OtherT>& other) const -> LateralVec<decltype(c0 + other.c0)> {
178 return LateralVec<decltype(this->c0 + other.c0)>(c0 + other.c0, c1 + other.c1);
179 }
180
186 LateralVec<T>& operator+=(const LateralVec<T>& other) {
187 c0 += other.c0;
188 c1 += other.c1;
189 return *this;
190 }
191
197 template <typename OtherT>
198 constexpr auto operator-(const LateralVec<OtherT>& other) const -> LateralVec<decltype(c0 - other.c0)> {
199 return LateralVec<decltype(this->c0 - other.c0)>(c0 - other.c0, c1 - other.c1);
200 }
201
207 LateralVec<T>& operator-=(const LateralVec<T>& other) {
208 c0 -= other.c0;
209 c1 -= other.c1;
210 return *this;
211 }
212
218 template <typename OtherT>
219 constexpr auto operator*(const OtherT scale) const -> LateralVec<decltype(c0*scale)> {
220 PLASK_NO_CONVERSION_WARNING_BEGIN
221 return LateralVec<decltype(c0*scale)>(c0 * scale, c1 * scale);
222 PLASK_NO_WARNING_END
223 }
224
230 LateralVec<T>& operator*=(const T scalar) {
231 c0 *= scalar;
232 c1 *= scalar;
233 return *this;
234 }
235
241 constexpr LateralVec<T> operator/(const T scale) const { return LateralVec<T>(c0 / scale, c1 / scale); }
242
248 LateralVec<T>& operator/=(const T scalar) {
249 c0 /= scalar;
250 c1 /= scalar;
251 return *this;
252 }
253
258 constexpr LateralVec<T> operator-() const {
259 return LateralVec<T>(-c0, -c1);
260 }
261
266 LateralVec<T> sqr() const {
267 return LateralVec<T>(c0*c0, c1*c1);
268 }
269
274 LateralVec<T>& sqr_inplace() {
275 c0 *= c0; c1 *= c1;
276 return *this;
277 }
278
283 template <typename OtherT>
284 LateralVec<T> pow(OtherT a) const {
285 return LateralVec<T>(std::pow(c0, a), std::pow(c1, a));
286 }
287
293 inline void flip(size_t i) {
294 assert(i < 2);
295 operator[](i) = -operator[](i);
296 }
297
304 inline LateralVec<T> flipped(size_t i) {
305 LateralVec<T> res = *this;
306 res.flip(i);
307 return res;
308 }
309
316 friend inline std::ostream& operator<<(std::ostream& out, const LateralVec<T>& to_print) {
317 return out << '[' << to_print.c0 << ", " << to_print.c1 << ']';
318 }
319
327 template<class OT> inline
328 bool operator< (LateralVec< OT> const& v) const {
329 if (dbl_compare_lt(this->c0, v.c0)) return true;
330 if (dbl_compare_gt(this->c0, v.c0)) return false;
331 return dbl_compare_lt(this->c1, v.c1);
332 }
333};
334
341 template <typename T1, typename T2>
342 inline auto dot(const LateralVec<T1>& v1, const LateralVec<T2>& v2) -> decltype(v1.c0*v2.c0) {
343 return ::plask::fma(v1.c0, v2.c0, v1.c1 * v2.c1); //MSVC needs ::plask::
344}
345
351 template <typename T1, typename T2>
352 inline auto cross(const LateralVec<T1>& v1, const LateralVec<T2>& v2) -> decltype(v1.c0*v2.c1) {
353 return ::plask::fma(v1.c0, v2.c1, - v1.c1 * v2.c0); //MSVC needs ::plask::
354}
355
362 template <typename T, typename OtherT>
363 inline constexpr auto operator*(const OtherT& scale, const LateralVec<T>& v) -> decltype(v*scale) {
364 return v * scale;
365}
366
367
368 PLASK_API_EXTERN_TEMPLATE_SPECIALIZATION_STRUCT(LateralVec<double>)
369 PLASK_API_EXTERN_TEMPLATE_SPECIALIZATION_STRUCT(LateralVec<int>)
370
371} // namespace plask
372
373 namespace std {
374 template <typename T, typename OtherT>
375 plask::LateralVec<T> pow(plask::LateralVec<T> vec, OtherT a) {
376 return vec.pow(a);
377 }
378}
379
380#endif