.. _program_listing_file_src_utilities.hpp: Program Listing for File utilities.hpp ====================================== |exhale_lsh| :ref:`Return to documentation for file ` (``src/utilities.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp /* This file is part of brille. Copyright © 2019,2020 Greg Tucker brille is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. brille is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with brille. If not, see . */ #ifndef BRILLE_UTILITIES_HPP_ #define BRILLE_UTILITIES_HPP_ #include #include #include #include // for std::overflow_error #include #include #include #include #include "debug.hpp" #include "approx.hpp" namespace brille{ const double pi = 3.14159265358979323846; const double halfpi = 1.57079632679489661923; // const double quarterpi = 0.785398163397448309616; // const double inversepi = 0.318309886183790671538; // const double twooverpi = 0.636619772367581343076; // const double twooversqrtpi = 1.12837916709551257390; // const double sqrttwo = 1.41421356237309504880; // const double sqrttwoovertwo = 0.707106781186547524401; // const double e = 2.71828182845904523536; // const double log2e = 1.44269504088896340736; // const double log10e = 0.434294481903251827651; // const double ln2 = 0.693147180559945309417; // const double ln10 = 2.30258509299404568402; namespace utils{ template T trace(const T *M); template void copy_array(T *D, const T *S); template void copy_matrix(T *M, const T *A); template void copy_vector(T *V, const T *A); template bool equal_array(const T *A, const T *B, const T tol=0); template bool equal_matrix(const T *A, const T *B, const T tol=0); template bool equal_vector(const T *A, const T *B, const T tol=0); template void multiply_arrays(T *C, const R *A, const S *B); template void multiply_matrix_matrix(T *C, const R *A, const S *B); template void multiply_matrix_vector(T *C, const R *A, const S *b); template void multiply_vector_matrix(T *C, const R *a, const S *B); // array multiplication with specializations for complex array type(s) template void mul_arrays(T* C, const I n, const I l, const I m, const R* A, const S* B); template void mul_arrays(std::complex* C, const I n, const I l, const I m, const R* A, const std::complex* B); template void mul_arrays(std::complex* C, const I n, const I l, const I m, const std::complex* A, const S* B); template void mul_arrays(std::complex* C, const I n, const I l, const I m, const std::complex* A, const std::complex* B); // specializations for matrix*matrix, matrix*vector, and vector*matrix template void mul_mat_mat(T* C, const I n, const R* A, const S* B){ mul_arrays(C, n, n, n, A, B);} template void mul_mat_vec(T* C, const I n, const R* A, const S* B){ mul_arrays(C, n, n, I(1), A, B);} template void mul_vec_mat(T* C, const I n, const R* A, const S* B){ mul_arrays(C, I(1), n, n, A, B);} // template> // std::enable_if_t&&std::is_same_v> // mul_mat_vec_inplace(const I n, const T* A, R* B){ // S* C = new S[n](); // mul_arrays(C, n, n, I(1), A, B); // for (I i=0; i> std::enable_if_t> mul_mat_vec_inplace(const I n, const T* A, R* B){ S* C = new S[n](); mul_arrays(C, n, n, I(1), A, B); //for (I i=0; i void add_arrays(T *C, const R *A, const S *B); template void add_matrix(T *C, const R *A, const S *B); template void subtract_arrays(T *C, const R *A, const S *B); template void subtract_matrix(T *C, const R *A, const S *B); template T my_cast(const R a); template void cast_array(T *A, const R *B); template void cast_matrix(T *A, const R *B); template void cast_vector(T *A, const R *B); template void array_cofactor(R *C, const R *A, const int i, const int j, const int N=3, const int M=3); template void matrix_cofactor(R *C, const R *A, const int i, const int j, const int N=3); template R matrix_determinant(const R *M, const int N=3); template void matrix_adjoint(R *A, const R *M, const int N=3); template R matrix_determinant_and_inverse(R *invM, const R *M, const R tol=0, const int N=3); template bool matrix_inverse(R *invM, const R *M, R tol=0, const int N=3); template bool similar_matrix(T *M, const T *A, const T *B, const T tol=0); template void array_transpose(R *D, const R *S); template void matrix_transpose(R *D, const R *S); template void matrix_transpose(R *B); template void matrix_metric(R *M, const R *L); template R vector_norm_squared(const R * v); template class vector_cross_impl { public: static void vector_cross(T*, const R*, const S*) { throw std::runtime_error("The cross product is only defined for 3-vectors"); } }; template class vector_cross_impl{ public: static void vector_cross(T * c, const R * a, const S * b) { c[0] = static_cast(a[1])* static_cast(b[2]) - static_cast(a[2])* static_cast(b[1]); c[1] = static_cast(a[2])* static_cast(b[0]) - static_cast(a[0])* static_cast(b[2]); c[2] = static_cast(a[0])* static_cast(b[1]) - static_cast(a[1])* static_cast(b[0]); } }; template void vector_cross(T* c, const R* a, const S* b) { vector_cross_impl::vector_cross(c, a, b); } template S vector_dot(const size_t, const T* a, const R* b); template R vector_dot(const R *a, const R *b); template T mod1(const T a); template bool is_int_matrix(const T * A, const R tol); template bool is_int_matrix(const int *, const R); template T frobenius_distance(const I n, const T* A, const T* B); template T frobenius_distance(const I n, const std::complex* A, const std::complex* B); template T vector_angle(const I n, const T* A, const T* B); template T vector_angle(const I n, const std::complex* A, const std::complex* B); template T euclidean_angle(const I n, const std::complex* A, const std::complex* B); template T hermitian_angle(const I n, const std::complex* A, const std::complex* B); template T hermitian_angle(const I n, const T* A, const T* B); template T hermitian_product(const I n, const T* a, const T* b); template std::complex hermitian_product(const I n, const T* a, const std::complex* b); template std::complex hermitian_product(const I n, const std::complex* a, const T* b); template std::complex hermitian_product(const I n, const std::complex* a, const std::complex* b); template T vector_distance(const I n, const T* a, const T* b); template T vector_distance(const I n, const std::complex* a, const std::complex* b); template T vector_product(const I n, const T* a, const T* b); template T vector_product(const I n, const T* a, const std::complex* b); template T vector_product(const I n, const std::complex* a, const T* b); template T vector_product(const I n, const std::complex* a, const std::complex* b); template T inner_product(const I n, const T* a, const T* b); template T inner_product(const I n, const std::complex* a, const std::complex* b); template T squared_distance(const T&A, const T& B); template T squared_distance(const std::complex& A, const std::complex& B); template T magnitude(const T a); template T magnitude(const std::complex a); template size_t encode_array_signs(const size_t n, const T* a); template size_t encode_array_signs(const size_t n, const std::complex* a); template int make_eigenvectors_equivalent(const size_t n, const T* v0, T* v1); template int make_eigenvectors_equivalent(const size_t n, const std::complex* v0, std::complex v1); template enable_if_t::value&&std::is_unsigned::value, unsigned long long> binomial_coefficient(const T n, const R k); template S u2s(const U u); template U s2u(const S s); #include "utilities.tpp" } // namespace utils } // namespace brille #endif