PLaSK library
Loading...
Searching...
No Matches
tensor2.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) 2022 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__TESNOR2_H
15#define PLASK__TESNOR2_H
16
21#include <boost/concept_check.hpp>
22#include <iostream>
23
24#include "../math.hpp"
25#include "2d.hpp"
26
27namespace plask {
28
34template <typename T> struct Tensor2 {
35 T c00,
37
38 T& tran() { return c00; }
39 const T& tran() const { return c00; }
40
41 T& vert() { return c11; }
42 const T& vert() const { return c11; }
43
46
51 template <typename OtherT> Tensor2(const Tensor2<OtherT>& p) : c00(p.c00), c11(p.c11) {}
52
57 Tensor2(const T& val) : c00(val), c11(val) {}
58
63 Tensor2(const T& c00, const T& c11) : c00(c00), c11(c11) {}
64
69 template <typename T0, typename T1> Tensor2(const std::pair<T0, T1>& comp) : c00(comp.first), c11(comp.second) {}
70
75 Tensor2(const Vec<2, T>& vec) : c00(vec.c0), c11(vec.c1) {}
76
83 inline T& operator[](size_t i) {
84 assert(i < 2);
85 return *(&c00 + i);
86 }
87
94 inline const T& operator[](size_t i) const {
95 assert(i < 2);
96 return *(&c00 + i);
97 }
98
100 operator std::tuple<T, T>() const { return std::make_tuple(c00, c11); }
101
107 template <typename OtherT> bool operator==(const Tensor2<OtherT>& p) const { return p.c00 == c00 && p.c11 == c11; }
108
114 template <typename OtherT> constexpr bool equals(const Tensor2<OtherT>& p) const {
115 return is_zero(p.c00 - c00) && is_zero(p.c11 - c11);
116 }
117
123 template <typename OtherT> bool operator!=(const Tensor2<OtherT>& p) const { return p.c00 != c00 || p.c11 != c11; }
124
130 template <typename OtherT> auto operator+(const Tensor2<OtherT>& other) const -> Tensor2<decltype(c00 + other.c00)> {
131 return Tensor2<decltype(this->c00 + other.c00)>(c00 + other.c00, c11 + other.c11);
132 }
133
140 c00 += other.c00;
141 c11 += other.c11;
142 return *this;
143 }
144
151 template <typename OtherT> auto operator-(const Tensor2<OtherT>& other) const -> Tensor2<decltype(c00 - other.c00)> {
152 return Tensor2<decltype(this->c00 - other.c00)>(c00 - other.c00, c11 - other.c11);
153 }
154
161 c00 -= other.c00;
162 c11 -= other.c11;
163 return *this;
164 }
165
171 template <typename OtherT> auto operator*(const OtherT scale) const -> Tensor2<decltype(c00 * scale)> {
172 return Tensor2<decltype(c00 * scale)>(c00 * scale, c11 * scale);
173 }
174
181 c00 *= scalar;
182 c11 *= scalar;
183 return *this;
184 }
185
191 Tensor2<T> operator/(const T scale) const { return Tensor2<T>(c00 / scale, c11 / scale); }
192
199 c00 /= scalar;
200 c11 /= scalar;
201 return *this;
202 }
203
208 Tensor2<T> operator-() const { return Tensor2<T>(-c00, -c11); }
209
210 // /**
211 // * Square each component of tensor
212 // * \return squared tensor
213 // */
214 // Tensor2<T> sqr() const {
215 // return Tensor2<T>(c00*c00, c11*c11);
216 // }
217
218 // /**
219 // * Square each component of tensor in place
220 // * \return *this (squared)
221 // */
222 // Tensor2<T>& sqr_inplace() {
223 // c00 *= c00; c11 *= c11;
224 // return *this;
225 // }
226
227 // /**
228 // * Square root of each component of tensor
229 // * \return squared tensor
230 // */
231 // Tensor2<T> sqrt() const {
232 // return Tensor2<T>(std::sqrt(c00), std::sqrt(c11));
233 // }
234
235 // /**
236 // * Square root of each component of tensor in place
237 // * \return *this (squared)
238 // */
239 // Tensor2<T>& sqrt_inplace() {
240 // c00 = std::sqrt(c00); c11 = std::sqrt(c11);
241 // return *this;
242 // }
243
248 Tensor2<T> pow(double a) const { return Tensor2<T>(std::pow(c00, a), std::pow(c11, a)); }
249
256 friend inline std::ostream& operator<<(std::ostream& out, const Tensor2<T>& to_print) {
257 return out << '(' << str(to_print.c00) << ", " << str(to_print.c11) << ')';
258 }
259};
260
267template <typename T, typename OtherT> auto operator*(const OtherT scale, const Tensor2<T>& tensor) -> decltype(tensor * scale) {
268 return tensor * scale;
269}
270
276template <typename T> inline Tensor2<T> conj(const Tensor2<T>& v) { return Tensor2<T>(conj(v.c00), conj(v.c11)); }
277
279template <typename T> struct NaNImpl<Tensor2<T>> {
280 static constexpr Tensor2<T> get() { return Tensor2<T>(NaN<T>()); }
281};
282
284template <typename T> struct ZeroImpl<Tensor2<T>> {
285 static constexpr Tensor2<T> get() { return Tensor2<T>(0.); }
286};
287
290template <typename T> inline bool is_zero(const Tensor2<T>& v) { return is_zero(v.c00) && is_zero(v.c11); }
291
292/*
293PLASK_API_EXTERN_TEMPLATE_STRUCT(Tensor2<double>)
294PLASK_API_EXTERN_TEMPLATE_STRUCT(Tensor2< std::complex<double> >)
295*/
296
297} // namespace plask
298
299namespace std {
300
301template <typename T> plask::Tensor2<T> sqrt(plask::Tensor2<T> tens) { return tens.sqrt(); }
302
303template <typename T, typename OtherT> plask::Tensor2<T> pow(plask::Tensor2<T> tens, OtherT a) { return tens.pow(a); }
304
305template <typename T> inline bool isnan(plask::Tensor2<T> tens) { return isnan(tens.c00) || isnan(tens.c11); }
306
307} // namespace std
308
309#endif // PLASK__TESNOR2_H