File Complex.h¶
File List > Intern > rayx-core > src > Shader > Complex.h
Go to the documentation of this file
#pragma once
#include <algorithm>
#include <glm.hpp>
#include "Core.h"
#if defined(RAYX_CUDA_ENABLED)
#include <cuda/std/complex>
#else
#include <complex>
#endif
namespace rayx {
namespace complex {
template <typename T>
#if defined(RAYX_CUDA_ENABLED)
using tcomplex = cuda::std::complex<T>;
#else
using tcomplex = std::complex<T>;
#endif
using Complex = tcomplex<double>;
} // namespace complex
using cvec2 = glm::tvec2<complex::Complex>;
using cvec3 = glm::tvec3<complex::Complex>;
using cmat3 = glm::tmat3x3<complex::Complex>;
static_assert(std::is_default_constructible_v<cvec2>);
static_assert(std::is_default_constructible_v<cvec3>);
static_assert(std::is_default_constructible_v<cmat3>);
namespace complex {
#if defined(RAYX_CUDA_ENABLED)
using cuda::std::abs;
using cuda::std::arg;
using cuda::std::conj;
using cuda::std::exp;
using cuda::std::log;
using cuda::std::log10;
using cuda::std::norm;
using cuda::std::polar;
using cuda::std::pow;
using cuda::std::proj;
using cuda::std::real;
using cuda::std::sqrt;
using cuda::std::acos;
using cuda::std::asin;
using cuda::std::atan;
using cuda::std::cos;
using cuda::std::sin;
using cuda::std::tan;
using cuda::std::acosh;
using cuda::std::asinh;
using cuda::std::atanh;
using cuda::std::cosh;
using cuda::std::sinh;
using cuda::std::tanh;
#else
using std::abs;
using std::arg;
using std::conj;
using std::exp;
using std::log;
using std::log10;
using std::norm;
using std::polar;
using std::pow;
using std::proj;
using std::real;
using std::sqrt;
using std::acos;
using std::asin;
using std::atan;
using std::cos;
using std::sin;
using std::tan;
using std::acosh;
using std::asinh;
using std::atanh;
using std::cosh;
using std::sinh;
using std::tanh;
#endif
} // namespace complex
// add some helper function for glm::tvec of complex
namespace complex {
RAYX_FN_ACC
inline glm::dvec2 abs(cvec2 v) { return glm::dvec2(abs(v.x), abs(v.y)); }
RAYX_FN_ACC
inline glm::dvec3 abs(cvec3 v) { return glm::dvec3(abs(v.x), abs(v.y), abs(v.z)); }
RAYX_FN_ACC
inline glm::dvec2 arg(cvec2 v) { return glm::dvec2(arg(v.x), arg(v.y)); }
RAYX_FN_ACC
inline glm::dvec3 arg(cvec3 v) { return glm::dvec3(arg(v.x), arg(v.y), arg(v.z)); }
RAYX_FN_ACC
inline cvec2 polar(glm::dvec2 mag, glm::dvec2 theta) { return cvec2(polar(mag.x, theta.x), polar(mag.y, theta.y)); }
RAYX_FN_ACC
inline cvec3 polar(glm::dvec3 mag, glm::dvec3 theta) { return cvec3(polar(mag.x, theta.x), polar(mag.y, theta.y), polar(mag.z, theta.z)); }
} // namespace complex
} // namespace rayx
namespace glm {
template <typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, rayx::complex::tcomplex<T>, Q> operator*(vec<3, rayx::complex::tcomplex<T>, Q> const& v, T scalar) {
return vec<3, rayx::complex::tcomplex<T>, Q>(v.x * scalar, v.y * scalar, v.z * scalar);
}
template <typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, rayx::complex::tcomplex<T>, Q> operator*(vec<3, T, Q> const& v, rayx::complex::tcomplex<T> scalar) {
return vec<3, rayx::complex::tcomplex<T>, Q>(v.x * scalar, v.y * scalar, v.z * scalar);
}
template <typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, rayx::complex::tcomplex<T>, Q> operator*(vec<3, rayx::complex::tcomplex<T>, Q> const& v,
rayx::complex::tcomplex<T> scalar) {
return vec<3, rayx::complex::tcomplex<T>, Q>(v.x * scalar, v.y * scalar, v.z * scalar);
}
template <typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, rayx::complex::tcomplex<T>, Q> operator*(T scalar, vec<3, rayx::complex::tcomplex<T>, Q> const& v) {
return vec<3, rayx::complex::tcomplex<T>, Q>(scalar * v.x, scalar * v.y, scalar * v.z);
}
template <typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, rayx::complex::tcomplex<T>, Q> operator*(rayx::complex::tcomplex<T> scalar, vec<3, T, Q> const& v) {
return vec<3, rayx::complex::tcomplex<T>, Q>(scalar * v.x, scalar * v.y, scalar * v.z);
}
template <typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<3, rayx::complex::tcomplex<T>, Q> operator*(rayx::complex::tcomplex<T> scalar,
vec<3, rayx::complex::tcomplex<T>, Q> const& v) {
return vec<3, rayx::complex::tcomplex<T>, Q>(scalar * v.x, scalar * v.y, scalar * v.z);
}
template <typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<3, 3, rayx::complex::tcomplex<T>, Q>::col_type operator*(
mat<3, 3, T, Q> const& m, typename mat<3, 3, rayx::complex::tcomplex<T>, Q>::row_type const& v) {
return typename mat<3, 3, rayx::complex::tcomplex<T>, Q>::col_type(
m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z, m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z, m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z);
}
template <typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename mat<3, 3, rayx::complex::tcomplex<T>, Q>::row_type operator*(
typename mat<3, 3, rayx::complex::tcomplex<T>, Q>::col_type const& v, mat<3, 3, T, Q> const& m) {
return typename mat<3, 3, rayx::complex::tcomplex<T>, Q>::row_type(
m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z, m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z, m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z);
}
template <typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, rayx::complex::tcomplex<T>, Q> operator*(mat<3, 3, T, Q> const& m1,
mat<3, 3, rayx::complex::tcomplex<T>, Q> const& m2) {
using namespace rayx::complex;
T const SrcA00 = m1[0][0];
T const SrcA01 = m1[0][1];
T const SrcA02 = m1[0][2];
T const SrcA10 = m1[1][0];
T const SrcA11 = m1[1][1];
T const SrcA12 = m1[1][2];
T const SrcA20 = m1[2][0];
T const SrcA21 = m1[2][1];
T const SrcA22 = m1[2][2];
tcomplex<T> const SrcB00 = m2[0][0];
tcomplex<T> const SrcB01 = m2[0][1];
tcomplex<T> const SrcB02 = m2[0][2];
tcomplex<T> const SrcB10 = m2[1][0];
tcomplex<T> const SrcB11 = m2[1][1];
tcomplex<T> const SrcB12 = m2[1][2];
tcomplex<T> const SrcB20 = m2[2][0];
tcomplex<T> const SrcB21 = m2[2][1];
tcomplex<T> const SrcB22 = m2[2][2];
return mat<3, 3, tcomplex<T>, Q>{
SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02, SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02,
SrcA02 * SrcB00 + SrcA12 * SrcB01 + SrcA22 * SrcB02, SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12,
SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12, SrcA02 * SrcB10 + SrcA12 * SrcB11 + SrcA22 * SrcB12,
SrcA00 * SrcB20 + SrcA10 * SrcB21 + SrcA20 * SrcB22, SrcA01 * SrcB20 + SrcA11 * SrcB21 + SrcA21 * SrcB22,
SrcA02 * SrcB20 + SrcA12 * SrcB21 + SrcA22 * SrcB22,
};
}
template <typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, rayx::complex::tcomplex<T>, Q> operator*(mat<3, 3, rayx::complex::tcomplex<T>, Q> const& m1,
mat<3, 3, T, Q> const& m2) {
using namespace rayx::complex;
tcomplex<T> const SrcA00 = m1[0][0];
tcomplex<T> const SrcA01 = m1[0][1];
tcomplex<T> const SrcA02 = m1[0][2];
tcomplex<T> const SrcA10 = m1[1][0];
tcomplex<T> const SrcA11 = m1[1][1];
tcomplex<T> const SrcA12 = m1[1][2];
tcomplex<T> const SrcA20 = m1[2][0];
tcomplex<T> const SrcA21 = m1[2][1];
tcomplex<T> const SrcA22 = m1[2][2];
T const SrcB00 = m2[0][0];
T const SrcB01 = m2[0][1];
T const SrcB02 = m2[0][2];
T const SrcB10 = m2[1][0];
T const SrcB11 = m2[1][1];
T const SrcB12 = m2[1][2];
T const SrcB20 = m2[2][0];
T const SrcB21 = m2[2][1];
T const SrcB22 = m2[2][2];
return mat<3, 3, tcomplex<T>, Q>{
SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02, SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02,
SrcA02 * SrcB00 + SrcA12 * SrcB01 + SrcA22 * SrcB02, SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12,
SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12, SrcA02 * SrcB10 + SrcA12 * SrcB11 + SrcA22 * SrcB12,
SrcA00 * SrcB20 + SrcA10 * SrcB21 + SrcA20 * SrcB22, SrcA01 * SrcB20 + SrcA11 * SrcB21 + SrcA21 * SrcB22,
SrcA02 * SrcB20 + SrcA12 * SrcB21 + SrcA22 * SrcB22,
};
}
template <typename T, qualifier Q>
GLM_FUNC_QUALIFIER GLM_CONSTEXPR mat<3, 3, rayx::complex::tcomplex<T>, Q> operator*(mat<3, 3, rayx::complex::tcomplex<T>, Q> const& m1,
mat<3, 3, rayx::complex::tcomplex<T>, Q> const& m2) {
using namespace rayx::complex;
tcomplex<T> const SrcA00 = m1[0][0];
tcomplex<T> const SrcA01 = m1[0][1];
tcomplex<T> const SrcA02 = m1[0][2];
tcomplex<T> const SrcA10 = m1[1][0];
tcomplex<T> const SrcA11 = m1[1][1];
tcomplex<T> const SrcA12 = m1[1][2];
tcomplex<T> const SrcA20 = m1[2][0];
tcomplex<T> const SrcA21 = m1[2][1];
tcomplex<T> const SrcA22 = m1[2][2];
tcomplex<T> const SrcB00 = m2[0][0];
tcomplex<T> const SrcB01 = m2[0][1];
tcomplex<T> const SrcB02 = m2[0][2];
tcomplex<T> const SrcB10 = m2[1][0];
tcomplex<T> const SrcB11 = m2[1][1];
tcomplex<T> const SrcB12 = m2[1][2];
tcomplex<T> const SrcB20 = m2[2][0];
tcomplex<T> const SrcB21 = m2[2][1];
tcomplex<T> const SrcB22 = m2[2][2];
return mat<3, 3, tcomplex<T>, Q>{
SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02, SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02,
SrcA02 * SrcB00 + SrcA12 * SrcB01 + SrcA22 * SrcB02, SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12,
SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12, SrcA02 * SrcB10 + SrcA12 * SrcB11 + SrcA22 * SrcB12,
SrcA00 * SrcB20 + SrcA10 * SrcB21 + SrcA20 * SrcB22, SrcA01 * SrcB20 + SrcA11 * SrcB21 + SrcA21 * SrcB22,
SrcA02 * SrcB20 + SrcA12 * SrcB21 + SrcA22 * SrcB22,
};
}
} // namespace glm