From d7b74ab40fecc4e440946b85e7bc7e5fbf6fd88f Mon Sep 17 00:00:00 2001 From: Michelle Date: Thu, 30 Jul 2026 22:23:06 +0200 Subject: [PATCH] Making loss_categorical_crossentropy --- include/math/clip.hpp | 100 ++++++ include/math/log.hpp | 144 ++++++++ include/math/mean.hpp | 159 +++++++++ include/neural_network/loss/loss.hpp | 134 ++++++++ .../loss/loss_categorical_crossentropy.hpp | 93 ++++++ main.cpp | 1 + src/math/clip.cpp | 257 +++++++++++++- src/math/log.cpp | 298 +++++++++++++++++ src/math/mean.cpp | 316 ++++++++++++++++++ src/neural_network/loss/loss.cpp | 166 +++++++++ .../loss/loss_categorical_crossentropy.cpp | 94 ++++++ 11 files changed, 1749 insertions(+), 13 deletions(-) create mode 100644 include/math/log.hpp create mode 100644 include/math/mean.hpp create mode 100644 include/neural_network/loss/loss.hpp create mode 100644 include/neural_network/loss/loss_categorical_crossentropy.hpp create mode 100644 src/math/log.cpp create mode 100644 src/math/mean.cpp create mode 100644 src/neural_network/loss/loss.cpp create mode 100644 src/neural_network/loss/loss_categorical_crossentropy.cpp diff --git a/include/math/clip.hpp b/include/math/clip.hpp index 45ef87d..85ff284 100644 --- a/include/math/clip.hpp +++ b/include/math/clip.hpp @@ -702,6 +702,106 @@ panic::tensor::matrix clip_higher_colwise(const panic::tensor::matrix& A, + + + + + + + + + + + + + + + +/** + * @brief Clips values in the vector or scalar. + * + * Computes: + * @code + + * @endcode + * + * @tparam T Numeric element type. + * @param a Input vector. + * @param lower Scalar value compared to each element of @p a. + * @param higher 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(const panic::tensor::vector& a, const T lower, const T higher, const panic::tensor::vector& c); + +/** + * @brief Returns a cliped value in the vector. + * + * Computes: + * @code + * @endcode + * + * @tparam T Numeric element type. + * @param a Input vector. + * @param lower Scalar value compared to each element of @p a. + * @param higher 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(const panic::tensor::vector& a, const T lower, const T higher); + + +/** + * @brief Clips the elementwise in the matrix. + * + * Computes: + * @code + * @endcode + * + * @tparam T Numeric element type. + * @param A Input matrix. + * @param lower Scalar value compared to each element of @p a. + * @param higher 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(const panic::tensor::matrix& A, const T lower, const T higher, panic::tensor::matrix& C); + +/** + * @brief Returns a new matrix containing the cliped min elementwise in the matrix. + * + * Computes: + * @code + * @endcode + * + * @tparam T Numeric element type. + * @param A Input matrix. + * @param lower Scalar value compared to each element of @p a. + * @param higher 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(const panic::tensor::matrix& A, const T lower, const T higher); diff --git a/include/math/log.hpp b/include/math/log.hpp new file mode 100644 index 0000000..bf2e939 --- /dev/null +++ b/include/math/log.hpp @@ -0,0 +1,144 @@ +/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * + * 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: log.cpp + * Revision: 0.1.0 + * Date: 29-07-2026 + * Author: Michelle Bausager + * + * Description: + * Functions to calculate the logorithem 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/mean.hpp b/include/math/mean.hpp new file mode 100644 index 0000000..626b630 --- /dev/null +++ b/include/math/mean.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: mean.hpp + * Revision: 0.1.0 + * Date: 30-07-2026 + * Author: Michelle Bausager + * + * Description: + * Functions to calculate mean of tensor arrays + * + *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +#pragma once + +#include // for panic::vector +#include // for panic::matrix + + +namespace panic{ +namespace math{ + + + + +/** + * @brief Returns the mean value of a vector + * + * Computes: + * @code + * result = mean(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 mean(const panic::tensor::vector& a); + +/** + * @brief Returns the mean value of a matrix. + * + * Computes: + * @code + * result = mean(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 mean(const panic::tensor::matrix& A); + +/** + * @brief Find the mean values row-wise of a matrix. + * + * Computes: + * @code + * c(i) = mean(A(i,j)) + * @endcode + * + * @tparam T Numeric element type. + * @param A Input matrix. + * @param c Output vector. 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 mean_rowwise(const panic::tensor::matrix& A, panic::tensor::vector& c); + +/** + * @brief Returns a new matrix containing the mean row-wise elementwise. + * + * Computes: + * @code + * result[i] = mean(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 mean_rowwise(const panic::tensor::matrix& A); + + +/** + * @brief Find the mean values column-wise of a matrix. + * + * Computes: + * @code + * C(j) = mean(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 mean_colwise(const panic::tensor::matrix& A, panic::tensor::vector& c); + +/** + * @brief Returns a new matrix containing the mean column-wise elementwise. + * + * Computes: + * @code + * result[j] = mean(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 mean_colwise(const panic::tensor::matrix& A); + +} // namespace math +} // namespace panic \ No newline at end of file diff --git a/include/neural_network/loss/loss.hpp b/include/neural_network/loss/loss.hpp new file mode 100644 index 0000000..0fc6a08 --- /dev/null +++ b/include/neural_network/loss/loss.hpp @@ -0,0 +1,134 @@ +/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * + * 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: neural_network + * File Name: loss.hpp + * Revision: 0.1.0 + * Date: 30-07-2026 + * Author: Michelle Bausager + * + * Description: + * Defines the base loss struct used in other loss functions in neural network + * + *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +#pragma once +//--------------------------------------------------------------------------------------------------------------------------- +// INCLUDE DESCRIPTION +//--------------------------------------------------------------------------------------------------------------------------- +#include // panic::uint_t, panic::int_t, and panic::real_t +#include // panic::tensor::real_matrix (uint_matrix, int_matrix) +#include + + +namespace panic{ + namespace neural_network{ + + + +/** + * @brief Base loss for the rest of the neural network library to use + * + * This base layer should be used in all loss functions. + * This is done so it's easy to make new loss functions in the model. + * The virtual means it should use derived object's version when called with a pointer. + * The derived object can use overloading on forward, or just use one of them, to support one-shot encoding. + * + * The struct is used for PANIC neural_network library. + */ +struct loss{ + + /** + * @brief Emphty vector to store sample losses + * + */ + panic::tensor::real_vector sample_losses; + + /** + * @brief Mean loss over the entire batch. + */ + panic::types::real_t data_loss; + + /** + * @brief Default de-constructor + * + */ + virtual ~loss() = default; + + + /** + * @brief Virtual forward function for derivative loss functions + * + * @param y_pred Matrix of model predection. + * @param y_true Vector of true label of data. + * + * @Note If the derivatived object does not use this, + * it returns false. + */ + virtual bool forward( + const panic::tensor::real_matrix& y_pred, + const panic::tensor::uint_vector& y_true); + + /** + * @brief Virtual forward function for derivative loss functions + * + * @param y_pred Matrix of model predection. + * @param y_true Matrix of true label of data. + * + * @Note If the derivatived object does not use this, + * it returns false. + */ + virtual bool forward( + const panic::tensor::real_matrix& y_pred, + const panic::tensor::real_matrix& y_true); + + /** + * @brief Virtual calculate function that calculates the loss + * + * @param y_pred Matrix of model predection. + * @param y_true Vector of true label of data. + * + */ + bool calculate( + const panic::tensor::real_matrix& y_pred, + const panic::tensor::uint_vector& y_true); + + /** + * @brief Virtual calculate function that calculates the loss + * + * @param y_pred Matrix of model predection. + * @param y_true Matrix of true label of data. + * + */ + bool calculate( + const panic::tensor::real_matrix& y_pred, + const panic::tensor::real_matrix& y_true); + +}; + + + + } // namespace neural_network +} // namespace panic + + + diff --git a/include/neural_network/loss/loss_categorical_crossentropy.hpp b/include/neural_network/loss/loss_categorical_crossentropy.hpp new file mode 100644 index 0000000..ffd04aa --- /dev/null +++ b/include/neural_network/loss/loss_categorical_crossentropy.hpp @@ -0,0 +1,93 @@ +/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * + * 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: neural_network + * File Name: loss_categorical_crossentropy.hpp + * Revision: 0.1.0 + * Date: 30-07-2026 + * Author: Michelle Bausager + * + * Description: + * Defines the base loss_categorical_crossentropy used in neural network + * + *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +#pragma once +//--------------------------------------------------------------------------------------------------------------------------- +// INCLUDE DESCRIPTION +//--------------------------------------------------------------------------------------------------------------------------- +#include +#include +#include // panic::uint_t, panic::int_t, and panic::real_t +#include // panic::tensor::real_matrix (uint_matrix, int_matrix) +#include + + +namespace panic{ + namespace neural_network{ + + + +/** + * @brief loss_categorical_crossentropy used in the rest of the neural network library + * + * + * The struct is used for PANIC neural_network library. + */ +struct loss_categorical_crossentropy: loss{ + + + + + /** + * @brief forward function to calculate losses + * + * @param y_pred Matrix of model predection. + * @param y_true Vector of true label of data. + * + */ + bool forward( + const panic::tensor::real_matrix& y_pred, + const panic::tensor::uint_vector& y_true); + + /** + * @brief forward function to calculate losses + * + * @param y_pred Matrix of model predection. + * @param y_true Vector of true label of data. + * + * @Note Overloaded if one-shot endcoded + * is used. + */ + bool forward( + const panic::tensor::real_matrix& y_pred, + const panic::tensor::real_matrix& y_true); + +}; + + + + } // namespace neural_network +} // namespace panic + + + diff --git a/main.cpp b/main.cpp index c815c37..e31d6fd 100644 --- a/main.cpp +++ b/main.cpp @@ -58,6 +58,7 @@ #include #include #include +#include #include diff --git a/src/math/clip.cpp b/src/math/clip.cpp index 33b3fc3..2321378 100644 --- a/src/math/clip.cpp +++ b/src/math/clip.cpp @@ -51,7 +51,7 @@ * 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; +static const panic::types::uint_t clip_omp_min_work = 500; //--------------------------------------------------------------------------------------------------------------------------- // INPLEMENTATION //--------------------------------------------------------------------------------------------------------------------------- @@ -73,7 +73,7 @@ bool clip_lower(const panic::tensor::vector& a, const T k, panic::tensor::vec return false; } - PANIC_OMP_PARALLEL_FOR_IF(a.size() > max_omp_min_work) + PANIC_OMP_PARALLEL_FOR_IF(a.size() > clip_omp_min_work) for (panic::types::uint_t i = 0; i < a.size(); ++i){ if (a[i] < k){ c[i] = k; @@ -162,7 +162,7 @@ bool clip_lower(const panic::tensor::vector& a, const panic::tensor::vector max_omp_min_work) + PANIC_OMP_PARALLEL_FOR_IF(a.size() > clip_omp_min_work) for (panic::types::uint_t i = 0; i < a.size(); ++i){ if (a[i] < b[i]){ c[i] = b[i]; @@ -248,7 +248,7 @@ bool clip_lower(const panic::tensor::matrix& A, const T k, panic::tensor::mat } - PANIC_OMP_PARALLEL_FOR_IF(work > max_omp_min_work) + PANIC_OMP_PARALLEL_FOR_IF(work > clip_omp_min_work) for (panic::types::uint_t i = 0; i < rows; ++i){ for (panic::types::uint_t j = 0; j < cols; ++j){ @@ -344,7 +344,7 @@ bool clip_lower(const panic::tensor::matrix& A, const panic::tensor::matrix max_omp_min_work) + PANIC_OMP_PARALLEL_FOR_IF(work > clip_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)){ @@ -438,7 +438,7 @@ bool clip_lower_rowwise(const panic::tensor::matrix& A, const panic::tensor:: } - PANIC_OMP_PARALLEL_FOR_IF(work > max_omp_min_work) + PANIC_OMP_PARALLEL_FOR_IF(work > clip_omp_min_work) for (panic::types::uint_t i = 0; i < rows; ++i){ for (panic::types::uint_t j = 0; j < cols; ++j){ @@ -536,7 +536,7 @@ bool clip_lower_colwise(const panic::tensor::matrix& A, const panic::tensor:: } - PANIC_OMP_PARALLEL_FOR_IF(work > max_omp_min_work) + PANIC_OMP_PARALLEL_FOR_IF(work > clip_omp_min_work) for (panic::types::uint_t i = 0; i < rows; ++i){ for (panic::types::uint_t j = 0; j < cols; ++j){ @@ -658,7 +658,7 @@ bool clip_higher(const panic::tensor::vector& a, const T k, panic::tensor::ve return false; } - PANIC_OMP_PARALLEL_FOR_IF(a.size() > max_omp_min_work) + PANIC_OMP_PARALLEL_FOR_IF(a.size() > clip_omp_min_work) for (panic::types::uint_t i = 0; i < a.size(); ++i){ if (a[i] > k){ c[i] = k; @@ -747,7 +747,7 @@ bool clip_higher(const panic::tensor::vector& a, const panic::tensor::vector< return false; } - PANIC_OMP_PARALLEL_FOR_IF(a.size() > max_omp_min_work) + PANIC_OMP_PARALLEL_FOR_IF(a.size() > clip_omp_min_work) for (panic::types::uint_t i = 0; i < a.size(); ++i){ if (a[i] > b[i]){ c[i] = b[i]; @@ -833,7 +833,7 @@ bool clip_higher(const panic::tensor::matrix& A, const T k, panic::tensor::ma } - PANIC_OMP_PARALLEL_FOR_IF(work > max_omp_min_work) + PANIC_OMP_PARALLEL_FOR_IF(work > clip_omp_min_work) for (panic::types::uint_t i = 0; i < rows; ++i){ for (panic::types::uint_t j = 0; j < cols; ++j){ @@ -929,7 +929,7 @@ bool clip_higher(const panic::tensor::matrix& A, const panic::tensor::matrix< } - PANIC_OMP_PARALLEL_FOR_IF(work > max_omp_min_work) + PANIC_OMP_PARALLEL_FOR_IF(work > clip_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)){ @@ -1023,7 +1023,7 @@ bool clip_higher_rowwise(const panic::tensor::matrix& A, const panic::tensor: } - PANIC_OMP_PARALLEL_FOR_IF(work > max_omp_min_work) + PANIC_OMP_PARALLEL_FOR_IF(work > clip_omp_min_work) for (panic::types::uint_t i = 0; i < rows; ++i){ for (panic::types::uint_t j = 0; j < cols; ++j){ @@ -1121,7 +1121,7 @@ bool clip_higher_colwise(const panic::tensor::matrix& A, const panic::tensor: } - PANIC_OMP_PARALLEL_FOR_IF(work > max_omp_min_work) + PANIC_OMP_PARALLEL_FOR_IF(work > clip_omp_min_work) for (panic::types::uint_t i = 0; i < rows; ++i){ for (panic::types::uint_t j = 0; j < cols; ++j){ @@ -1229,5 +1229,236 @@ template panic::tensor::matrix + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::clip +// +// Description: +// Clips of vector compared with scalar +//-------------------------------------------------------------------------------------------------------------------------- +template +bool clip(const panic::tensor::vector& a, const T lower, const T higher, panic::tensor::vector& c){ + + if (!c.resize(a.size())){ + return false; + } + + PANIC_OMP_PARALLEL_FOR_IF(a.size() > clip_omp_min_work) + for (panic::types::uint_t i = 0; i < a.size(); ++i){ + if (a[i] < lower){ + c[i] = lower; + } + else if(a[i] > higher){ + c[i] = higher; + } + 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(const panic::tensor::vector& a, + const panic::types::uint_t lower, + const panic::types::uint_t higher, + panic::tensor::vector& c +); +template bool clip(const panic::tensor::vector& a, + const panic::types::int_t lower, + const panic::types::int_t higher, + panic::tensor::vector& c +); +template bool clip(const panic::tensor::vector& a, + const panic::types::real_t lower, + const panic::types::real_t higher, + panic::tensor::vector& c +); + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::clip +// +// Description: +// Clips of vector compared with scalar +//-------------------------------------------------------------------------------------------------------------------------- +template +panic::tensor::vector clip(const panic::tensor::vector& a, const T lower, const T higher){ + panic::tensor::vector c(a.size()); + + if (!clip(a, lower, higher, 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(const panic::tensor::vector& a, + const panic::types::uint_t lower, + const panic::types::uint_t higher +); +template panic::tensor::vector + clip(const panic::tensor::vector& a, + const panic::types::int_t lower, + const panic::types::int_t higher +); +template panic::tensor::vector + clip(const panic::tensor::vector& a, + const panic::types::real_t lower, + const panic::types::real_t higher +); + + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::clip +// +// Description: +// Clips of matrix compared with scalar +//-------------------------------------------------------------------------------------------------------------------------- +template +bool clip(const panic::tensor::matrix& A, const T lower, const T higher, 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 > clip_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) < lower){ + C(i,j) = lower; + } + else if(A(i,j) > higher){ + C(i,j) = higher; + } + 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(const panic::tensor::matrix& A, + const panic::types::uint_t lower, + const panic::types::uint_t higher, + panic::tensor::matrix& C +); +template bool clip(const panic::tensor::matrix& A, + const panic::types::int_t lower, + const panic::types::int_t higher, + panic::tensor::matrix& C +); +template bool clip(const panic::tensor::matrix& A, + const panic::types::real_t lower, + const panic::types::real_t higher, + panic::tensor::matrix& C +); + + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::clip +// +// Description: +// Clips of matrix compared with scalar +//-------------------------------------------------------------------------------------------------------------------------- +template +panic::tensor::matrix clip(const panic::tensor::matrix& A, const T lower, const T higher){ + panic::tensor::matrix C; + + if (!clip(A, lower, higher, 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(const panic::tensor::matrix& A, + const panic::types::uint_t lower, + const panic::types::uint_t higher +); +template panic::tensor::matrix + clip(const panic::tensor::matrix& A, + const panic::types::int_t lower, + const panic::types::int_t higher +); +template panic::tensor::matrix + clip(const panic::tensor::matrix& A, + const panic::types::real_t lower, + const panic::types::real_t higher +); + + + + + } // namespace math } // namespace panic diff --git a/src/math/log.cpp b/src/math/log.cpp new file mode 100644 index 0000000..fc004d4 --- /dev/null +++ b/src/math/log.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: log.cpp + * Revision: 0.1.0 + * Date: 29-07-2026 + * Author: Michelle Bausager + * + * Description: + * Functions to calculate the logorithem 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/mean.cpp b/src/math/mean.cpp new file mode 100644 index 0000000..3103990 --- /dev/null +++ b/src/math/mean.cpp @@ -0,0 +1,316 @@ +/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * + * 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: mean.cpp + * Revision: 0.1.0 + * Date: 30-07-2026 + * Author: Michelle Bausager + * + * Description: + * Functions to calculate mean of tensor arrays + * + *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ + +//--------------------------------------------------------------------------------------------------------------------------- +// INCLUDE DESCRIPTION +//----------------------------------------------------------------------------------------------------- + +#include +#include + +#include // for panic::vector +#include // for panic::matrix + +#include + +//--------------------------------------------------------------------------------------------------------------------------- +// 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 mean_omp_min_work = 500; +//--------------------------------------------------------------------------------------------------------------------------- +// INPLEMENTATION +//--------------------------------------------------------------------------------------------------------------------------- + +namespace panic { + namespace math { + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::mean +// +// Description: +// Find the mean value for a vector +//-------------------------------------------------------------------------------------------------------------------------- +template +T mean(const panic::tensor::vector& a){ + + T sum = panic::math::sum(a); + + return sum / static_cast(a.size()); +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template panic::types::uint_t mean(const panic::tensor::vector& a +); +template panic::types::int_t mean(const panic::tensor::vector& a +); +template panic::types::real_t mean(const panic::tensor::vector& a +); + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::mean +// +// Description: +// Find the mean value for a matrix +//-------------------------------------------------------------------------------------------------------------------------- +template +T mean(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 sum = panic::math::sum(A); + + return sum / static_cast(work); +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template panic::types::uint_t mean(const panic::tensor::matrix& a +); +template panic::types::int_t mean(const panic::tensor::matrix& a +); +template panic::types::real_t mean(const panic::tensor::matrix& a +); + + + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::mean_rowwise +// +// Description: +// Find the mean row-wise of a matrix +//-------------------------------------------------------------------------------------------------------------------------- +template +bool mean_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; + } + + if (!sum_rowwise(A, b)){ + return false; + } + + + // Each thread handles separate rows and writes to a separate b[i]. + PANIC_OMP_PARALLEL_FOR_IF(rows > mean_omp_min_work) + for (panic::types::uint_t i = 0; i < rows; ++i){ + b[i] /= cols; + + } + + return true; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template bool mean_rowwise(const panic::tensor::matrix& A, + panic::tensor::vector& b +); +template bool mean_rowwise(const panic::tensor::matrix& A, + panic::tensor::vector& b +); +template bool mean_rowwise(const panic::tensor::matrix& A, + panic::tensor::vector& b +); + + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::mean_rowwise +// +// Description: +// Returns row-wise sum values +//-------------------------------------------------------------------------------------------------------------------------- +template +panic::tensor::vector mean_rowwise(const panic::tensor::matrix& A){ + panic::tensor::vector b; + + if (!mean_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 + mean_rowwise(const panic::tensor::matrix& A +); +template panic::tensor::vector + mean_rowwise(const panic::tensor::matrix& A +); +template panic::tensor::vector + mean_rowwise(const panic::tensor::matrix& A +); + + + + + + + + + + + + + + + + + + + + + + + + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::mean_colwise +// +// Description: +// Find the mean column-wise of a matrix +//-------------------------------------------------------------------------------------------------------------------------- +template +bool mean_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; + } + + if (! sum_colwise(A,b)){ + return false; + } + + // Each thread handles separate cols and writes to a separate b[i]. + PANIC_OMP_PARALLEL_FOR_IF(work > mean_omp_min_work) + for (panic::types::uint_t i = 0; i < cols; ++i){ + b[i] /= cols; + } + + return true; +} +//-------------------------------------------------------------------------------------------------------------------------- +// EXPLICIT TEMPLATE INSTANTIATION +// +// The implementation is in this .cpp file. +// Build the overload for the official PANIC numeric types. +//-------------------------------------------------------------------------------------------------------------------------- +template bool mean_colwise(const panic::tensor::matrix& A, + panic::tensor::vector& b +); +template bool mean_colwise(const panic::tensor::matrix& A, + panic::tensor::vector& b +); +template bool mean_colwise(const panic::tensor::matrix& A, + panic::tensor::vector& b +); + + + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::math::mean_colwise +// +// Description: +// Returns column-wise mean values +//-------------------------------------------------------------------------------------------------------------------------- +template +panic::tensor::vector mean_colwise(const panic::tensor::matrix& A){ + panic::tensor::vector b; + + if (!mean_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 + mean_colwise(const panic::tensor::matrix& A +); +template panic::tensor::vector + mean_colwise(const panic::tensor::matrix& A +); +template panic::tensor::vector + mean_colwise(const panic::tensor::matrix& A +); + + + } // namespace math +} // namespace panic diff --git a/src/neural_network/loss/loss.cpp b/src/neural_network/loss/loss.cpp new file mode 100644 index 0000000..33ac345 --- /dev/null +++ b/src/neural_network/loss/loss.cpp @@ -0,0 +1,166 @@ +/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * + * 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: neural_network + * File Name: loss.cpp + * Revision: 0.1.0 + * Date: 30-07-2026 + * Author: Michelle Bausager + * + * Description: + * Defines the base loss struct used in other loss functions in neural network + * + *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +//--------------------------------------------------------------------------------------------------------------------------- +// INCLUDE DESCRIPTION +//--------------------------------------------------------------------------------------------------------------------------- +#include +#include +#include // panic::uint_t, panic::int_t, and panic::real_t +#include // panic::tensor::real_matrix (uint_matrix, int_matrix) +#include + +#include + + +//--------------------------------------------------------------------------------------------------------------------------- +// 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 loss_omp_min_size = 500; +//--------------------------------------------------------------------------------------------------------------------------- + + +namespace panic{ + namespace neural_network{ + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::neural_network::loss::calculate +// +// Description: +// Calculates the mean loss on class targets. +//-------------------------------------------------------------------------------------------------------------------------- +bool loss::calculate( + const panic::tensor::real_matrix& y_pred, + const panic::tensor::uint_vector& y_true){ + + // Calculate sample losses + if (!forward(y_pred, y_true)){ + return false; + } + + // Calculate mean loss + data_loss = panic::math::mean(sample_losses); + + //return calculate_mean(); + return true; +} + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::neural_network::loss::calculate +// +// Description: +// Calculates the mean loss using matrix targets. +//-------------------------------------------------------------------------------------------------------------------------- +bool loss::calculate( + const panic::tensor::real_matrix& y_pred, + const panic::tensor::real_matrix& y_true){ + + if (!forward(y_pred, y_true)){ + return false; + } + + //return calculate_mean(); + return true; +} + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::neural_network::loss::forward +// +// Description: +// Default implementation. Derived classes can override it. +//-------------------------------------------------------------------------------------------------------------------------- +bool loss::forward( + const panic::tensor::real_matrix& y_pred, + const panic::tensor::uint_vector& y_true){ + + return false; +} + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::neural_network::loss::forward +// +// Description: +// Default matrix-target implementation. Derived classes can override it. +//-------------------------------------------------------------------------------------------------------------------------- +bool loss::forward( + const panic::tensor::real_matrix& y_pred, + const panic::tensor::real_matrix& y_true){ + + return false; +} + +/* + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::neural_network::loss::calculate_mean +// +// Description: +// Calculates the average of all sample loss values. +//-------------------------------------------------------------------------------------------------------------------------- +bool loss::calculate_mean(){ + + if (sample_losses.size() == 0){ + return false; + } + + panic::types::real_t sum = + static_cast(0); + + for ( + panic::types::uint_t i = 0; + i < sample_losses.size(); + ++i + ){ + sum += sample_losses[i]; + } + + data_loss = + sum / + static_cast(sample_losses.size()); + + return true; +} +*/ + + } // namespace tensor +} // namespace panic + + + diff --git a/src/neural_network/loss/loss_categorical_crossentropy.cpp b/src/neural_network/loss/loss_categorical_crossentropy.cpp new file mode 100644 index 0000000..ff4229a --- /dev/null +++ b/src/neural_network/loss/loss_categorical_crossentropy.cpp @@ -0,0 +1,94 @@ +/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * + * 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: neural_network + * File Name: loss_categorical_crossentropy.hpp + * Revision: 0.1.0 + * Date: 30-07-2026 + * Author: Michelle Bausager + * + * Description: + * Defines the base loss_categorical_crossentropy used in neural network + * + *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +//--------------------------------------------------------------------------------------------------------------------------- +// INCLUDE DESCRIPTION +//--------------------------------------------------------------------------------------------------------------------------- +#include +#include +#include // panic::uint_t, panic::int_t, and panic::real_t +#include // panic::tensor::real_matrix (uint_matrix, int_matrix) +#include + +#include + + +//--------------------------------------------------------------------------------------------------------------------------- +// 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 loss_categorical_crossentropy_omp_min_size = 500; +//--------------------------------------------------------------------------------------------------------------------------- + + +namespace panic{ + namespace neural_network{ + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::neural_network::loss_categorical_crossentropy::forward +// +// Description: +// Default implementation. Derived classes can override it. +//-------------------------------------------------------------------------------------------------------------------------- +bool loss_categorical_crossentropy::forward( + const panic::tensor::real_matrix& y_pred, + const panic::tensor::uint_vector& y_true){ + + return false; +} + + +//-------------------------------------------------------------------------------------------------------------------------- +// Function Name : panic::neural_network::loss_categorical_crossentropy::forward +// +// Description: +// Default matrix-target implementation. Derived classes can override it. +//-------------------------------------------------------------------------------------------------------------------------- +bool loss_categorical_crossentropy::forward( + const panic::tensor::real_matrix& y_pred, + const panic::tensor::real_matrix& y_true){ + + return false; +} + + + } // namespace tensor +} // namespace panic + + +