/**++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * * 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 //--------------------------------------------------------------------------------------------------------------------------- // DEFINE DESCRIPTION //--------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------- // TYPE DESCRIPTION //--------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------- // VARIABLE DESCRIPTION //--------------------------------------------------------------------------------------------------------------------------- static const panic::uint_t matrix_omp_min_size = 10000; //--------------------------------------------------------------------------------------------------------------------------- // FUNCTION PROTOTYPE //--------------------------------------------------------------------------------------------------------------------------- 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::uint_t rows, panic::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::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::uint_t rows, panic::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::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 like this: // matrix A(3); // matrix B = A; //-------------------------------------------------------------------------------------------------------------------------- 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::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 like this: // matrix A(5); // matrix B(3); // B = A; //-------------------------------------------------------------------------------------------------------------------------- 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(length > matrix_omp_min_size) for (panic::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::uint_t matrix::rows() const{ return n; } //-------------------------------------------------------------------------------------------------------------------------- // Function Name : panic::tensor::matrix::cols // // Description: // Returns the length/size of the matrix //-------------------------------------------------------------------------------------------------------------------------- template panic::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::uint_t new_n, panic::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::uint_t new_length = new_n*new_m; T* new_data = new T[new_length]; panic::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::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::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::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::uint_t index_n, panic::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::uint_t index_n, panic::uint_t index_m) const{ return data[index_n*m + index_m]; } //--------------------------------------------------------------------------------------------------------------------------- // EXPLICIT TEMPLATE INSTANTIATION //--------------------------------------------------------------------------------------------------------------------------- template struct matrix; template struct matrix; template struct matrix; } // namespace tensor } // namespace panic