From e6e9fe102688c3affc68b29a36ca1cd0f9da15ad Mon Sep 17 00:00:00 2001 From: Michelle Date: Wed, 29 Jul 2026 21:28:29 +0200 Subject: [PATCH] max.hpp is done --- include/math/clip.hpp | 712 ++++++++++ include/math/exp.hpp | 145 ++ include/math/max.hpp | 159 +++ include/math/maximum.hpp | 353 ----- main.cpp | 8 +- src/math/clip.cpp | 1233 +++++++++++++++++ src/math/exp.cpp | 298 ++++ src/math/max.cpp | 339 +++++ src/math/maximum.cpp | 638 --------- .../activation/activation_ReLU.cpp | 4 +- 10 files changed, 2893 insertions(+), 996 deletions(-) create mode 100644 include/math/clip.hpp create mode 100644 include/math/exp.hpp create mode 100644 include/math/max.hpp delete mode 100644 include/math/maximum.hpp create mode 100644 src/math/clip.cpp create mode 100644 src/math/exp.cpp create mode 100644 src/math/max.cpp delete mode 100644 src/math/maximum.cpp diff --git a/include/math/clip.hpp b/include/math/clip.hpp new file mode 100644 index 0000000..45ef87d --- /dev/null +++ b/include/math/clip.hpp @@ -0,0 +1,712 @@ +/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * + * + * PANIC + * Portable Algorithms and Numerics In C++ + * + * Scientific computing from scratch, with feeling. + * + * Copyright (c) 2026 Michelle Bausager + * + * This file is part of PANIC. + * + * PANIC is free software licensed under the GNU General Public License v3.0 or later. + * You may redistribute and/or modify it under the terms of the GPL. + * + * PANIC 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 LICENSE file for the full license text. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * + * Project Name: PANIC + * Module Name: math + * File Name: clip.hpp + * Revision: 0.1.0 + * Date: 29-07-2026 + * Author: Michelle Bausager + * + * Description: + * Functions that clips the value + * + *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +#pragma once + +#include // for panic::vector +#include // for panic::matrix + +namespace panic{ +namespace math{ + + +/** + * @brief Clips the max values in the vector or scalar. + * + * Computes: + * @code + * if (a[i] < k) + * c[i] = k + * else + * c[i] = a[i] + * @endcode + * + * @tparam T Numeric element type. + * @param a Input vector. + * @param k Scalar value compared to each element of @p a. + * @param c Output vector. Resized to match @p a. + * + * @return true if @p c was resized and filled successfully. + * @return false if resizing @p c failed. + * + * @note This overload writes the result into an existing vector to avoid + * unnecessary temporary allocations. + */ +template +bool clip_lower(const panic::tensor::vector& a, const T k, panic::tensor::vector& c); + +/** + * @brief Returns a cliped max value in the vector. + * + * Computes: + * @code + * if (a[i] < k) + * result[i] = k + * else + * result[i] = a[i] + * @endcode + * + * @tparam T Numeric element type. + * @param a Input vector. + * @param k Scalar value compared to each element of @p a. + * + * @return A new vector containing the result. + * @return An empty vector if the operation fails. + * + * @note This overload is convenient, but may allocate a new vector. + */ +template +panic::tensor::vector clip_lower(const panic::tensor::vector& a, const T k); + + + +/** + * @brief Clips the max elementwise in the vector. + * + * Computes: + * @code + * if (a[i] < b[i]) + * c[i] = b[i] + * else + * c[i] = a[i] + * @endcode + * + * @tparam T Numeric element type. + * @param a First vector. + * @param b Second vector. Must have size of @p a + * @param c Output vector. Resized to match @p a. + * + * @return true if @p c was resized and filled successfully. + * @return false if vector sizes do not match or resizing @p c failed. + */ +template +bool clip_lower(const panic::tensor::vector& a, const panic::tensor::vector& b, panic::tensor::vector& c); + +/** + * @brief Returns a new vector containing cliped max elementwise of a vector. + * + * Computes: + * @code + * if (a[i] < b[i]) + * result[i] = b[i] + * else + * result[i] = a[i] + * @endcode + * + * @tparam T Numeric element type. + * @param a First vector. + * @param b Second vector. Must have size of @p a + * + * @return A new vector containing the result. + * @return An empty vector if the operation fails. + * + * @note This overload is convenient, but may allocate a new vector. + */ +template +panic::tensor::vector clip_lower(const panic::tensor::vector& a, const panic::tensor::vector& b); + + + + + + + +/** + * @brief Clips the max elementwise in the matrix. + * + * Computes: + * @code + * if (A(i,j) < k) + * C(i,j) = k + * else + * C(i,j) = A(i,j) + * @endcode + * + * @tparam T Numeric element type. + * @param A Input matrix. + * @param k Scalar value compared to each element of @p a. + * @param C Output Matrix. Resized to match @p A. + * + * @return true if @p C was resized and filled successfully. + * @return false if resizing @p C failed. + * + * @note This overload writes the result into an existing matrix to avoid + * unnecessary temporary allocations. + */ +template +bool clip_lower(const panic::tensor::matrix& A, const T k, panic::tensor::matrix& C); + +/** + * @brief Returns a new matrix containing the cliped max elementwise in the matrix. + * + * Computes: + * @code + * if (A(i,j) < k) + * result(i,j) = k + * else + * result(i,j) = A(i,j) + * @endcode + * + * @tparam T Numeric element type. + * @param A Input matrix. + * @param k Scalar value compared to each element of @p a. + * + * @return A new matrix containing the result. + * @return An empty matrix if the operation fails. + * + * @note This overload is convenient, but may allocate a new matrix. + */ +template +panic::tensor::matrix clip_lower(const panic::tensor::matrix& A, const T k); + +/** + * @brief Clips the max of a matrix elementwise too a matrix. + * + * Computes: + * @code + * if (A(i,j) < B(i,j)) + * C(i,j) = B(i,j) + * else + * C(i,j) = A(i,j) + * @endcode + * + * @tparam T Numeric element type. + * @param A First matrix. + * @param B Second matrix. Must have size of @p A. + * @param C Output matrix. Resized to match @p A. + * + * @return true if @p C was resized and filled successfully. + * @return false if matrix sizes do not match or resizing @p c failed. + */ +template +bool clip_lower(const panic::tensor::matrix& A, const panic::tensor::matrix& B, panic::tensor::matrix& C); + +/** + * @brief Returns a new matrix containing a matrix elementwise cliped to the maixmum. + * + * Computes: + * @code + * if (A(i,j) < B(i,j)) + * result(i,j) = B(i,j) + * else + * result(i,j) = A(i,j) + * @endcode + * + * @tparam T Numeric element type. + * @param A Input matrix. + * @param B Second matrix. Must have size of @p A. + * + * @return A new matrix containing the result. + * @return An empty matrix if the operation fails. + * + * @note This overload is convenient, but may allocate a new matrix. + */ +template +panic::tensor::matrix clip_lower(const panic::tensor::matrix& A, const panic::tensor::matrix& B); + +/** + * @brief Clips the max of a vector rowwise too a matrix. + * + * Computes: + * @code + * if (A(i,j) < b[j]) + * C(i,j) = b[j]) + * else + * C(i,j) = A(i,j) + * @endcode + * + * @tparam T Numeric element type. + * @param A Matrix. + * @param b Vector. Must have size of @p A.cols(). + * @param C Output matrix. Resized to match @p A. + * + * @return true if @p C was resized and filled successfully. + * @return false if matrix sizes do not match or resizing @p c failed. + */ +template +bool clip_lower_rowwise(const panic::tensor::matrix& A, const panic::tensor::vector& b, panic::tensor::matrix& C); + +/** + * @brief Returns a new matrix containing a vector rowwise cliped to the maixmum. + * + * Computes: + * @code + * if (A(i,j) < b[j]) + * result(i,j) = b[j]) + * else + * result(i,j) = A(i,j) + * @endcode + * + * @tparam T Numeric element type. + * @param A Matrix. + * @param b Vector. Must have size of @p A.cols(). + * + * @return A new matrix containing the result. + * @return An empty matrix if the operation fails. + * + * @note This overload is convenient, but may allocate a new vector. + */ +template +panic::tensor::matrix clip_lower_rowwise(const panic::tensor::matrix& A, const panic::tensor::vector& b); + +/** + * @brief Clips the max of a vector rowwise too a matrix. + * + * Computes: + * @code + * if (A(i,j) < b[i]) + * C(i,j) = b[i]) + * else + * C(i,j) = A(i,j) + * @endcode + * + * @tparam T Numeric element type. + * @param A Matrix. + * @param b Vector. Must have size of @p A.rows(). + * @param C Output matrix. Resized to match @p A. + * + * @return true if @p C was resized and filled successfully. + * @return false if matrix sizes do not match or resizing @p c failed. + */ +template +bool clip_lower_colwise(const panic::tensor::matrix& A, const panic::tensor::vector& b, panic::tensor::matrix& C); + +/** + * @brief Returns a new matrix containing a vector rowwise cliped to the maixmum. + * + * Computes: + * @code + * if (A(i,j) < b[i]) + * result(i,j) = b[i]) + * else + * result(i,j) = A(i,j) + * @endcode + * + * @tparam T Numeric element type. + * @param A Matrix. + * @param b Vector. Must have size of @p A.rows(). + * + * @return A new matrix containing the result. + * @return An empty matrix if the operation fails. + * + * @note This overload is convenient, but may allocate a new vector. + */ +template +panic::tensor::matrix clip_lower_colwise(const panic::tensor::matrix& A, const panic::tensor::vector& b); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +/** + * @brief Clips the min values in the vector or scalar. + * + * Computes: + * @code + * if (a[i] > k) + * c[i] = k + * else + * c[i] = a[i] + * @endcode + * + * @tparam T Numeric element type. + * @param a Input vector. + * @param k Scalar value compared to each element of @p a. + * @param c Output vector. Resized to match @p a. + * + * @return true if @p c was resized and filled successfully. + * @return false if resizing @p c failed. + * + * @note This overload writes the result into an existing vector to avoid + * unnecessary temporary allocations. + */ +template +bool clip_higher(const panic::tensor::vector& a, const T k, panic::tensor::vector& c); + +/** + * @brief Returns a cliped min value in the vector. + * + * Computes: + * @code + * if (a[i] > k) + * result[i] = k + * else + * result[i] = a[i] + * @endcode + * + * @tparam T Numeric element type. + * @param a Input vector. + * @param k Scalar value compared to each element of @p a. + * + * @return A new vector containing the result. + * @return An empty vector if the operation fails. + * + * @note This overload is convenient, but may allocate a new vector. + */ +template +panic::tensor::vector clip_higher(const panic::tensor::vector& a, const T k); + + + +/** + * @brief Clips the min elementwise in the vector. + * + * Computes: + * @code + * if (a[i] > b[i]) + * c[i] = b[i] + * else + * c[i] = a[i] + * @endcode + * + * @tparam T Numeric element type. + * @param a First vector. + * @param b Second vector. Must have size of @p a + * @param c Output vector. Resized to match @p a. + * + * @return true if @p c was resized and filled successfully. + * @return false if vector sizes do not match or resizing @p c failed. + */ +template +bool clip_higher(const panic::tensor::vector& a, const panic::tensor::vector& b, panic::tensor::vector& c); + +/** + * @brief Returns a new vector containing cliped min elementwise of a vector. + * + * Computes: + * @code + * if (a[i] > b[i]) + * result[i] = b[i] + * else + * result[i] = a[i] + * @endcode + * + * @tparam T Numeric element type. + * @param a First vector. + * @param b Second vector. Must have size of @p a + * + * @return A new vector containing the result. + * @return An empty vector if the operation fails. + * + * @note This overload is convenient, but may allocate a new vector. + */ +template +panic::tensor::vector clip_higher(const panic::tensor::vector& a, const panic::tensor::vector& b); + + + + + + + +/** + * @brief Clips the min elementwise in the matrix. + * + * Computes: + * @code + * if (A(i,j) > k) + * C(i,j) = k + * else + * C(i,j) = A(i,j) + * @endcode + * + * @tparam T Numeric element type. + * @param A Input matrix. + * @param k Scalar value compared to each element of @p a. + * @param C Output Matrix. Resized to match @p A. + * + * @return true if @p C was resized and filled successfully. + * @return false if resizing @p C failed. + * + * @note This overload writes the result into an existing matrix to avoid + * unnecessary temporary allocations. + */ +template +bool clip_higher(const panic::tensor::matrix& A, const T k, panic::tensor::matrix& C); + +/** + * @brief Returns a new matrix containing the cliped min elementwise in the matrix. + * + * Computes: + * @code + * if (A(i,j) > k) + * result(i,j) = k + * else + * result(i,j) = A(i,j) + * @endcode + * + * @tparam T Numeric element type. + * @param A Input matrix. + * @param k Scalar value compared to each element of @p a. + * + * @return A new matrix containing the result. + * @return An empty matrix if the operation fails. + * + * @note This overload is convenient, but may allocate a new matrix. + */ +template +panic::tensor::matrix clip_higher(const panic::tensor::matrix& A, const T k); + +/** + * @brief Clips the min of a matrix elementwise too a matrix. + * + * Computes: + * @code + * if (A(i,j) > B(i,j)) + * C(i,j) = B(i,j) + * else + * C(i,j) = A(i,j) + * @endcode + * + * @tparam T Numeric element type. + * @param A First matrix. + * @param B Second matrix. Must have size of @p A. + * @param C Output matrix. Resized to match @p A. + * + * @return true if @p C was resized and filled successfully. + * @return false if matrix sizes do not match or resizing @p c failed. + */ +template +bool clip_higher(const panic::tensor::matrix& A, const panic::tensor::matrix& B, panic::tensor::matrix& C); + +/** + * @brief Returns a new matrix containing a matrix elementwise cliped to the maixmum. + * + * Computes: + * @code + * if (A(i,j) > B(i,j)) + * result(i,j) = B(i,j) + * else + * result(i,j) = A(i,j) + * @endcode + * + * @tparam T Numeric element type. + * @param A Input matrix. + * @param B Second matrix. Must have size of @p A. + * + * @return A new matrix containing the result. + * @return An empty matrix if the operation fails. + * + * @note This overload is convenient, but may allocate a new matrix. + */ +template +panic::tensor::matrix clip_higher(const panic::tensor::matrix& A, const panic::tensor::matrix& B); + +/** + * @brief Clips the min of a vector rowwise too a matrix. + * + * Computes: + * @code + * if (A(i,j) > b[j]) + * C(i,j) = b[j]) + * else + * C(i,j) = A(i,j) + * @endcode + * + * @tparam T Numeric element type. + * @param A Matrix. + * @param b Vector. Must have size of @p A.cols(). + * @param C Output matrix. Resized to match @p A. + * + * @return true if @p C was resized and filled successfully. + * @return false if matrix sizes do not match or resizing @p c failed. + */ +template +bool clip_higher_rowwise(const panic::tensor::matrix& A, const panic::tensor::vector& b, panic::tensor::matrix& C); + +/** + * @brief Returns a new matrix containing a vector rowwise cliped to the minimum. + * + * Computes: + * @code + * if (A(i,j) > b[j]) + * result(i,j) = b[j]) + * else + * result(i,j) = A(i,j) + * @endcode + * + * @tparam T Numeric element type. + * @param A Matrix. + * @param b Vector. Must have size of @p A.cols(). + * + * @return A new matrix containing the result. + * @return An empty matrix if the operation fails. + * + * @note This overload is convenient, but may allocate a new vector. + */ +template +panic::tensor::matrix clip_higher_rowwise(const panic::tensor::matrix& A, const panic::tensor::vector& b); + +/** + * @brief Clips the min of a vector columnwise too a matrix. + * + * Computes: + * @code + * if (A(i,j) > b[i]) + * C(i,j) = b[i]) + * else + * C(i,j) = A(i,j) + * @endcode + * + * @tparam T Numeric element type. + * @param A Matrix. + * @param b Vector. Must have size of @p A.rows(). + * @param C Output matrix. Resized to match @p A. + * + * @return true if @p C was resized and filled successfully. + * @return false if matrix sizes do not match or resizing @p c failed. + */ +template +bool clip_higher_colwise(const panic::tensor::matrix& A, const panic::tensor::vector& b, panic::tensor::matrix& C); + +/** + * @brief Returns a new matrix containing a vector column-wise cliped to the minimum. + * + * Computes: + * @code + * if (A(i,j) > b[i]) + * result(i,j) = b[i]) + * else + * result(i,j) = A(i,j) + * @endcode + * + * @tparam T Numeric element type. + * @param A Matrix. + * @param b Vector. Must have size of @p A.rows(). + * + * @return A new matrix containing the result. + * @return An empty matrix if the operation fails. + * + * @note This overload is convenient, but may allocate a new vector. + */ +template +panic::tensor::matrix clip_higher_colwise(const panic::tensor::matrix& A, const panic::tensor::vector& b); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} // namespace math +} // namespace panic \ No newline at end of file diff --git a/include/math/exp.hpp b/include/math/exp.hpp new file mode 100644 index 0000000..75269c6 --- /dev/null +++ b/include/math/exp.hpp @@ -0,0 +1,145 @@ +/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * + * + * PANIC + * Portable Algorithms and Numerics In C++ + * + * Scientific computing from scratch, with feeling. + * + * Copyright (c) 2026 Michelle Bausager + * + * This file is part of PANIC. + * + * PANIC is free software licensed under the GNU General Public License v3.0 or later. + * You may redistribute and/or modify it under the terms of the GPL. + * + * PANIC 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 LICENSE file for the full license text. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * + * Project Name: PANIC + * Module Name: math + * File Name: exp.hpp + * Revision: 0.1.0 + * Date: 29-07-2026 + * Author: Michelle Bausager + * + * Description: + * Functions to calculate the exponential of numbers + * + *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +#pragma once + +#include // for panic::vector +#include // for panic::matrix + +namespace panic{ +namespace math{ + + + +/** + * @brief calculates the exponential of a value. + * + * Computes: + * @code + * result = exp(k) + * @endcode + * + * @tparam T Numeric element type. + * @param k Value to take the exp of. + * + * @return The calculated value + * + * @note This function is omp-friendly. + */ +template +T exp(const T x); + + +/** + * @brief Calculates the exponential elementwise in a vector + * + * Computes: + * @code + * c[i] = exp(a[i]) + * @endcode + * + * @tparam T Numeric element type. + * @param a Input vector. + * @param c Output vector. Resized to match @p a. + * + * @return true if @p c was resized and filled successfully. + * @return false if resizing @p c failed. + * + * @note This overload writes the result into an existing vector to avoid + * unnecessary temporary allocations. + */ +template +bool exp(const panic::tensor::vector& a, panic::tensor::vector& c); + +/** + * @brief Calculates the exponential elementwise in a vector + * + * Computes: + * @code + * result[i] = exp(a[i]) + * @endcode + * + * @tparam T Numeric element type. + * @param a Input vector. + * + * @return A new vector containing the result. + * @return An empty vector if the operation fails. + * + * @note This overload is convenient, but may allocate a new vector. + */ +template +panic::tensor::vector add(const panic::tensor::vector& a); + +/** + * @brief Calculates the expnential elementwise of a matrix + * + * Computes: + * @code + * C(i,j) = exp(A(i,j)) + * @endcode + * + * @tparam T Numeric element type. + * @param A Input matrix. + * @param C Output Matrix. Resized to match @p A. + * + * @return true if @p C was resized and filled successfully. + * @return false if resizing @p C failed. + * + * @note This overload writes the result into an existing vector to avoid + * unnecessary temporary allocations. + */ +template +bool exp(const panic::tensor::matrix& A, panic::tensor::matrix& C); + +/** + * @brief Returns the calculated ecponential elementwise of the matrix + * + * Computes: + * @code + * result(i,j) = exp(A(i,j)) + * @endcode + * + * @tparam T Numeric element type. + * @param A Input matrix. + * + * @return A new matrix containing the result. + * @return An empty matrix if the operation fails. + * + * @note This overload is convenient, but may allocate a new vector. + */ +template +panic::tensor::matrix exp(const panic::tensor::matrix& A); + +} // namespace math +} // namespace panic \ No newline at end of file diff --git a/include/math/max.hpp b/include/math/max.hpp new file mode 100644 index 0000000..5565f9b --- /dev/null +++ b/include/math/max.hpp @@ -0,0 +1,159 @@ +/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * + * + * PANIC + * Portable Algorithms and Numerics In C++ + * + * Scientific computing from scratch, with feeling. + * + * Copyright (c) 2026 Michelle Bausager + * + * This file is part of PANIC. + * + * PANIC is free software licensed under the GNU General Public License v3.0 or later. + * You may redistribute and/or modify it under the terms of the GPL. + * + * PANIC 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 LICENSE file for the full license text. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * + * Project Name: PANIC + * Module Name: math + * File Name: max.hpp + * Revision: 0.1.0 + * Date: 29-07-2026 + * Author: Michelle Bausager + * + * Description: + * Functions to find the maximum value; + * + *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +#pragma once + +#include // for panic::vector +#include // for panic::matrix + +namespace panic{ +namespace math{ + + + + +/** + * @brief Returns the maximum value of a vector + * + * Computes: + * @code + * result = max(a) + * @endcode + * + * @tparam T Numeric element type. + * @param a Input vector. + * + * @return A new vector containing the result. + * @return An empty vector if the operation fails. + * + * @note This overload is convenient, but may allocate a new vector. + */ +template +T max(const panic::tensor::vector& a); + +/** + * @brief Returns the maximum value of a matrix. + * + * Computes: + * @code + * result = max(A) + * @endcode + * + * @tparam T Numeric element type. + * @param A Input matrix. + * + * @return A new matrix containing the result. + * @return An empty matrix if the operation fails. + * + */ +template +T max(const panic::tensor::matrix& A); + +/** + * @brief Find the maximum values row-wise of a matrix. + * + * Computes: + * @code + * C(i) = max(A(i,j)) + * @endcode + * + * @tparam T Numeric element type. + * @param A Input matrix. + * @param C Output matrix. Resized to match @p A.cols(). + * + * @return true if @p c was resized and filled successfully. + * @return false if vector sizes do not match or resizing @p c failed. + */ +template +bool max_rowwise(const panic::tensor::matrix& A, panic::tensor::vector& c); + +/** + * @brief Returns a new matrix containing the maiximum row-wise elementwise. + * + * Computes: + * @code + * result[i] = max(A(i,j)) + * @endcode + * + * @tparam T Numeric element type. + * @param A Input matrix. + * + * @return A new matrix containing the result. + * @return An empty matrix if the operation fails. + * + * @note This overload is convenient, but may allocate a new vector. + */ +template +panic::tensor::vector max_rowwise(const panic::tensor::matrix& A); + + +/** + * @brief Find the maximum values column-wise of a matrix. + * + * Computes: + * @code + * C(j) = max(A(i,j)) + * @endcode + * + * @tparam T Numeric element type. + * @param A Input matrix. + * @param C Output matrix. Resized to match @p A.rows(). + * + * @return true if @p c was resized and filled successfully. + * @return false if vector sizes do not match or resizing @p c failed. + */ +template +bool max_colwise(const panic::tensor::matrix& A, panic::tensor::vector& c); + +/** + * @brief Returns a new matrix containing the maiximum column-wise elementwise. + * + * Computes: + * @code + * result[j] = max(A(i,j)) + * @endcode + * + * @tparam T Numeric element type. + * @param A Input matrix. + * + * @return A new matrix containing the result. + * @return An empty matrix if the operation fails. + * + * @note This overload is convenient, but may allocate a new vector. + */ +template +panic::tensor::vector max_colwise(const panic::tensor::matrix& A); + +} // namespace math +} // namespace panic \ No newline at end of file diff --git a/include/math/maximum.hpp b/include/math/maximum.hpp deleted file mode 100644 index 1892614..0000000 --- a/include/math/maximum.hpp +++ /dev/null @@ -1,353 +0,0 @@ -/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * - * PANIC - * Portable Algorithms and Numerics In C++ - * - * Scientific computing from scratch, with feeling. - * - * Copyright (c) 2026 Michelle Bausager - * - * This file is part of PANIC. - * - * PANIC is free software licensed under the GNU General Public License v3.0 or later. - * You may redistribute and/or modify it under the terms of the GPL. - * - * PANIC 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 LICENSE file for the full license text. - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * Project Name: PANIC - * Module Name: math - * File Name: maximum.hpp - * Revision: 0.1.0 - * Date: 29-07-2026 - * Author: Michelle Bausager - * - * Description: - * Functions that finds the maximum - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -#pragma once - -#include // for panic::vector -#include // for panic::matrix - -namespace panic{ -namespace math{ - - -/** - * @brief Clips the maximum values in the vector or scalar. - * - * Computes: - * @code - * if (a[i] < k) - * c[i] = k - * else - * c[i] = a[i] - * @endcode - * - * @tparam T Numeric element type. - * @param a Input vector. - * @param k Scalar value compared to each element of @p a. - * @param c Output vector. Resized to match @p a. - * - * @return true if @p c was resized and filled successfully. - * @return false if resizing @p c failed. - * - * @note This overload writes the result into an existing vector to avoid - * unnecessary temporary allocations. - */ -template -bool maximum(const panic::tensor::vector& a, const T k, panic::tensor::vector& c); - -/** - * @brief Returns a cliped maximum value in the vector. - * - * Computes: - * @code - * if (a[i] < k) - * result[i] = k - * else - * result[i] = a[i] - * @endcode - * - * @tparam T Numeric element type. - * @param a Input vector. - * @param k Scalar value compared to each element of @p a. - * - * @return A new vector containing the result. - * @return An empty vector if the operation fails. - * - * @note This overload is convenient, but may allocate a new vector. - */ -template -panic::tensor::vector maximum(const panic::tensor::vector& a, const T k); - - - -/** - * @brief Clips the maximum elementwise in the vector. - * - * Computes: - * @code - * if (a[i] < b[i]) - * c[i] = b[i] - * else - * c[i] = a[i] - * @endcode - * - * @tparam T Numeric element type. - * @param a First vector. - * @param b Second vector. Must have size of @p a - * @param c Output vector. Resized to match @p a. - * - * @return true if @p c was resized and filled successfully. - * @return false if vector sizes do not match or resizing @p c failed. - */ -template -bool maximum(const panic::tensor::vector& a, const panic::tensor::vector& b, panic::tensor::vector& c); - -/** - * @brief Returns a new vector containing cliped maximum elementwise of a vector. - * - * Computes: - * @code - * if (a[i] < b[i]) - * result[i] = b[i] - * else - * result[i] = a[i] - * @endcode - * - * @tparam T Numeric element type. - * @param a First vector. - * @param b Second vector. Must have size of @p a - * - * @return A new vector containing the result. - * @return An empty vector if the operation fails. - * - * @note This overload is convenient, but may allocate a new vector. - */ -template -panic::tensor::vector maximum(const panic::tensor::vector& a, const panic::tensor::vector& b); - - - - - - - -/** - * @brief Clips the maximum elementwise in the matrix. - * - * Computes: - * @code - * if (A(i,j) < k) - * C(i,j) = k - * else - * C(i,j) = A(i,j) - * @endcode - * - * @tparam T Numeric element type. - * @param A Input matrix. - * @param k Scalar value compared to each element of @p a. - * @param C Output Matrix. Resized to match @p A. - * - * @return true if @p C was resized and filled successfully. - * @return false if resizing @p C failed. - * - * @note This overload writes the result into an existing matrix to avoid - * unnecessary temporary allocations. - */ -template -bool maximum(const panic::tensor::matrix& A, const T k, panic::tensor::matrix& C); - -/** - * @brief Returns a new matrix containing the cliped maximum elementwise in the matrix. - * - * Computes: - * @code - * if (A(i,j) < k) - * result(i,j) = k - * else - * result(i,j) = A(i,j) - * @endcode - * - * @tparam T Numeric element type. - * @param A Input matrix. - * @param k Scalar value compared to each element of @p a. - * - * @return A new matrix containing the result. - * @return An empty matrix if the operation fails. - * - * @note This overload is convenient, but may allocate a new matrix. - */ -template -panic::tensor::matrix maximum(const panic::tensor::matrix& A, const T k); - -/** - * @brief Clips the maximum of a matrix elementwise too a matrix. - * - * Computes: - * @code - * if (A(i,j) < B(i,j)) - * C(i,j) = B(i,j) - * else - * C(i,j) = A(i,j) - * @endcode - * - * @tparam T Numeric element type. - * @param A First matrix. - * @param B Second matrix. Must have size of @p A. - * @param C Output matrix. Resized to match @p A. - * - * @return true if @p C was resized and filled successfully. - * @return false if matrix sizes do not match or resizing @p c failed. - */ -template -bool maximum(const panic::tensor::matrix& A, const panic::tensor::matrix& B, panic::tensor::matrix& C); - -/** - * @brief Returns a new matrix containing a matrix elementwise cliped to the maixmum. - * - * Computes: - * @code - * if (A(i,j) < B(i,j)) - * result(i,j) = B(i,j) - * else - * result(i,j) = A(i,j) - * @endcode - * - * @tparam T Numeric element type. - * @param A Input matrix. - * @param B Second matrix. Must have size of @p A. - * - * @return A new matrix containing the result. - * @return An empty matrix if the operation fails. - * - * @note This overload is convenient, but may allocate a new matrix. - */ -template -panic::tensor::matrix maximum(const panic::tensor::matrix& A, const panic::tensor::matrix& B); - -/** - * @brief Clips the maximum of a vector rowwise too a matrix. - * - * Computes: - * @code - * if (A(i,j) < b[j]) - * C(i,j) = b[j]) - * else - * C(i,j) = A(i,j) - * @endcode - * - * @tparam T Numeric element type. - * @param A Matrix. - * @param b Vector. Must have size of @p A.cols(). - * @param C Output matrix. Resized to match @p A. - * - * @return true if @p C was resized and filled successfully. - * @return false if matrix sizes do not match or resizing @p c failed. - */ -template -bool maximum_rowwise(const panic::tensor::matrix& A, const panic::tensor::vector& b, panic::tensor::matrix& C); - -/** - * @brief Returns a new matrix containing a vector rowwise cliped to the maixmum. - * - * Computes: - * @code - * if (A(i,j) < b[j]) - * result(i,j) = b[j]) - * else - * result(i,j) = A(i,j) - * @endcode - * - * @tparam T Numeric element type. - * @param A Matrix. - * @param b Vector. Must have size of @p A.cols(). - * - * @return A new matrix containing the result. - * @return An empty matrix if the operation fails. - * - * @note This overload is convenient, but may allocate a new vector. - */ -template -panic::tensor::matrix maximum_rowwise(const panic::tensor::matrix& A, const panic::tensor::vector& b); - -/** - * @brief Clips the maximum of a vector rowwise too a matrix. - * - * Computes: - * @code - * if (A(i,j) < b[i]) - * C(i,j) = b[i]) - * else - * C(i,j) = A(i,j) - * @endcode - * - * @tparam T Numeric element type. - * @param A Matrix. - * @param b Vector. Must have size of @p A.rows(). - * @param C Output matrix. Resized to match @p A. - * - * @return true if @p C was resized and filled successfully. - * @return false if matrix sizes do not match or resizing @p c failed. - */ -template -bool maximum_colwise(const panic::tensor::matrix& A, const panic::tensor::vector& b, panic::tensor::matrix& C); - -/** - * @brief Returns a new matrix containing a vector rowwise cliped to the maixmum. - * - * Computes: - * @code - * if (A(i,j) < b[i]) - * result(i,j) = b[i]) - * else - * result(i,j) = A(i,j) - * @endcode - * - * @tparam T Numeric element type. - * @param A Matrix. - * @param b Vector. Must have size of @p A.rows(). - * - * @return A new matrix containing the result. - * @return An empty matrix if the operation fails. - * - * @note This overload is convenient, but may allocate a new vector. - */ -template -panic::tensor::matrix maximum_colwise(const panic::tensor::matrix& A, const panic::tensor::vector& b); - - - - - - - - - - - - - - - - - - - - - - - - - -} // namespace math -} // namespace panic \ No newline at end of file diff --git a/main.cpp b/main.cpp index f5147b9..d0d0c79 100644 --- a/main.cpp +++ b/main.cpp @@ -49,13 +49,14 @@ #include #include -#include +#include #include #include #include #include #include #include +#include #include @@ -721,9 +722,10 @@ int main(void) { mymodel.forward(X); - panic::io::print_matrix(mymodel.outputs); - + //panic::io::print_matrix(mymodel.outputs); + std::cout << panic::math::exp(15.5f) << std::endl; + std::cout << std::exp(15.5) << std::endl; return 0; diff --git a/src/math/clip.cpp b/src/math/clip.cpp new file mode 100644 index 0000000..33b3fc3 --- /dev/null +++ b/src/math/clip.cpp @@ -0,0 +1,1233 @@ +/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * + * + * PANIC + * Portable Algorithms and Numerics In C++ + * + * Scientific computing from scratch, with feeling. + * + * Copyright (c) 2026 Michelle Bausager + * + * This file is part of PANIC. + * + * PANIC is free software licensed under the GNU General Public License v3.0 or later. + * You may redistribute and/or modify it under the terms of the GPL. + * + * PANIC 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 LICENSE file for the full license text. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * + * Project Name: PANIC + * Module Name: math + * File Name: clip.cpp + * Revision: 0.1.0 + * Date: 29-07-2026 + * Author: Michelle Bausager + * + * Description: + * Functions that clips the values + * + *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +//--------------------------------------------------------------------------------------------------------------------------- +// INCLUDE DESCRIPTION +//----------------------------------------------------------------------------------------------------- + +#include +#include + +#include // for panic::vector +#include // for panic::matrix + +//--------------------------------------------------------------------------------------------------------------------------- +// PRIVATE CONSTANTS +//--------------------------------------------------------------------------------------------------------------------------- +/** + * @brief Minimum number of element operations before using the OpenMP-enabled loop. + * + * Small vectors and matrices are kept serial because the overhead of starting + * worker threads can be larger than the work itself. + */ +static const panic::types::uint_t max_omp_min_work = 500; +//--------------------------------------------------------------------------------------------------------------------------- +// INPLEMENTATION +//--------------------------------------------------------------------------------------------------------------------------- + +namespace panic { + namespace math { + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::clip_lower +// +// Description: +// Clips max of vector compared with scalar +//-------------------------------------------------------------------------------------------------------------------------- +template +bool clip_lower(const panic::tensor::vector& a, const T k, panic::tensor::vector& c){ + + if (!c.resize(a.size())){ + return false; + } + + PANIC_OMP_PARALLEL_FOR_IF(a.size() > max_omp_min_work) + for (panic::types::uint_t i = 0; i < a.size(); ++i){ + if (a[i] < k){ + c[i] = k; + } + else{ + c[i] = a[i]; + } + } + + return true; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template bool clip_lower(const panic::tensor::vector& a, + const panic::types::uint_t k, + panic::tensor::vector& c +); +template bool clip_lower(const panic::tensor::vector& a, + const panic::types::int_t k, + panic::tensor::vector& c +); +template bool clip_lower(const panic::tensor::vector& a, + const panic::types::real_t k, + panic::tensor::vector& c +); + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::clip_lower +// +// Description: +// Clips max of vector compared with scalar +//-------------------------------------------------------------------------------------------------------------------------- +template +panic::tensor::vector clip_lower(const panic::tensor::vector& a, const T k){ + panic::tensor::vector c(a.size()); + + if (!clip_lower(a, k, c)){ + return panic::tensor::vector(); + } + + return c; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template panic::tensor::vector + clip_lower(const panic::tensor::vector& a, + const panic::types::uint_t k +); +template panic::tensor::vector + clip_lower(const panic::tensor::vector& a, + const panic::types::int_t k +); +template panic::tensor::vector + clip_lower(const panic::tensor::vector& a, + const panic::types::real_t k +); + + + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::clip_lower +// +// Description: +// Clips max of vector compared with another vector +//-------------------------------------------------------------------------------------------------------------------------- +template +bool clip_lower(const panic::tensor::vector& a, const panic::tensor::vector& b, panic::tensor::vector& c){ + + if (a.size() != b.size()){ + return false; + } + + if (!c.resize(a.size())){ + return false; + } + + PANIC_OMP_PARALLEL_FOR_IF(a.size() > max_omp_min_work) + for (panic::types::uint_t i = 0; i < a.size(); ++i){ + if (a[i] < b[i]){ + c[i] = b[i]; + } + else{ + c[i] = a[i]; + } + } + + return true; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template bool clip_lower(const panic::tensor::vector& a, + const panic::tensor::vector& b, + panic::tensor::vector& c +); +template bool clip_lower(const panic::tensor::vector& a, + const panic::tensor::vector& b, + panic::tensor::vector& c +); +template bool clip_lower(const panic::tensor::vector& a, + const panic::tensor::vector& b, + panic::tensor::vector& c +); + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::clip_lower +// +// Description: +// Clips max of vector compared with another vector +//-------------------------------------------------------------------------------------------------------------------------- +template +panic::tensor::vector clip_lower(const panic::tensor::vector& a, const panic::tensor::vector& b){ + panic::tensor::vector c(a.size()); + + if (!clip_lower(a, b, c)){ + return panic::tensor::vector(); + } + + return c; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template panic::tensor::vector + clip_lower(const panic::tensor::vector& a, + const panic::tensor::vector& b +); +template panic::tensor::vector + clip_lower(const panic::tensor::vector& a, + const panic::tensor::vector& b +); +template panic::tensor::vector + clip_lower(const panic::tensor::vector& a, + const panic::tensor::vector& b +); + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::max +// +// Description: +// Clips max of matrix compared with scalar +//-------------------------------------------------------------------------------------------------------------------------- +template +bool clip_lower(const panic::tensor::matrix& A, const T k, panic::tensor::matrix& C){ + + panic::types::uint_t rows = A.rows(); + panic::types::uint_t cols = A.cols(); + panic::types::uint_t work = rows*cols; + + if ( !C.resize(rows, cols) ){ + return false; + } + + + PANIC_OMP_PARALLEL_FOR_IF(work > max_omp_min_work) + for (panic::types::uint_t i = 0; i < rows; ++i){ + for (panic::types::uint_t j = 0; j < cols; ++j){ + + if (A(i,j) < k){ + C(i,j) = k; + } + else{ + C(i,j) = A(i,j); + } + } + + } + + return true; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template bool clip_lower(const panic::tensor::matrix& A, + const panic::types::uint_t k, + panic::tensor::matrix& C +); +template bool clip_lower(const panic::tensor::matrix& A, + const panic::types::int_t k, + panic::tensor::matrix& C +); +template bool clip_lower(const panic::tensor::matrix& A, + const panic::types::real_t k, + panic::tensor::matrix& C +); + + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::clip_lower +// +// Description: +// Clips max of matrix compared with scalar +//-------------------------------------------------------------------------------------------------------------------------- +template +panic::tensor::matrix clip_lower(const panic::tensor::matrix& A, const T k){ + panic::tensor::matrix C; + + if (!clip_lower(A, k, C)){ + return panic::tensor::matrix(); + } + + return C; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template panic::tensor::matrix + clip_lower(const panic::tensor::matrix& A, + const panic::types::uint_t k +); +template panic::tensor::matrix + clip_lower(const panic::tensor::matrix& A, + const panic::types::int_t k +); +template panic::tensor::matrix + clip_lower(const panic::tensor::matrix& A, + const panic::types::real_t k +); + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::clip_lower +// +// Description: +// Clips max of two matrices +//-------------------------------------------------------------------------------------------------------------------------- +template +bool clip_lower(const panic::tensor::matrix& A, const panic::tensor::matrix& B, panic::tensor::matrix& C){ + + panic::types::uint_t rows = A.rows(); + panic::types::uint_t cols = A.cols(); + panic::types::uint_t work = rows*cols; + + if ( (rows != B.rows()) || (cols != B.cols())){ + return false; + } + + if ( !C.resize(rows, cols) ){ + return false; + } + + + PANIC_OMP_PARALLEL_FOR_IF(work > max_omp_min_work) + for (panic::types::uint_t i = 0; i < rows; ++i){ + for (panic::types::uint_t j = 0; j < cols; ++j){ + if (A(i,j) < B(i,j)){ + C(i,j) = B(i,j); + } + else{ + C(i,j) = A(i,j); + } + } + + } + + return true; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template bool clip_lower(const panic::tensor::matrix& A, + const panic::tensor::matrix& B, + panic::tensor::matrix& C +); +template bool clip_lower(const panic::tensor::matrix& A, + const panic::tensor::matrix& B, + panic::tensor::matrix& C +); +template bool clip_lower(const panic::tensor::matrix& A, + const panic::tensor::matrix& B, + panic::tensor::matrix& C +); + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::clip_lower +// +// Description: +// Clips max of two matrices +//-------------------------------------------------------------------------------------------------------------------------- +template +panic::tensor::matrix clip_lower(const panic::tensor::matrix& A, const panic::tensor::matrix& B){ + panic::tensor::matrix C; + + if (!clip_lower(A, B, C)){ + return panic::tensor::matrix(); + } + + return C; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template panic::tensor::matrix + clip_lower(const panic::tensor::matrix& A, + const panic::tensor::matrix& B +); +template panic::tensor::matrix + clip_lower(const panic::tensor::matrix& A, + const panic::tensor::matrix& B +); +template panic::tensor::matrix + clip_lower(const panic::tensor::matrix& A, + const panic::tensor::matrix& B +); + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::clip_lower_rowwise +// +// Description: +// Clips max rowwise of matrix compared with vector +//-------------------------------------------------------------------------------------------------------------------------- +template +bool clip_lower_rowwise(const panic::tensor::matrix& A, const panic::tensor::vector& b, panic::tensor::matrix& C){ + + panic::types::uint_t rows = A.rows(); + panic::types::uint_t cols = A.cols(); + panic::types::uint_t work = rows*cols; + + if ( cols != b.size() ){ + return false; + } + + if ( !C.resize(rows, cols) ){ + return false; + } + + + PANIC_OMP_PARALLEL_FOR_IF(work > max_omp_min_work) + for (panic::types::uint_t i = 0; i < rows; ++i){ + for (panic::types::uint_t j = 0; j < cols; ++j){ + + if (A(i,j) < b[j]){ + C(i,j) = b[j]; + } + else{ + C(i,j) = A(i,j); + } + } + + } + + return true; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template bool clip_lower_rowwise(const panic::tensor::matrix& A, + const panic::tensor::vector& b, + panic::tensor::matrix& C +); +template bool clip_lower_rowwise(const panic::tensor::matrix& A, + const panic::tensor::vector& b, + panic::tensor::matrix& C +); +template bool clip_lower_rowwise(const panic::tensor::matrix& A, + const panic::tensor::vector& b, + panic::tensor::matrix& C +); + + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::clip_lower_rowwise +// +// Description: +// Clips max rowwise of matrix compared with vector +//-------------------------------------------------------------------------------------------------------------------------- +template +panic::tensor::matrix clip_lower_rowwise(const panic::tensor::matrix& A, const panic::tensor::vector& b){ + panic::tensor::matrix C; + + if (!clip_lower_rowwise(A, b, C)){ + return panic::tensor::matrix(); + } + + return C; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template panic::tensor::matrix + clip_lower_rowwise(const panic::tensor::matrix& A, + const panic::tensor::vector& b +); +template panic::tensor::matrix + clip_lower_rowwise(const panic::tensor::matrix& A, + const panic::tensor::vector& b +); +template panic::tensor::matrix + clip_lower_rowwise(const panic::tensor::matrix& A, + const panic::tensor::vector& b +); + + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::clip_lower_colwise +// +// Description: +// Clips max column-wise of matrix compared with vector +//-------------------------------------------------------------------------------------------------------------------------- +template +bool clip_lower_colwise(const panic::tensor::matrix& A, const panic::tensor::vector& b, panic::tensor::matrix& C){ + + panic::types::uint_t rows = A.rows(); + panic::types::uint_t cols = A.cols(); + panic::types::uint_t work = rows*cols; + + if ( rows != b.size() ){ + return false; + } + + if ( !C.resize(rows, cols) ){ + return false; + } + + + PANIC_OMP_PARALLEL_FOR_IF(work > max_omp_min_work) + for (panic::types::uint_t i = 0; i < rows; ++i){ + for (panic::types::uint_t j = 0; j < cols; ++j){ + + if (A(i,j) < b[i]){ + C(i,j) = b[i]; + } + else{ + C(i,j) = A(i,j); + } + } + + } + + return true; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template bool clip_lower_colwise(const panic::tensor::matrix& A, + const panic::tensor::vector& b, + panic::tensor::matrix& C +); +template bool clip_lower_colwise(const panic::tensor::matrix& A, + const panic::tensor::vector& b, + panic::tensor::matrix& C +); +template bool clip_lower_colwise(const panic::tensor::matrix& A, + const panic::tensor::vector& b, + panic::tensor::matrix& C +); + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::clip_lower_colwise +// +// Description: +// Clips max column-wise of matrix compared with vector +//-------------------------------------------------------------------------------------------------------------------------- +template +panic::tensor::matrix clip_lower_colwise(const panic::tensor::matrix& A, const panic::tensor::vector& b){ + panic::tensor::matrix C; + + + if (!clip_lower_colwise(A, b, C)){ + return panic::tensor::matrix(); + } + + return C; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template panic::tensor::matrix + clip_lower_colwise(const panic::tensor::matrix& A, + const panic::tensor::vector& b +); +template panic::tensor::matrix + clip_lower_colwise(const panic::tensor::matrix& A, + const panic::tensor::vector& b +); +template panic::tensor::matrix + clip_lower_colwise(const panic::tensor::matrix& A, + const panic::tensor::vector& b +); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::clip_higher +// +// Description: +// Clips min of vector compared with scalar +//-------------------------------------------------------------------------------------------------------------------------- +template +bool clip_higher(const panic::tensor::vector& a, const T k, panic::tensor::vector& c){ + + if (!c.resize(a.size())){ + return false; + } + + PANIC_OMP_PARALLEL_FOR_IF(a.size() > max_omp_min_work) + for (panic::types::uint_t i = 0; i < a.size(); ++i){ + if (a[i] > k){ + c[i] = k; + } + else{ + c[i] = a[i]; + } + } + + return true; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template bool clip_higher(const panic::tensor::vector& a, + const panic::types::uint_t k, + panic::tensor::vector& c +); +template bool clip_higher(const panic::tensor::vector& a, + const panic::types::int_t k, + panic::tensor::vector& c +); +template bool clip_higher(const panic::tensor::vector& a, + const panic::types::real_t k, + panic::tensor::vector& c +); + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::clip_higher +// +// Description: +// Clips min of vector compared with scalar +//-------------------------------------------------------------------------------------------------------------------------- +template +panic::tensor::vector clip_higher(const panic::tensor::vector& a, const T k){ + panic::tensor::vector c(a.size()); + + if (!clip_higher(a, k, c)){ + return panic::tensor::vector(); + } + + return c; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template panic::tensor::vector + clip_higher(const panic::tensor::vector& a, + const panic::types::uint_t k +); +template panic::tensor::vector + clip_higher(const panic::tensor::vector& a, + const panic::types::int_t k +); +template panic::tensor::vector + clip_higher(const panic::tensor::vector& a, + const panic::types::real_t k +); + + + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::clip_higher +// +// Description: +// Clips min of vector compared with another vector +//-------------------------------------------------------------------------------------------------------------------------- +template +bool clip_higher(const panic::tensor::vector& a, const panic::tensor::vector& b, panic::tensor::vector& c){ + + if (a.size() != b.size()){ + return false; + } + + if (!c.resize(a.size())){ + return false; + } + + PANIC_OMP_PARALLEL_FOR_IF(a.size() > max_omp_min_work) + for (panic::types::uint_t i = 0; i < a.size(); ++i){ + if (a[i] > b[i]){ + c[i] = b[i]; + } + else{ + c[i] = a[i]; + } + } + + return true; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template bool clip_higher(const panic::tensor::vector& a, + const panic::tensor::vector& b, + panic::tensor::vector& c +); +template bool clip_higher(const panic::tensor::vector& a, + const panic::tensor::vector& b, + panic::tensor::vector& c +); +template bool clip_higher(const panic::tensor::vector& a, + const panic::tensor::vector& b, + panic::tensor::vector& c +); + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::clip_higher +// +// Description: +// Clips min of vector compared with another vector +//-------------------------------------------------------------------------------------------------------------------------- +template +panic::tensor::vector clip_higher(const panic::tensor::vector& a, const panic::tensor::vector& b){ + panic::tensor::vector c(a.size()); + + if (!clip_higher(a, b, c)){ + return panic::tensor::vector(); + } + + return c; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template panic::tensor::vector + clip_higher(const panic::tensor::vector& a, + const panic::tensor::vector& b +); +template panic::tensor::vector + clip_higher(const panic::tensor::vector& a, + const panic::tensor::vector& b +); +template panic::tensor::vector + clip_higher(const panic::tensor::vector& a, + const panic::tensor::vector& b +); + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::clip_higher +// +// Description: +// Clips min of matrix compared with scalar +//-------------------------------------------------------------------------------------------------------------------------- +template +bool clip_higher(const panic::tensor::matrix& A, const T k, panic::tensor::matrix& C){ + + panic::types::uint_t rows = A.rows(); + panic::types::uint_t cols = A.cols(); + panic::types::uint_t work = rows*cols; + + if ( !C.resize(rows, cols) ){ + return false; + } + + + PANIC_OMP_PARALLEL_FOR_IF(work > max_omp_min_work) + for (panic::types::uint_t i = 0; i < rows; ++i){ + for (panic::types::uint_t j = 0; j < cols; ++j){ + + if (A(i,j) > k){ + C(i,j) = k; + } + else{ + C(i,j) = A(i,j); + } + } + + } + + return true; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template bool clip_higher(const panic::tensor::matrix& A, + const panic::types::uint_t k, + panic::tensor::matrix& C +); +template bool clip_higher(const panic::tensor::matrix& A, + const panic::types::int_t k, + panic::tensor::matrix& C +); +template bool clip_higher(const panic::tensor::matrix& A, + const panic::types::real_t k, + panic::tensor::matrix& C +); + + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::clip_higher +// +// Description: +// Clips min of matrix compared with scalar +//-------------------------------------------------------------------------------------------------------------------------- +template +panic::tensor::matrix clip_higher(const panic::tensor::matrix& A, const T k){ + panic::tensor::matrix C; + + if (!clip_higher(A, k, C)){ + return panic::tensor::matrix(); + } + + return C; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template panic::tensor::matrix + clip_higher(const panic::tensor::matrix& A, + const panic::types::uint_t k +); +template panic::tensor::matrix + clip_higher(const panic::tensor::matrix& A, + const panic::types::int_t k +); +template panic::tensor::matrix + clip_higher(const panic::tensor::matrix& A, + const panic::types::real_t k +); + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::clip_higher +// +// Description: +// Clips min of two matrices +//-------------------------------------------------------------------------------------------------------------------------- +template +bool clip_higher(const panic::tensor::matrix& A, const panic::tensor::matrix& B, panic::tensor::matrix& C){ + + panic::types::uint_t rows = A.rows(); + panic::types::uint_t cols = A.cols(); + panic::types::uint_t work = rows*cols; + + if ( (rows != B.rows()) || (cols != B.cols())){ + return false; + } + + if ( !C.resize(rows, cols) ){ + return false; + } + + + PANIC_OMP_PARALLEL_FOR_IF(work > max_omp_min_work) + for (panic::types::uint_t i = 0; i < rows; ++i){ + for (panic::types::uint_t j = 0; j < cols; ++j){ + if (A(i,j) > B(i,j)){ + C(i,j) = B(i,j); + } + else{ + C(i,j) = A(i,j); + } + } + + } + + return true; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template bool clip_higher(const panic::tensor::matrix& A, + const panic::tensor::matrix& B, + panic::tensor::matrix& C +); +template bool clip_higher(const panic::tensor::matrix& A, + const panic::tensor::matrix& B, + panic::tensor::matrix& C +); +template bool clip_higher(const panic::tensor::matrix& A, + const panic::tensor::matrix& B, + panic::tensor::matrix& C +); + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::clip_higher +// +// Description: +// Clips min of two matrices +//-------------------------------------------------------------------------------------------------------------------------- +template +panic::tensor::matrix clip_higher(const panic::tensor::matrix& A, const panic::tensor::matrix& B){ + panic::tensor::matrix C; + + if (!clip_higher(A, B, C)){ + return panic::tensor::matrix(); + } + + return C; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template panic::tensor::matrix + clip_higher(const panic::tensor::matrix& A, + const panic::tensor::matrix& B +); +template panic::tensor::matrix + clip_higher(const panic::tensor::matrix& A, + const panic::tensor::matrix& B +); +template panic::tensor::matrix + clip_higher(const panic::tensor::matrix& A, + const panic::tensor::matrix& B +); + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::clip_higher_rowwise +// +// Description: +// Clips min rowwise of matrix compared with vector +//-------------------------------------------------------------------------------------------------------------------------- +template +bool clip_higher_rowwise(const panic::tensor::matrix& A, const panic::tensor::vector& b, panic::tensor::matrix& C){ + + panic::types::uint_t rows = A.rows(); + panic::types::uint_t cols = A.cols(); + panic::types::uint_t work = rows*cols; + + if ( cols != b.size() ){ + return false; + } + + if ( !C.resize(rows, cols) ){ + return false; + } + + + PANIC_OMP_PARALLEL_FOR_IF(work > max_omp_min_work) + for (panic::types::uint_t i = 0; i < rows; ++i){ + for (panic::types::uint_t j = 0; j < cols; ++j){ + + if (A(i,j) > b[j]){ + C(i,j) = b[j]; + } + else{ + C(i,j) = A(i,j); + } + } + + } + + return true; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template bool clip_higher_rowwise(const panic::tensor::matrix& A, + const panic::tensor::vector& b, + panic::tensor::matrix& C +); +template bool clip_higher_rowwise(const panic::tensor::matrix& A, + const panic::tensor::vector& b, + panic::tensor::matrix& C +); +template bool clip_higher_rowwise(const panic::tensor::matrix& A, + const panic::tensor::vector& b, + panic::tensor::matrix& C +); + + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::clip_higher_rowwise +// +// Description: +// Clips min rowwise of matrix compared with vector +//-------------------------------------------------------------------------------------------------------------------------- +template +panic::tensor::matrix clip_higher_rowwise(const panic::tensor::matrix& A, const panic::tensor::vector& b){ + panic::tensor::matrix C; + + if (!clip_higher_rowwise(A, b, C)){ + return panic::tensor::matrix(); + } + + return C; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template panic::tensor::matrix + clip_higher_rowwise(const panic::tensor::matrix& A, + const panic::tensor::vector& b +); +template panic::tensor::matrix + clip_higher_rowwise(const panic::tensor::matrix& A, + const panic::tensor::vector& b +); +template panic::tensor::matrix + clip_higher_rowwise(const panic::tensor::matrix& A, + const panic::tensor::vector& b +); + + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::clip_higher_colwise +// +// Description: +// Clips min column-wise of matrix compared with vector +//-------------------------------------------------------------------------------------------------------------------------- +template +bool clip_higher_colwise(const panic::tensor::matrix& A, const panic::tensor::vector& b, panic::tensor::matrix& C){ + + panic::types::uint_t rows = A.rows(); + panic::types::uint_t cols = A.cols(); + panic::types::uint_t work = rows*cols; + + if ( rows != b.size() ){ + return false; + } + + if ( !C.resize(rows, cols) ){ + return false; + } + + + PANIC_OMP_PARALLEL_FOR_IF(work > max_omp_min_work) + for (panic::types::uint_t i = 0; i < rows; ++i){ + for (panic::types::uint_t j = 0; j < cols; ++j){ + + if (A(i,j) > b[i]){ + C(i,j) = b[i]; + } + else{ + C(i,j) = A(i,j); + } + } + + } + + return true; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template bool clip_higher_colwise(const panic::tensor::matrix& A, + const panic::tensor::vector& b, + panic::tensor::matrix& C +); +template bool clip_higher_colwise(const panic::tensor::matrix& A, + const panic::tensor::vector& b, + panic::tensor::matrix& C +); +template bool clip_higher_colwise(const panic::tensor::matrix& A, + const panic::tensor::vector& b, + panic::tensor::matrix& C +); + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::clip_higher_colwise +// +// Description: +// Clips min column-wise of matrix compared with vector +//-------------------------------------------------------------------------------------------------------------------------- +template +panic::tensor::matrix clip_higher_colwise(const panic::tensor::matrix& A, const panic::tensor::vector& b){ + panic::tensor::matrix C; + + + if (!clip_higher_colwise(A, b, C)){ + return panic::tensor::matrix(); + } + + return C; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template panic::tensor::matrix + clip_higher_colwise(const panic::tensor::matrix& A, + const panic::tensor::vector& b +); +template panic::tensor::matrix + clip_higher_colwise(const panic::tensor::matrix& A, + const panic::tensor::vector& b +); +template panic::tensor::matrix + clip_higher_colwise(const panic::tensor::matrix& A, + const panic::tensor::vector& b +); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + } // namespace math +} // namespace panic diff --git a/src/math/exp.cpp b/src/math/exp.cpp new file mode 100644 index 0000000..c24085e --- /dev/null +++ b/src/math/exp.cpp @@ -0,0 +1,298 @@ +/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * + * PANIC + * Portable Algorithms and Numerics In C++ + * + * Scientific computing from scratch, with feeling. + * + * Copyright (c) 2026 Michelle Bausager + * + * This file is part of PANIC. + * + * PANIC is free software licensed under the GNU General Public License v3.0 or later. + * You may redistribute and/or modify it under the terms of the GPL. + * + * PANIC 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 LICENSE file for the full license text. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * + * Project Name: PANIC + * Module Name: math + * File Name: exp.cpp + * Revision: 0.1.0 + * Date: 29-07-2026 + * Author: Michelle Bausager + * + * Description: + * Functions to calculate the exponential of numbers + * + *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ + +//--------------------------------------------------------------------------------------------------------------------------- +// INCLUDE DESCRIPTION +//----------------------------------------------------------------------------------------------------- + +#include +#include +#include + +#include // for panic::vector +#include // for panic::matrix + +//--------------------------------------------------------------------------------------------------------------------------- +// PRIVATE CONSTANTS +//--------------------------------------------------------------------------------------------------------------------------- +/** + * @brief Minimum number of element operations before using the OpenMP-enabled loop. + * + * Small vectors and matrices are kept serial because the overhead of starting + * worker threads can be larger than the work itself. + */ +static const panic::types::uint_t exp_omp_min_work = 500; +//--------------------------------------------------------------------------------------------------------------------------- +// INPLEMENTATION +//--------------------------------------------------------------------------------------------------------------------------- + +namespace panic { + namespace math { + + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::exp +// +// Description: +// Calculates the exponential +//-------------------------------------------------------------------------------------------------------------------------- +template +T exp(const T x){ + + // The identity: + // + // e^(-x) = 1 / e^x + // + // lets the rest of the function work only with positive values. + if (x < static_cast(0)) { + return static_cast(1) / exp(-x); + } + + // Natural logarithm of 2. + // + // This is useful because: + // + // e^(ln(2)) = 2 + // + const T ln2 = static_cast(0.69314718055994530942); + + // Split x into: + // + // x = k * ln(2) + r + // + // For example, when x = 2: + // + // k = floor(2 / ln(2)) = 2 + // r = 2 - 2 * ln(2) ≈ 0.6137 + // + // This makes r small, which makes the Taylor series + // converge much faster. + const panic::types::uint_t k = static_cast(x / ln2); + + const T r = x - static_cast(k) * ln2; + + // Taylor series: + // + // r² r³ r⁴ + // e^r = 1 + r + ---- + ---- + ---- + ... + // 2! 3! 4! + // + // result starts with the first term: 1. + T result = static_cast(1); + + // term also starts at 1, representing: + // + // r^0 / 0! = 1 + T term = static_cast(1); + + + for (panic::types::uint_t n = 1; n <= 15; ++n){ + + // Produce the next Taylor term from the previous one. + // + // For example: + // + // n = 1: term = 1 * r / 1 = r + // n = 2: term = r * r / 2 = r² / 2! + // n = 3: term = r²/2 * r/3 = r³ / 3! + // + // This avoids separately calculating powers and factorials. + term *= r / static_cast(n); + + // Add the new term to the approximation. + result += term; + } + + // We currently have e^r. + // + // From: + // + // x = k * ln(2) + r + // + // we get: + // + // e^x = e^(k * ln(2)) * e^r + // = 2^k * e^r + // + // Therefore, multiply the result by 2 exactly k times. + for (panic::types::uint_t i = 0; i < k; ++i) { + result *= static_cast(2); + } + + return result; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template panic::types::real_t exp(const panic::types::real_t x +); + + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::exp +// +// Description: +// Calculates the exponential elementwise of a vector +//-------------------------------------------------------------------------------------------------------------------------- +template +bool exp(const panic::tensor::vector& a, panic::tensor::vector& c){ + + if (!c.resize(a.size())){ + return false; + } + + PANIC_OMP_PARALLEL_FOR_IF(a.size() > exp_omp_min_work) + for (panic::types::uint_t i = 0; i < a.size(); ++i){ + c[i] = exp(a[i]); + } + + return true; +} + +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template bool exp(const panic::tensor::vector& a, + panic::tensor::vector& c +); + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::exp +// +// Description: +// Calculates the exponential elementwise for a vector +//-------------------------------------------------------------------------------------------------------------------------- +template +panic::tensor::vector exp(const panic::tensor::vector& a){ + panic::tensor::vector c(a.size()); + + if (!exp(a, c)){ + return panic::tensor::vector(); + } + + return c; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template panic::tensor::vector + exp(const panic::tensor::vector& a +); + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::exp +// +// Description: +// calculates the exponential elementwise of a matrix +//-------------------------------------------------------------------------------------------------------------------------- +template +bool exp(const panic::tensor::matrix& A, panic::tensor::matrix& C){ + + panic::types::uint_t rows = A.rows(); + panic::types::uint_t cols = A.cols(); + panic::types::uint_t work = rows*cols; + + if ( !C.resize(rows, cols) ){ + return false; + } + + + PANIC_OMP_PARALLEL_FOR_IF(work > exp_omp_min_work) + for (panic::types::uint_t i = 0; i < rows; ++i){ + for (panic::types::uint_t j = 0; j < cols; ++j){ + C(i,j) = exp(A(i,j)); + } + + } + + return true; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template bool exp(const panic::tensor::matrix& A, + panic::tensor::matrix& C +); + + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::exp +// +// Description: +// Calculates the exponential element-wise of a matrix +//-------------------------------------------------------------------------------------------------------------------------- +template +panic::tensor::matrix exp(const panic::tensor::matrix& A){ + panic::tensor::matrix C; + + if (!exp(A, C)){ + return panic::tensor::matrix(); + } + + return C; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template panic::tensor::matrix + exp(const panic::tensor::matrix& A +); + + + } // namespace math +} // namespace panic diff --git a/src/math/max.cpp b/src/math/max.cpp new file mode 100644 index 0000000..108f86b --- /dev/null +++ b/src/math/max.cpp @@ -0,0 +1,339 @@ +/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * + * PANIC + * Portable Algorithms and Numerics In C++ + * + * Scientific computing from scratch, with feeling. + * + * Copyright (c) 2026 Michelle Bausager + * + * This file is part of PANIC. + * + * PANIC is free software licensed under the GNU General Public License v3.0 or later. + * You may redistribute and/or modify it under the terms of the GPL. + * + * PANIC 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 LICENSE file for the full license text. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * + * Project Name: PANIC + * Module Name: math + * File Name: add.cpp + * Revision: 0.1.0 + * Date: 25-06-2026 + * Author: Michelle Bausager + * + * Description: + * Functions to add panic::tensors togther; + * + *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ + +//--------------------------------------------------------------------------------------------------------------------------- +// INCLUDE DESCRIPTION +//----------------------------------------------------------------------------------------------------- + +#include +#include + +#include // for panic::vector +#include // for panic::matrix + +//--------------------------------------------------------------------------------------------------------------------------- +// PRIVATE CONSTANTS +//--------------------------------------------------------------------------------------------------------------------------- +/** + * @brief Minimum number of element operations before using the OpenMP-enabled loop. + * + * Small vectors and matrices are kept serial because the overhead of starting + * worker threads can be larger than the work itself. + */ +static const panic::types::uint_t max_omp_min_work = 500; +//--------------------------------------------------------------------------------------------------------------------------- +// INPLEMENTATION +//--------------------------------------------------------------------------------------------------------------------------- + +namespace panic { + namespace math { + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::max +// +// Description: +// Find the max value for a vector +//-------------------------------------------------------------------------------------------------------------------------- +template +T max(const panic::tensor::vector& a){ + + T y = a[0]; + + // Find the maximum in parallel for large vectors. + // Each thread computes a local maximum, then OpenMP combines them into y. + #pragma omp parallel for if(a.size() > max_omp_min_work) reduction(max:y) + for (panic::types::uint_t i = 1; i < a.size(); ++i) { + if (a[i] > y) { + y = a[i]; + } + } + + return y; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template panic::types::uint_t max(const panic::tensor::vector& a +); +template panic::types::int_t max(const panic::tensor::vector& a +); +template panic::types::real_t max(const panic::tensor::vector& a +); + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::max +// +// Description: +// Find the max value for a matrix +//-------------------------------------------------------------------------------------------------------------------------- +template +T max(const panic::tensor::matrix& A){ + + panic::types::uint_t rows = A.rows(); + panic::types::uint_t cols = A.cols(); + panic::types::uint_t work = rows*cols; + + T y = A(0,0); + + // Find the maximum in parallel for large vectors. + // Each thread computes a local maximum, then OpenMP combines them into y. + #pragma omp parallel for if(work > max_omp_min_work) reduction(max:y) + for (panic::types::uint_t i = 0; i < A.rows(); ++i) { + for (panic::types::uint_t j = 0; j < A.cols(); ++j){ + if (A(i,j) > y) { + y = A(i,j); + } + } + } + return y; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template panic::types::uint_t max(const panic::tensor::matrix& a +); +template panic::types::int_t max(const panic::tensor::matrix& a +); +template panic::types::real_t max(const panic::tensor::matrix& a +); + + + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::max_rowwise +// +// Description: +// Find the maximum row-wise of a matrix +//-------------------------------------------------------------------------------------------------------------------------- +template +bool max_rowwise(const panic::tensor::matrix& A, panic::tensor::vector& b){ + + panic::types::uint_t rows = A.rows(); + panic::types::uint_t cols = A.cols(); + panic::types::uint_t work = rows*cols; + + if ( !b.resize(rows) ){ + return false; + } + + // Each thread handles separate rows and writes to a separate b[i]. + PANIC_OMP_PARALLEL_FOR_IF(work > max_omp_min_work) + for (panic::types::uint_t i = 0; i < rows; ++i){ + b[i] = A(i,0); + for (panic::types::uint_t j = 0; j < cols; ++j){ + if (b[i] < A(i,j)){ + b[i] = A(i,j); + } + + + } + + } + + return true; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template bool max_rowwise(const panic::tensor::matrix& A, + panic::tensor::vector& b +); +template bool max_rowwise(const panic::tensor::matrix& A, + panic::tensor::vector& b +); +template bool max_rowwise(const panic::tensor::matrix& A, + panic::tensor::vector& b +); + + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::max_rowwise +// +// Description: +// Returns row-wise max values +//-------------------------------------------------------------------------------------------------------------------------- +template +panic::tensor::vector max_rowwise(const panic::tensor::matrix& A){ + panic::tensor::vector b; + + if (!max_rowwise(A, b)){ + return panic::tensor::vector(); + } + + return b; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template panic::tensor::vector + max_rowwise(const panic::tensor::matrix& A +); +template panic::tensor::vector + max_rowwise(const panic::tensor::matrix& A +); +template panic::tensor::vector + max_rowwise(const panic::tensor::matrix& A +); + + + + + + + + + + + + + + + + + + + + + + + + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::max_colwise +// +// Description: +// Find the maximum column-wise of a matrix +//-------------------------------------------------------------------------------------------------------------------------- +template +bool max_colwise(const panic::tensor::matrix& A, panic::tensor::vector& b){ + + panic::types::uint_t rows = A.rows(); + panic::types::uint_t cols = A.cols(); + panic::types::uint_t work = rows*cols; + + if ( !b.resize(cols) ){ + return false; + } + + // Each thread handles separate cols and writes to a separate b[i]. + PANIC_OMP_PARALLEL_FOR_IF(work > max_omp_min_work) + for (panic::types::uint_t i = 0; i < cols; ++i){ + b[i] = A(0,i); + for (panic::types::uint_t j = 0; j < rows; ++j){ + if (b[i] < A(j,i)){ + b[i] = A(j,i); + } + + + } + + } + + return true; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template bool max_colwise(const panic::tensor::matrix& A, + panic::tensor::vector& b +); +template bool max_colwise(const panic::tensor::matrix& A, + panic::tensor::vector& b +); +template bool max_colwise(const panic::tensor::matrix& A, + panic::tensor::vector& b +); + + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::max_colwise +// +// Description: +// Returns column-wise max values +//-------------------------------------------------------------------------------------------------------------------------- +template +panic::tensor::vector max_colwise(const panic::tensor::matrix& A){ + panic::tensor::vector b; + + if (!max_colwise(A, b)){ + return panic::tensor::vector(); + } + + return b; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template panic::tensor::vector + max_colwise(const panic::tensor::matrix& A +); +template panic::tensor::vector + max_colwise(const panic::tensor::matrix& A +); +template panic::tensor::vector + max_colwise(const panic::tensor::matrix& A +); + + + } // namespace math +} // namespace panic diff --git a/src/math/maximum.cpp b/src/math/maximum.cpp deleted file mode 100644 index 4e96761..0000000 --- a/src/math/maximum.cpp +++ /dev/null @@ -1,638 +0,0 @@ -/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * - * PANIC - * Portable Algorithms and Numerics In C++ - * - * Scientific computing from scratch, with feeling. - * - * Copyright (c) 2026 Michelle Bausager - * - * This file is part of PANIC. - * - * PANIC is free software licensed under the GNU General Public License v3.0 or later. - * You may redistribute and/or modify it under the terms of the GPL. - * - * PANIC 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 LICENSE file for the full license text. - * - * SPDX-License-Identifier: GPL-3.0-or-later - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - * - * Project Name: PANIC - * Module Name: math - * File Name: maximum.cpp - * Revision: 0.1.0 - * Date: 29-07-2026 - * Author: Michelle Bausager - * - * Description: - * Functions that finds the maximum - * - *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -//--------------------------------------------------------------------------------------------------------------------------- -// INCLUDE DESCRIPTION -//----------------------------------------------------------------------------------------------------- - -#include -#include - -#include // for panic::vector -#include // for panic::matrix - -//--------------------------------------------------------------------------------------------------------------------------- -// PRIVATE CONSTANTS -//--------------------------------------------------------------------------------------------------------------------------- -/** - * @brief Minimum number of element operations before using the OpenMP-enabled loop. - * - * Small vectors and matrices are kept serial because the overhead of starting - * worker threads can be larger than the work itself. - */ -static const panic::types::uint_t maximum_omp_min_work = 500; -//--------------------------------------------------------------------------------------------------------------------------- -// INPLEMENTATION -//--------------------------------------------------------------------------------------------------------------------------- - -namespace panic { - namespace math { - - -//-------------------------------------------------------------------------------------------------------------------------- -// Function Name : panic::math::maximum -// -// Description: -// Clips maximum of vector compared with scalar -//-------------------------------------------------------------------------------------------------------------------------- -template -bool maximum(const panic::tensor::vector& a, const T k, panic::tensor::vector& c){ - - if (!c.resize(a.size())){ - return false; - } - - PANIC_OMP_PARALLEL_FOR_IF(a.size() > maximum_omp_min_work) - for (panic::types::uint_t i = 0; i < a.size(); ++i){ - if (a[i] < k){ - c[i] = k; - } - else{ - c[i] = a[i]; - } - } - - return true; -} -//-------------------------------------------------------------------------------------------------------------------------- -// EXPLICIT TEMPLATE INSTANTIATION -// -// The implementation is in this .cpp file. -// Build the overload for the official PANIC numeric types. -//-------------------------------------------------------------------------------------------------------------------------- -template bool maximum(const panic::tensor::vector& a, - const panic::types::uint_t k, - panic::tensor::vector& c -); -template bool maximum(const panic::tensor::vector& a, - const panic::types::int_t k, - panic::tensor::vector& c -); -template bool maximum(const panic::tensor::vector& a, - const panic::types::real_t k, - panic::tensor::vector& c -); - - - -//-------------------------------------------------------------------------------------------------------------------------- -// Function Name : panic::math::maximum -// -// Description: -// Clips maximum of vector compared with scalar -//-------------------------------------------------------------------------------------------------------------------------- -template -panic::tensor::vector maximum(const panic::tensor::vector& a, const T k){ - panic::tensor::vector c(a.size()); - - if (!maximum(a, k, c)){ - return panic::tensor::vector(); - } - - return c; -} -//-------------------------------------------------------------------------------------------------------------------------- -// EXPLICIT TEMPLATE INSTANTIATION -// -// The implementation is in this .cpp file. -// Build the overload for the official PANIC numeric types. -//-------------------------------------------------------------------------------------------------------------------------- -template panic::tensor::vector - maximum(const panic::tensor::vector& a, - const panic::types::uint_t k -); -template panic::tensor::vector - maximum(const panic::tensor::vector& a, - const panic::types::int_t k -); -template panic::tensor::vector - maximum(const panic::tensor::vector& a, - const panic::types::real_t k -); - - - - - -//-------------------------------------------------------------------------------------------------------------------------- -// Function Name : panic::math::maximum -// -// Description: -// Clips maximum of vector compared with another vector -//-------------------------------------------------------------------------------------------------------------------------- -template -bool maximum(const panic::tensor::vector& a, const panic::tensor::vector& b, panic::tensor::vector& c){ - - if (a.size() != b.size()){ - return false; - } - - if (!c.resize(a.size())){ - return false; - } - - PANIC_OMP_PARALLEL_FOR_IF(a.size() > maximum_omp_min_work) - for (panic::types::uint_t i = 0; i < a.size(); ++i){ - if (a[i] < b[i]){ - c[i] = b[i]; - } - else{ - c[i] = a[i]; - } - } - - return true; -} -//-------------------------------------------------------------------------------------------------------------------------- -// EXPLICIT TEMPLATE INSTANTIATION -// -// The implementation is in this .cpp file. -// Build the overload for the official PANIC numeric types. -//-------------------------------------------------------------------------------------------------------------------------- -template bool maximum(const panic::tensor::vector& a, - const panic::tensor::vector& b, - panic::tensor::vector& c -); -template bool maximum(const panic::tensor::vector& a, - const panic::tensor::vector& b, - panic::tensor::vector& c -); -template bool maximum(const panic::tensor::vector& a, - const panic::tensor::vector& b, - panic::tensor::vector& c -); - - -//-------------------------------------------------------------------------------------------------------------------------- -// Function Name : panic::math::maximum -// -// Description: -// Clips maximum of vector compared with another vector -//-------------------------------------------------------------------------------------------------------------------------- -template -panic::tensor::vector maximum(const panic::tensor::vector& a, const panic::tensor::vector& b){ - panic::tensor::vector c(a.size()); - - if (!maximum(a, b, c)){ - return panic::tensor::vector(); - } - - return c; -} -//-------------------------------------------------------------------------------------------------------------------------- -// EXPLICIT TEMPLATE INSTANTIATION -// -// The implementation is in this .cpp file. -// Build the overload for the official PANIC numeric types. -//-------------------------------------------------------------------------------------------------------------------------- -template panic::tensor::vector - maximum(const panic::tensor::vector& a, - const panic::tensor::vector& b -); -template panic::tensor::vector - maximum(const panic::tensor::vector& a, - const panic::tensor::vector& b -); -template panic::tensor::vector - maximum(const panic::tensor::vector& a, - const panic::tensor::vector& b -); - - -//-------------------------------------------------------------------------------------------------------------------------- -// Function Name : panic::math::maximum -// -// Description: -// Clips maximum of matrix compared with scalar -//-------------------------------------------------------------------------------------------------------------------------- -template -bool maximum(const panic::tensor::matrix& A, const T k, panic::tensor::matrix& C){ - - panic::types::uint_t rows = A.rows(); - panic::types::uint_t cols = A.cols(); - panic::types::uint_t work = rows*cols; - - if ( !C.resize(rows, cols) ){ - return false; - } - - - PANIC_OMP_PARALLEL_FOR_IF(work > maximum_omp_min_work) - for (panic::types::uint_t i = 0; i < rows; ++i){ - for (panic::types::uint_t j = 0; j < cols; ++j){ - - if (A(i,j) < k){ - C(i,j) = k; - } - else{ - C(i,j) = A(i,j); - } - } - - } - - return true; -} -//-------------------------------------------------------------------------------------------------------------------------- -// EXPLICIT TEMPLATE INSTANTIATION -// -// The implementation is in this .cpp file. -// Build the overload for the official PANIC numeric types. -//-------------------------------------------------------------------------------------------------------------------------- -template bool maximum(const panic::tensor::matrix& A, - const panic::types::uint_t k, - panic::tensor::matrix& C -); -template bool maximum(const panic::tensor::matrix& A, - const panic::types::int_t k, - panic::tensor::matrix& C -); -template bool maximum(const panic::tensor::matrix& A, - const panic::types::real_t k, - panic::tensor::matrix& C -); - - - - -//-------------------------------------------------------------------------------------------------------------------------- -// Function Name : panic::math::maximum -// -// Description: -// Clips maximum of matrix compared with scalar -//-------------------------------------------------------------------------------------------------------------------------- -template -panic::tensor::matrix maximum(const panic::tensor::matrix& A, const T k){ - panic::tensor::matrix C; - - if (!maximum(A, k, C)){ - return panic::tensor::matrix(); - } - - return C; -} -//-------------------------------------------------------------------------------------------------------------------------- -// EXPLICIT TEMPLATE INSTANTIATION -// -// The implementation is in this .cpp file. -// Build the overload for the official PANIC numeric types. -//-------------------------------------------------------------------------------------------------------------------------- -template panic::tensor::matrix - maximum(const panic::tensor::matrix& A, - const panic::types::uint_t k -); -template panic::tensor::matrix - maximum(const panic::tensor::matrix& A, - const panic::types::int_t k -); -template panic::tensor::matrix - maximum(const panic::tensor::matrix& A, - const panic::types::real_t k -); - - -//-------------------------------------------------------------------------------------------------------------------------- -// Function Name : panic::math::maximum -// -// Description: -// Clips maximum of two matrices -//-------------------------------------------------------------------------------------------------------------------------- -template -bool maximum(const panic::tensor::matrix& A, const panic::tensor::matrix& B, panic::tensor::matrix& C){ - - panic::types::uint_t rows = A.rows(); - panic::types::uint_t cols = A.cols(); - panic::types::uint_t work = rows*cols; - - if ( (rows != B.rows()) || (cols != B.cols())){ - return false; - } - - if ( !C.resize(rows, cols) ){ - return false; - } - - - PANIC_OMP_PARALLEL_FOR_IF(work > maximum_omp_min_work) - for (panic::types::uint_t i = 0; i < rows; ++i){ - for (panic::types::uint_t j = 0; j < cols; ++j){ - if (A(i,j) < B(i,j)){ - C(i,j) = B(i,j); - } - else{ - C(i,j) = A(i,j); - } - } - - } - - return true; -} -//-------------------------------------------------------------------------------------------------------------------------- -// EXPLICIT TEMPLATE INSTANTIATION -// -// The implementation is in this .cpp file. -// Build the overload for the official PANIC numeric types. -//-------------------------------------------------------------------------------------------------------------------------- -template bool maximum(const panic::tensor::matrix& A, - const panic::tensor::matrix& B, - panic::tensor::matrix& C -); -template bool maximum(const panic::tensor::matrix& A, - const panic::tensor::matrix& B, - panic::tensor::matrix& C -); -template bool maximum(const panic::tensor::matrix& A, - const panic::tensor::matrix& B, - panic::tensor::matrix& C -); - - - -//-------------------------------------------------------------------------------------------------------------------------- -// Function Name : panic::math::maximum -// -// Description: -// Clips maximum of two matrices -//-------------------------------------------------------------------------------------------------------------------------- -template -panic::tensor::matrix maximum(const panic::tensor::matrix& A, const panic::tensor::matrix& B){ - panic::tensor::matrix C; - - if (!maximum(A, B, C)){ - return panic::tensor::matrix(); - } - - return C; -} -//-------------------------------------------------------------------------------------------------------------------------- -// EXPLICIT TEMPLATE INSTANTIATION -// -// The implementation is in this .cpp file. -// Build the overload for the official PANIC numeric types. -//-------------------------------------------------------------------------------------------------------------------------- -template panic::tensor::matrix - maximum(const panic::tensor::matrix& A, - const panic::tensor::matrix& B -); -template panic::tensor::matrix - maximum(const panic::tensor::matrix& A, - const panic::tensor::matrix& B -); -template panic::tensor::matrix - maximum(const panic::tensor::matrix& A, - const panic::tensor::matrix& B -); - - -//-------------------------------------------------------------------------------------------------------------------------- -// Function Name : panic::math::maximum_rowwise -// -// Description: -// Clips maximum rowwise of matrix compared with vector -//-------------------------------------------------------------------------------------------------------------------------- -template -bool maximum_rowwise(const panic::tensor::matrix& A, const panic::tensor::vector& b, panic::tensor::matrix& C){ - - panic::types::uint_t rows = A.rows(); - panic::types::uint_t cols = A.cols(); - panic::types::uint_t work = rows*cols; - - if ( cols != b.size() ){ - return false; - } - - if ( !C.resize(rows, cols) ){ - return false; - } - - - PANIC_OMP_PARALLEL_FOR_IF(work > maximum_omp_min_work) - for (panic::types::uint_t i = 0; i < rows; ++i){ - for (panic::types::uint_t j = 0; j < cols; ++j){ - - if (A(i,j) < b[j]){ - C(i,j) = b[j]; - } - else{ - C(i,j) = A(i,j); - } - } - - } - - return true; -} -//-------------------------------------------------------------------------------------------------------------------------- -// EXPLICIT TEMPLATE INSTANTIATION -// -// The implementation is in this .cpp file. -// Build the overload for the official PANIC numeric types. -//-------------------------------------------------------------------------------------------------------------------------- -template bool maximum_rowwise(const panic::tensor::matrix& A, - const panic::tensor::vector& b, - panic::tensor::matrix& C -); -template bool maximum_rowwise(const panic::tensor::matrix& A, - const panic::tensor::vector& b, - panic::tensor::matrix& C -); -template bool maximum_rowwise(const panic::tensor::matrix& A, - const panic::tensor::vector& b, - panic::tensor::matrix& C -); - - - - -//-------------------------------------------------------------------------------------------------------------------------- -// Function Name : panic::math::maximum_rowwise -// -// Description: -// Clips maximum rowwise of matrix compared with vector -//-------------------------------------------------------------------------------------------------------------------------- -template -panic::tensor::matrix maximum_rowwise(const panic::tensor::matrix& A, const panic::tensor::vector& b){ - panic::tensor::matrix C; - - if (!maximum_rowwise(A, b, C)){ - return panic::tensor::matrix(); - } - - return C; -} -//-------------------------------------------------------------------------------------------------------------------------- -// EXPLICIT TEMPLATE INSTANTIATION -// -// The implementation is in this .cpp file. -// Build the overload for the official PANIC numeric types. -//-------------------------------------------------------------------------------------------------------------------------- -template panic::tensor::matrix - maximum_rowwise(const panic::tensor::matrix& A, - const panic::tensor::vector& b -); -template panic::tensor::matrix - maximum_rowwise(const panic::tensor::matrix& A, - const panic::tensor::vector& b -); -template panic::tensor::matrix - maximum_rowwise(const panic::tensor::matrix& A, - const panic::tensor::vector& b -); - - - - -//-------------------------------------------------------------------------------------------------------------------------- -// Function Name : panic::math::maximum_colwise -// -// Description: -// Clips maximum column-wise of matrix compared with vector -//-------------------------------------------------------------------------------------------------------------------------- -template -bool maximum_colwise(const panic::tensor::matrix& A, const panic::tensor::vector& b, panic::tensor::matrix& C){ - - panic::types::uint_t rows = A.rows(); - panic::types::uint_t cols = A.cols(); - panic::types::uint_t work = rows*cols; - - if ( rows != b.size() ){ - return false; - } - - if ( !C.resize(rows, cols) ){ - return false; - } - - - PANIC_OMP_PARALLEL_FOR_IF(work > maximum_omp_min_work) - for (panic::types::uint_t i = 0; i < rows; ++i){ - for (panic::types::uint_t j = 0; j < cols; ++j){ - - if (A(i,j) < b[i]){ - C(i,j) = b[i]; - } - else{ - C(i,j) = A(i,j); - } - } - - } - - return true; -} -//-------------------------------------------------------------------------------------------------------------------------- -// EXPLICIT TEMPLATE INSTANTIATION -// -// The implementation is in this .cpp file. -// Build the overload for the official PANIC numeric types. -//-------------------------------------------------------------------------------------------------------------------------- -template bool maximum_colwise(const panic::tensor::matrix& A, - const panic::tensor::vector& b, - panic::tensor::matrix& C -); -template bool maximum_colwise(const panic::tensor::matrix& A, - const panic::tensor::vector& b, - panic::tensor::matrix& C -); -template bool maximum_colwise(const panic::tensor::matrix& A, - const panic::tensor::vector& b, - panic::tensor::matrix& C -); - - - -//-------------------------------------------------------------------------------------------------------------------------- -// Function Name : panic::math::maximum_colwise -// -// Description: -// Clips maximum column-wise of matrix compared with vector -//-------------------------------------------------------------------------------------------------------------------------- -template -panic::tensor::matrix maximum_colwise(const panic::tensor::matrix& A, const panic::tensor::vector& b){ - panic::tensor::matrix C; - - - if (!maximum_colwise(A, b, C)){ - return panic::tensor::matrix(); - } - - return C; -} -//-------------------------------------------------------------------------------------------------------------------------- -// EXPLICIT TEMPLATE INSTANTIATION -// -// The implementation is in this .cpp file. -// Build the overload for the official PANIC numeric types. -//-------------------------------------------------------------------------------------------------------------------------- -template panic::tensor::matrix - maximum_colwise(const panic::tensor::matrix& A, - const panic::tensor::vector& b -); -template panic::tensor::matrix - maximum_colwise(const panic::tensor::matrix& A, - const panic::tensor::vector& b -); -template panic::tensor::matrix - maximum_colwise(const panic::tensor::matrix& A, - const panic::tensor::vector& b -); - - - - - - - - - - - - - - - - - - - - - - - - - - - } // namespace math -} // namespace panic diff --git a/src/neural_network/activation/activation_ReLU.cpp b/src/neural_network/activation/activation_ReLU.cpp index 3c8ebf0..eab0e7e 100644 --- a/src/neural_network/activation/activation_ReLU.cpp +++ b/src/neural_network/activation/activation_ReLU.cpp @@ -38,7 +38,7 @@ #include #include -#include +#include @@ -78,7 +78,7 @@ activation_ReLU::activation_ReLU() { //-------------------------------------------------------------------------------------------------------------------------- bool activation_ReLU::forward(const panic::tensor::real_matrix& inputs){ - panic::math::maximum(inputs, 0.0f, outputs); + panic::math::clip_lower(inputs, 0.0f, outputs); /* if (inputs.cols() != weights.rows()){ return false;