/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * * 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: tensor * File Name: matrix.cpp * Revision: 0.1.0 * Date: 23-06-2026 * Author: Michelle Bausager * * Description: * Defines the matrix object that will be used in the rest of the libraries. * *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ //--------------------------------------------------------------------------------------------------------------------------- // INCLUDE DESCRIPTION //--------------------------------------------------------------------------------------------------------------------------- #include #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 matrix_omp_min_size = 500; namespace panic{ namespace tensor{ //-------------------------------------------------------------------------------------------------------------------------- // Constructor Name : panic::tensor::matrix::matrix // // Description: // Creates an empty matrix. //-------------------------------------------------------------------------------------------------------------------------- template matrix::matrix() { n = 0; m = 0; length = 0; data = 0; } //-------------------------------------------------------------------------------------------------------------------------- // Constructor Name : panic::tensor::matrix::matrix // // Description: // Creates a matrix with size allocation and initializes all values to zero. //-------------------------------------------------------------------------------------------------------------------------- template matrix::matrix(panic::types::uint_t rows, panic::types::uint_t cols){ n = rows; m = cols; length = n*m; if (length == 0){ data = 0; return; } data = new T[length]; PANIC_OMP_PARALLEL_FOR_IF(length > matrix_omp_min_size) for (panic::types::uint_t i = 0; i < length; ++i){ data[i] = static_cast(0); } } //-------------------------------------------------------------------------------------------------------------------------- // Constructor Name : panic::tensor::matrix::matrix // // Description: // Creates a matrix with size allocation and initializes all values. //-------------------------------------------------------------------------------------------------------------------------- template matrix::matrix(panic::types::uint_t rows, panic::types::uint_t cols, T value){ n = rows; m = cols; length = n*m; if (length == 0){ data = 0; return; } data = new T[length]; PANIC_OMP_PARALLEL_FOR_IF(length > matrix_omp_min_size) for (panic::types::uint_t i = 0; i < length; ++i){ data[i] = value; } } //-------------------------------------------------------------------------------------------------------------------------- // Constructor Name : panic::tensor::matrix::matrix // // Description: // Copy-contructor, makes a deep copy of another matrix //-------------------------------------------------------------------------------------------------------------------------- template matrix::matrix(const matrix& other){ n = other.n; m = other.m; length = other.length; if (length == 0){ data = 0; return; } data = new T[length]; PANIC_OMP_PARALLEL_FOR_IF(length > matrix_omp_min_size) for (panic::types::uint_t i = 0; i < length; ++i){ data[i] = other.data[i]; } } //-------------------------------------------------------------------------------------------------------------------------- // Deconstructor Name : panic::tensor::matrix::~matrix // // Description: // Deletes the data and releases the memory. //-------------------------------------------------------------------------------------------------------------------------- template matrix::~matrix(){ delete[] data; data = 0; n = 0; m = 0; length = 0; } //-------------------------------------------------------------------------------------------------------------------------- // Function Name : panic::tensor::matrix::operator= // // Description: // Copy-assignment. Copies from another matrix. //-------------------------------------------------------------------------------------------------------------------------- template matrix& matrix::operator=(const matrix& other){ if (this == &other){ return *this; } T* new_data = 0; if (other.length > 0){ new_data = new T[other.length]; PANIC_OMP_PARALLEL_FOR_IF(other.length > matrix_omp_min_size) for (panic::types::uint_t i = 0; i < other.length; ++i){ new_data[i] = other.data[i]; } } delete[] data; data = new_data; n = other.n; m = other.m; length = other.length; return *this; } //-------------------------------------------------------------------------------------------------------------------------- // Function Name : panic::tensor::matrix::rows // // Description: // Returns the length/size of the matrix //-------------------------------------------------------------------------------------------------------------------------- template panic::types::uint_t matrix::rows() const{ return n; } //-------------------------------------------------------------------------------------------------------------------------- // Function Name : panic::tensor::matrix::cols // // Description: // Returns the length/size of the matrix //-------------------------------------------------------------------------------------------------------------------------- template panic::types::uint_t matrix::cols() const{ return m; } //-------------------------------------------------------------------------------------------------------------------------- // Function Name : panic::tensor::matrix::resize // // Description: // Resizes the matrix to new dimentions and keeps old values //-------------------------------------------------------------------------------------------------------------------------- template bool matrix::resize(panic::types::uint_t new_n, panic::types::uint_t new_m){ if ((new_n == n) && (new_m == m)){ return true; } if ((new_n == 0) || (new_m == 0)){ delete[] data; n = 0; m = 0; length = 0; data = 0; return true; } panic::types::uint_t new_length = new_n*new_m; T* new_data = new T[new_length]; panic::types::uint_t copy_size = length; if (new_length < length){ copy_size = new_length; } PANIC_OMP_PARALLEL_FOR_IF(copy_size > matrix_omp_min_size) for (panic::types::uint_t i = 0; i < copy_size; ++i){ new_data[i] = data[i]; } PANIC_OMP_PARALLEL_FOR_IF(new_length - copy_size > matrix_omp_min_size) for (panic::types::uint_t i = copy_size; i < new_length; ++i){ new_data[i] = static_cast(0); } delete[] data; data = new_data; n = new_n; m = new_m; length = new_length; return true; } //-------------------------------------------------------------------------------------------------------------------------- // Function Name : panic::tensor::matrix::fill // // Description: // Fills te matrix with a value //-------------------------------------------------------------------------------------------------------------------------- template bool matrix::fill(T value){ PANIC_OMP_PARALLEL_FOR_IF(length > matrix_omp_min_size) for (panic::types::uint_t i = 0; i < length; ++i){ data[i] = value; } return true; } //-------------------------------------------------------------------------------------------------------------------------- // Function Name : panic::tensor::matrix::operator() // // Description: // Lets you read and write A(2,3) //-------------------------------------------------------------------------------------------------------------------------- template T& matrix::operator()(panic::types::uint_t index_n, panic::types::uint_t index_m){ return data[index_n*m + index_m]; } //-------------------------------------------------------------------------------------------------------------------------- // Function Name : panic::tensor::matrix::operator[] // // Description: // Lets you read A(2,3) from a const matrix //-------------------------------------------------------------------------------------------------------------------------- template const T& matrix::operator()(panic::types::uint_t index_n, panic::types::uint_t index_m) const{ return data[index_n*m + index_m]; } //-------------------------------------------------------------------------------------------------------------------------- // Function Name : panic::tensor::matrix::set_row // // Description: // Filles and set a row to a value. //-------------------------------------------------------------------------------------------------------------------------- template bool matrix::set_row(const panic::types::uint_t index_row, const T c){ PANIC_OMP_PARALLEL_FOR_IF(m > matrix_omp_min_size) for (panic::types::uint_t i = 0; i < m; ++i){ data[index_row*m + i] = c; } return true; } //-------------------------------------------------------------------------------------------------------------------------- // Function Name : panic::tensor::matrix::set_row // // Description: // Filles and set a row to a vector. //-------------------------------------------------------------------------------------------------------------------------- template bool matrix::set_row(const panic::types::uint_t index_row, const panic::tensor::vector v){ if (m != v.size()){ return false; } PANIC_OMP_PARALLEL_FOR_IF(m > matrix_omp_min_size) for (panic::types::uint_t i = 0; i < m; ++i){ data[index_row*m + i] = v[i]; } return true; } //-------------------------------------------------------------------------------------------------------------------------- // Function Name : panic::tensor::matrix::set_col // // Description: // Filles and set a column to a value. //-------------------------------------------------------------------------------------------------------------------------- template bool matrix::set_col(const panic::types::uint_t index_col, const T c){ PANIC_OMP_PARALLEL_FOR_IF(n > matrix_omp_min_size) for (panic::types::uint_t i = 0; i < n; ++i){ data[i*m + index_col] = c; } return true; } //-------------------------------------------------------------------------------------------------------------------------- // Function Name : panic::tensor::matrix::set_col // // Description: // Filles and set a colmn to a vector. //-------------------------------------------------------------------------------------------------------------------------- template bool matrix::set_col(const panic::types::uint_t index_col, const panic::tensor::vector v){ if (n != v.size()){ return false; } PANIC_OMP_PARALLEL_FOR_IF(n > matrix_omp_min_size) for (panic::types::uint_t i = 0; i < n; ++i){ data[i*m + index_col] = v[i]; } return true; } //--------------------------------------------------------------------------------------------------------------------------- // EXPLICIT TEMPLATE INSTANTIATION //--------------------------------------------------------------------------------------------------------------------------- template struct matrix; template struct matrix; template struct matrix; } // namespace tensor } // namespace panic