跳转至

测试

Tip

以下的测试用代码和案例也作为使用教学案例。

tiny_matrix_test.hpp

/**
 * @file tiny_matrix_test.hpp
 * @author SHUAIWEN CUI (SHUAIWEN001@e.ntu.edu.sg)
 * @brief This file is the header file for the test of the submodule matrix (advanced matrix operations) of the tiny_math middleware.
 * @version 1.0
 * @date 2025-04-17
 * @copyright Copyright (c) 2025
 *
 */

#pragma once

/* DEPENDENCIES */
#include "tiny_matrix.hpp" // TinyMatrix Header

/* STATEMENTS */
void tiny_matrix_test();  // C-compatible test entry

tiny_matrix_test.cpp

/**
 * @file tiny_matrix_test.cpp
 * @author SHUAIWEN CUI (SHUAIWEN001@e.ntu.edu.sg)
 * @brief This file is the source file for the test of the submodule matrix (advanced matrix operations) of the tiny_math middleware.
 * @version 1.0
 * @date 2025-04-17
 * @copyright Copyright (c) 2025
 *
 */

/* DEPENDENCIES */
#include "tiny_matrix_test.hpp" // TinyMatrix Test Header
#include "tiny_time.h"           // For performance testing

#include <iostream>
#include <iomanip>
#include <cmath>
#include <sstream>  // For std::istringstream (used in stream operator tests)

#if MCU_PLATFORM_SELECTED == MCU_PLATFORM_ESP32
#include "esp_task_wdt.h"       // For FreeRTOS task watchdog
#endif

/* PERFORMANCE TESTING MACROS */
// Reduced matrix sizes and iterations to prevent watchdog timeout and memory issues
#define PERFORMANCE_TEST_ITERATIONS 100        // Reduced from 1000 to prevent timeout
#define PERFORMANCE_TEST_ITERATIONS_HEAVY 10   // Reduced from 100 for compute-intensive operations
#define PERFORMANCE_TEST_WARMUP 3              // Reduced from 10

// Macro for timing a single operation
#define TIME_OPERATION(operation, description) \
    do { \
        TinyTimeMark_t t0 = tiny_get_running_time(); \
        operation; \
        TinyTimeMark_t t1 = tiny_get_running_time(); \
        double dt_us = (double)(t1 - t0); \
        std::cout << "[Performance] " << description << ": " << std::fixed << std::setprecision(2) << dt_us << " us\n"; \
    } while(0)

// Helper function to feed watchdog (inline to avoid function call overhead in tight loops)
#if MCU_PLATFORM_SELECTED == MCU_PLATFORM_ESP32
// Static flag to track if task has been added to watchdog
static bool task_wdt_added = false;

inline void ensure_task_wdt_added()
{
    if (!task_wdt_added)
    {
        esp_task_wdt_add(NULL);  // Add current task to watchdog (NULL = current task)
        task_wdt_added = true;
    }
}

inline void feed_watchdog()
{
    ensure_task_wdt_added();
    esp_task_wdt_reset();
}

inline void feed_watchdog_if_needed(int iteration, int interval)
{
    if ((iteration + 1) % interval == 0)
    {
        feed_watchdog();
    }
}
#else
inline void feed_watchdog()
{
    // No-op for non-ESP32 platforms
}

inline void feed_watchdog_if_needed(int iteration, int interval)
{
    // No-op for non-ESP32 platforms
    (void)iteration;
    (void)interval;
}
#endif

// Macro for timing repeated operations
#define TIME_REPEATED_OPERATION(operation, iterations, description) \
    do { \
        /* Feed watchdog before starting */ \
        feed_watchdog(); \
        /* Warmup */ \
        for (int w = 0; w < PERFORMANCE_TEST_WARMUP; ++w) { \
            feed_watchdog();  /* Feed watchdog before each operation */ \
            operation; \
            feed_watchdog();  /* Feed watchdog after each operation */ \
        } \
        /* Actual test */ \
        TinyTimeMark_t perf_t0 = tiny_get_running_time(); \
        for (int i = 0; i < iterations; ++i) { \
            /* Feed watchdog every 10 iterations (increased interval to reduce overhead) */ \
            if (i % 10 == 0) feed_watchdog(); \
            operation; \
        } \
        feed_watchdog();  /* Final feed after loop */ \
        TinyTimeMark_t perf_t1 = tiny_get_running_time(); \
        double perf_dt_total_us = (double)(perf_t1 - perf_t0); \
        double perf_dt_avg_us = perf_dt_total_us / iterations; \
        std::cout << "[Performance] " << description << " (" << iterations << " iterations): " \
                  << std::fixed << std::setprecision(2) << perf_dt_total_us << " us total, " \
                  << perf_dt_avg_us << " us avg\n"; \
    } while(0)

// Helper function to check if two matrices are approximately equal
bool matrices_approximately_equal(const tiny::Mat &m1, const tiny::Mat &m2, float epsilon = 1e-5f)
{
    if (m1.row != m2.row || m1.col != m2.col)
        return false;

    for (int i = 0; i < m1.row; ++i)
    {
        for (int j = 0; j < m1.col; ++j)
        {
            if (std::fabs(m1(i, j) - m2(i, j)) > epsilon)
                return false;
        }
    }
    return true;
}

// ============================================================================
// Group 1: Object Foundation - Constructor & Destructor Tests
// ============================================================================
// Purpose: Test object creation and destruction - the foundation of all operations
void test_constructor_destructor()
{
    std::cout << "\n[Group 1: Object Foundation - Constructor & Destructor Tests]\n";

    // Test 1.1: default constructor
    std::cout << "[Test 1.1] Default Constructor\n";
    tiny::Mat mat1;
    mat1.print_info();
    mat1.print_matrix(true);

    // Test 1.2: constructor with rows and cols, using internal allocation
    std::cout << "[Test 1.2] Constructor with Rows and Cols\n";
    tiny::Mat mat2(3, 4);
    mat2.print_info();
    mat2.print_matrix(true);

    // Test 1.3: constructor with rows and cols, specifying stride, using internal allocation
    std::cout << "[Test 1.3] Constructor with Rows, Cols and Stride\n";
    tiny::Mat mat3(3, 4, 5);
    mat3.print_info();
    mat3.print_matrix(true);

    // Test 1.4: constructor with external data
    std::cout << "[Test 1.4] Constructor with External Data\n";
    float data[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
    tiny::Mat mat4(data, 3, 4);
    mat4.print_info();
    mat4.print_matrix(true);

    // Test 1.5: constructor with external data and stride
    std::cout << "[Test 1.5] Constructor with External Data and Stride\n";
    float data_stride[15] = {0, 1, 2, 3, 0, 4, 5, 6, 7, 0, 8, 9, 10, 11, 0};
    tiny::Mat mat5(data_stride, 3, 4, 5);
    mat5.print_info();
    mat5.print_matrix(true);

    // Test 1.6: copy constructor
    std::cout << "[Test 1.6] Copy Constructor\n";
    tiny::Mat mat6(mat5);
    mat6.print_info();
    mat6.print_matrix(true);
}

// ============================================================================
// Group 2: Object Foundation - Element Access Tests
// ============================================================================
// Purpose: Test element access - fundamental operation for data manipulation
void test_element_access()
{
    std::cout << "\n[Group 2: Object Foundation - Element Access Tests]\n";
    tiny::Mat mat(2, 3);

    // Test 2.1: non-const access
    std::cout << "[Test 2.1] Non-const Access\n";
    mat(0, 0) = 1.1f;
    mat(0, 1) = 2.2f;
    mat(0, 2) = 3.3f;
    mat(1, 0) = 4.4f;
    mat(1, 1) = 5.5f;
    mat(1, 2) = 6.6f;
    mat.print_info();
    mat.print_matrix(true);

    // Test 2.2: const access
    std::cout << "[Test 2.2] Const Access\n";
    const tiny::Mat const_mat = mat;
    std::cout << "const_mat(0, 0): " << const_mat(0, 0) << "\n";
}

// ============================================================================
// Group 3: Object Foundation - Data Manipulation Tests (ROI Operations)
// ============================================================================
// Purpose: Test ROI operations - efficient data views and submatrix operations
void test_roi_operations()
{
    std::cout << "\n[Group 3: Object Foundation - Data Manipulation Tests (ROI Operations)]\n";

    // Material Matrices
    tiny::Mat matA(2, 3);
    for (int i = 0; i < 2; ++i)
    {
        for (int j = 0; j < 3; ++j)
        {
            matA(i, j) = i * 3 + j + 1;
            matA(i, j) = matA(i, j) / 10;
        }
    }

    float data[15] = {0, 1, 2, 3, 0, 4, 5, 6, 7, 0, 8, 9, 10, 11, 0};
    tiny::Mat matB(data, 3, 4, 5);

    tiny::Mat matC;

    std::cout << "[Material Matrices]\n";
    std::cout << "matA:\n";
    matA.print_info();
    matA.print_matrix(true);
    std::cout << "matB:\n";
    matB.print_info();
    matB.print_matrix(true);
    std::cout << "matC:\n";
    matC.print_info();
    matC.print_matrix(true);

    // Test 3.1: Copy ROI
    std::cout << "[Test 3.1] Copy ROI - Over Range Case\n";
    matB.copy_paste(matA, 1, 2);
    std::cout << "matB after copy_paste matA at (1, 2):\n";
    matB.print_matrix(true);
    std::cout << "nothing changed.\n";

    std::cout << "[Test 3.1] Copy ROI - Suitable Range Case\n";
    matB.copy_paste(matA, 1, 1);
    std::cout << "matB after copy_paste matA at (1, 1):\n";
    matB.print_info();
    matB.print_matrix(true);
    std::cout << "successfully copied.\n";

    // Test 3.2: Copy Head
    std::cout << "[Test 3.2] Copy Head\n";
    matC.copy_head(matB);
    std::cout << "matC after copy_head matB:\n";
    matC.print_info();
    matC.print_matrix(true);

    std::cout << "[Test 3.2] Copy Head - Memory Sharing Check\n"; // matB and matC share the same data pointer
    matB(0, 0) = 99.99f;
    std::cout << "matB(0, 0) = 99.99f\n";
    std::cout << "matC:\n";
    matC.print_info();
    matC.print_matrix(true);

    // Test 3.3: Get a View of ROI - low level function
    std::cout << "[Test 3.3] Get a View of ROI - Low Level Function\n";
    std::cout << "get a view of ROI with overrange dimensions - rows:\n";
    tiny::Mat roi1 = matB.view_roi(1, 1, 3, 2); // note here, C++ will use the copy constructor, which will copy according to the case (submatrix - shallow copy | normal - deep copy)
    std::cout << "get a view of ROI with overrange dimensions - cols:\n";
    tiny::Mat roi2 = matB.view_roi(1, 1, 2, 4); // note here, C++ will use the copy constructor, which will copy according to the case (submatrix - shallow copy | normal - deep copy)
    std::cout << "get a view of ROI with suitable dimensions:\n";
    tiny::Mat roi3 = matB.view_roi(1, 1, 2, 2); // note here, C++ will use the copy constructor, which will copy according to the case (submatrix - shallow copy | normal - deep copy)
    std::cout << "roi3:\n";
    roi3.print_info();
    roi3.print_matrix(true);

    // Test 3.4: Get a View of ROI - using ROI structure
    std::cout << "[Test 3.4] Get a View of ROI - Using ROI Structure\n";
    tiny::Mat::ROI roi_struct(1, 1, 2, 2);
    tiny::Mat roi4 = matB.view_roi(roi_struct);
    roi4.print_info();
    roi4.print_matrix(true);

    // Test 3.5: Copy ROI - low level function
    std::cout << "[Test 3.5] Copy ROI - Low Level Function\n";
    tiny::Mat mat_deep_copy = matB.copy_roi(1, 1, 2, 2);
    mat_deep_copy.print_info();
    mat_deep_copy.print_matrix(true);

    // Test 3.6: Copy ROI - using ROI structure
    std::cout << "[Test 3.6] Copy ROI - Using ROI Structure\n";
    TinyTimeMark_t tic1 = tiny_get_running_time();
    tiny::Mat::ROI roi_struct2(1, 1, 2, 2);
    tiny::Mat mat_deep_copy2 = matB.copy_roi(roi_struct2);
    TinyTimeMark_t toc1 = tiny_get_running_time();
    TinyTimeMark_t copy_roi_time = toc1 - tic1;
    std::cout << "time for copy_roi using ROI structure: " << copy_roi_time << " ms\n";
    mat_deep_copy2.print_info();
    mat_deep_copy2.print_matrix(true);

    // Test 3.7: Block
    std::cout << "[Test 3.7] Block\n";
    TinyTimeMark_t tic2 = tiny_get_running_time();
    tiny::Mat mat_block = matB.block(1, 1, 2, 2);
    TinyTimeMark_t toc2 = tiny_get_running_time();
    TinyTimeMark_t block_roi_time = toc2 - tic2;
    std::cout << "time for block: " << block_roi_time << " ms\n";
    mat_block.print_info();
    mat_block.print_matrix(true);

    // Test 3.8: Swap Rows
    std::cout << "[Test 3.8] Swap Rows\n";
    std::cout << "matB before swap rows:\n";
    matB.print_info();
    matB.print_matrix(true);
    std::cout << "matB after swap_rows(0, 2):\n";
    matB.swap_rows(0, 2);
    matB.print_info();
    matB.print_matrix(true);

    // Test 3.9: Swap Columns
    std::cout << "[Test 3.9] Swap Columns\n";
    std::cout << "matB before swap columns:\n";
    matB.print_info();
    matB.print_matrix(true);
    std::cout << "matB after swap_cols(0, 2):\n";
    matB.swap_cols(0, 2);
    matB.print_info();
    matB.print_matrix(true);

    // Test 3.10: Clear
    std::cout << "[Test 3.10] Clear\n";
    std::cout << "matB before clear:\n";
    matB.print_info();
    matB.print_matrix(true);
    std::cout << "matB after clear:\n";
    matB.clear();
    matB.print_info();
    matB.print_matrix(true);
}

// ============================================================================
// Group 4: Basic Operations - Arithmetic Operators Tests
// ============================================================================
// Purpose: Test basic arithmetic operations - foundation for numerical computations
// Group 4.1: Assignment Operator
void test_assignment_operator()
{
    std::cout << "\n[Group 4.1: Basic Operations - Assignment Operator Tests]\n";

    std::cout << "\n[Test 4.1.1] Assignment (Same Dimensions)\n";
    tiny::Mat dst(2, 3), src(2, 3);
    for (int i = 0; i < 2; ++i)
        for (int j = 0; j < 3; ++j)
            src(i, j) = static_cast<float>(i * 3 + j + 1);
    dst = src;
    dst.print_matrix(true);

    std::cout << "\n[Test 4.1.2] Assignment (Different Dimensions)\n";
    tiny::Mat dst2(4, 2);
    dst2 = src;
    dst2.print_matrix(true);

    std::cout << "\n[Test 4.1.3] Assignment to Sub-Matrix (Expect Error)\n";
    float data[15] = {0, 1, 2, 3, 0, 4, 5, 6, 7, 0, 8, 9, 10, 11, 0};
    tiny::Mat base(data, 3, 4, 5);
    tiny::Mat subView = base.view_roi(1, 1, 2, 2);
    subView = src;
    subView.print_matrix(true);

    std::cout << "\n[Test 4.1.4] Self-Assignment\n";
    src = src;
    src.print_matrix(true);
}

// Group 4.2: Matrix Addition
void test_matrix_addition()
{
    std::cout << "\n[Group 4.2: Matrix Addition Tests]\n";

    std::cout << "\n[Test 4.2.1] Matrix Addition (Same Dimensions)\n";
    tiny::Mat A(2, 3), B(2, 3);
    for (int i = 0; i < 2; ++i)
        for (int j = 0; j < 3; ++j)
        {
            A(i, j) = static_cast<float>(i * 3 + j + 1);
            B(i, j) = 1.0f;
        }
    A += B;
    A.print_matrix(true);

    std::cout << "\n[Test 4.2.2] Sub-Matrix Addition\n";
    float data[20] = {0,1,2,3,0,4,5,6,7,0,8,9,10,11,0,12,13,14,15,0};
    tiny::Mat base(data, 4, 4, 5);
    tiny::Mat subA = base.view_roi(1,1,2,2);
    tiny::Mat subB = base.view_roi(1,1,2,2);
    subA += subB;
    subA.print_matrix(true);

    std::cout << "\n[Test 4.2.3] Full Matrix + Sub-Matrix Addition\n";
    tiny::Mat full(2,2);
    for(int i=0;i<2;++i) for(int j=0;j<2;++j) full(i,j)=2.0f;
    full += subB;
    full.print_matrix(true);

    std::cout << "\n[Test 4.2.4] Addition Dimension Mismatch (Expect Error)\n";
    tiny::Mat wrongDim(3,3);
    full += wrongDim;
}

// Group 4.3: Constant Addition
void test_constant_addition()
{
    std::cout << "\n[Group 4.3: Constant Addition Tests]\n";

    std::cout << "\n[Test 4.3.1] Full Matrix + Constant\n";
    tiny::Mat mat1(2,3);
    for (int i = 0; i < 2; ++i)
        for (int j = 0; j < 3; ++j)
            mat1(i,j) = static_cast<float>(i*3 + j);
    mat1 += 5.0f;
    mat1.print_matrix(true);

    std::cout << "\n[Test 4.3.2] Sub-Matrix + Constant\n";
    float data[20] = {0,1,2,3,0,4,5,6,7,0,8,9,10,11,0,12,13,14,15,0};
    tiny::Mat base(data,4,4,5);
    tiny::Mat sub = base.view_roi(1,1,2,2);
    sub += 3.0f;
    sub.print_matrix(true);

    std::cout << "\n[Test 4.3.3] Add Zero\n";
    tiny::Mat mat2(2,2);
    mat2(0,0)=1; mat2(0,1)=2; mat2(1,0)=3; mat2(1,1)=4;
    mat2 += 0.0f;
    mat2.print_matrix(true);

    std::cout << "\n[Test 4.3.4] Add Negative Constant\n";
    tiny::Mat mat3(2,2);
    mat3(0,0)=10; mat3(0,1)=20; mat3(1,0)=30; mat3(1,1)=40;
    mat3 += -15.0f;
    mat3.print_matrix(true);
}

// Group 4.4: Matrix Subtraction
void test_matrix_subtraction()
{
    std::cout << "\n[Group 4.4: Matrix Subtraction Tests]\n";

    std::cout << "\n[Test 4.4.1] Matrix Subtraction\n";
    tiny::Mat A(2,2), B(2,2);
    A(0,0)=5; A(0,1)=7; A(1,0)=9; A(1,1)=11;
    B(0,0)=1; B(0,1)=2; B(1,0)=3; B(1,1)=4;
    A -= B;
    A.print_matrix(true);

    std::cout << "\n[Test 4.4.2] Subtraction Dimension Mismatch (Expect Error)\n";
    tiny::Mat wrong(3,3);
    A -= wrong;
}

// Group 4.5: Constant Subtraction
void test_constant_subtraction()
{
    std::cout << "\n[Group 4.5: Constant Subtraction Tests]\n";

    std::cout << "\n[Test 4.5.1] Full Matrix - Constant\n";
    tiny::Mat mat(2,3);
    for (int i=0;i<2;++i) for(int j=0;j<3;++j) mat(i,j) = i*3+j+1;
    mat -= 2.0f;
    mat.print_matrix(true);

    std::cout << "\n[Test 4.5.2] Sub-Matrix - Constant\n";
    float data[15] = {0,1,2,3,0,4,5,6,7,0,8,9,10,11,0};
    tiny::Mat base(data,3,4,5);
    tiny::Mat sub = base.view_roi(1,1,2,2);
    sub -= 1.5f;
    sub.print_matrix(true);
}

// Group 4.6: Matrix Element-wise Division
void test_matrix_division()
{
    std::cout << "\n[Group 4.6: Matrix Element-wise Division Tests]\n";

    std::cout << "\n[Test 4.6.1] Element-wise Division (Same Dimensions, No Zero)\n";
    tiny::Mat A(2, 2), B(2, 2);
    A(0,0) = 10; A(0,1) = 20; A(1,0) = 30; A(1,1) = 40;
    B(0,0) = 2;  B(0,1) = 4;  B(1,0) = 5;  B(1,1) = 8;
    A /= B;
    A.print_matrix(true);

    std::cout << "\n[Test 4.6.2] Dimension Mismatch (Expect Error)\n";
    tiny::Mat wrongDim(3, 3);
    A /= wrongDim;

    std::cout << "\n[Test 4.6.3] Division by Matrix Containing Zero (Expect Error)\n";
    tiny::Mat C(2, 2), D(2, 2);
    C(0,0)=5; C(0,1)=10; C(1,0)=15; C(1,1)=20;
    D(0,0)=1; D(0,1)=0;  D(1,0)=3;  D(1,1)=4;  // Contains zero
    C /= D;
    C.print_matrix(true);  // Should remain unchanged
}

// Group 4.7: Constant Division
void test_constant_division()
{
    std::cout << "\n[Group 4.7: Matrix Division by Constant Tests]\n";

    std::cout << "\n[Test 4.7.1] Divide Full Matrix by Positive Constant\n";
    tiny::Mat mat1(2, 3);
    for (int i = 0; i < 2; ++i)
        for (int j = 0; j < 3; ++j)
            mat1(i, j) = static_cast<float>(i * 3 + j + 2);  // Avoid zero
    mat1 /= 2.0f;
    mat1.print_matrix(true);

    std::cout << "\n[Test 4.7.2] Divide Matrix by Negative Constant\n";
    tiny::Mat mat2(2, 2);
    mat2(0,0)=6; mat2(0,1)=12; mat2(1,0)=18; mat2(1,1)=24;
    mat2 /= -3.0f;
    mat2.print_matrix(true);

    std::cout << "\n[Test 4.7.3] Division by Zero Constant (Expect Error)\n";
    tiny::Mat mat3(2, 2);
    mat3(0,0)=1; mat3(0,1)=2; mat3(1,0)=3; mat3(1,1)=4;
    mat3 /= 0.0f;
    mat3.print_matrix(true);  // Should remain unchanged
}

// Group 4.8: Matrix Exponentiation
void test_matrix_exponentiation()
{
    std::cout << "\n[Group 4.8: Matrix Exponentiation Tests]\n";

    std::cout << "\n[Test 4.8.1] Raise Each Element to Power of 2\n";
    tiny::Mat mat1(2, 2);
    mat1(0,0)=2; mat1(0,1)=3; mat1(1,0)=4; mat1(1,1)=5;
    tiny::Mat result1 = mat1 ^ 2;
    result1.print_matrix(true);

    std::cout << "\n[Test 4.8.2] Raise Each Element to Power of 0\n";
    tiny::Mat mat2(2, 2);
    mat2(0,0)=7; mat2(0,1)=-3; mat2(1,0)=0.5f; mat2(1,1)=10;
    tiny::Mat result2 = mat2 ^ 0;
    result2.print_matrix(true);  // Expect all 1

    std::cout << "\n[Test 4.8.3] Raise Each Element to Power of 1\n";
    tiny::Mat mat3(2, 2);
    mat3(0,0)=9; mat3(0,1)=8; mat3(1,0)=7; mat3(1,1)=6;
    tiny::Mat result3 = mat3 ^ 1;
    result3.print_matrix(true);  // Expect same as original

    std::cout << "\n[Test 4.8.4] Raise Each Element to Power of -1 (Expect Error or Warning)\n";
    tiny::Mat mat4(2, 2);
    mat4(0,0)=1; mat4(0,1)=2; mat4(1,0)=4; mat4(1,1)=5;
    tiny::Mat result4 = mat4 ^ -1;
    result4.print_matrix(true);

    std::cout << "\n[Test 4.8.5] Raise Matrix Containing Zero to Power of 3\n";
    tiny::Mat mat5(2, 2);
    mat5(0,0)=0; mat5(0,1)=2; mat5(1,0)=-1; mat5(1,1)=3;
    tiny::Mat result5 = mat5 ^ 3;
    result5.print_matrix(true);
}

// ============================================================================
// Group 5: Matrix Properties - Linear Algebra Tests
// ============================================================================
// Purpose: Test matrix properties and basic linear algebra operations
// Group 5.1: Matrix Transpose
void test_matrix_transpose()
{
    std::cout << "\n[Group 5.1: Matrix Properties - Matrix Transpose Tests]\n";

    // Test 5.1.1: Basic 2x3 matrix transpose
    std::cout << "\n[Test 5.1.1] Transpose of 2x3 Matrix\n";
    tiny::Mat mat1(2, 3);
    int val = 1;
    for (int i = 0; i < 2; ++i)
        for (int j = 0; j < 3; ++j)
            mat1(i, j) = val++;

    std::cout << "Original 2x3 Matrix:\n";
    mat1.print_matrix(true);

    tiny::Mat transposed1 = mat1.transpose();
    std::cout << "Transposed 3x2 Matrix:\n";
    transposed1.print_matrix(true);

    // Test 5.1.2: Square matrix transpose (3x3)
    std::cout << "\n[Test 5.1.2] Transpose of 3x3 Square Matrix\n";
    tiny::Mat mat2(3, 3);
    val = 1;
    for (int i = 0; i < 3; ++i)
        for (int j = 0; j < 3; ++j)
            mat2(i, j) = val++;

    std::cout << "Original 3x3 Matrix:\n";
    mat2.print_matrix(true);

    tiny::Mat transposed2 = mat2.transpose();
    std::cout << "Transposed 3x3 Matrix:\n";
    transposed2.print_matrix(true);

    // Test 5.1.3: Matrix with padding (4x2, stride=3)
    std::cout << "\n[Test 5.1.3] Transpose of Matrix with Padding\n";
    float data[12] = {1, 2, 0, 3, 4, 0, 5, 6, 0, 7, 8, 0};  // stride=3, 4 rows
    tiny::Mat mat3(data, 4, 2, 3);
    std::cout << "Original 4x2 Matrix (with padding):\n";
    mat3.print_matrix(true);

    tiny::Mat transposed3 = mat3.transpose();
    std::cout << "Transposed 2x4 Matrix:\n";
    transposed3.print_matrix(true);

    // Test 5.1.4: Transpose of empty matrix
    std::cout << "\n[Test 5.1.4] Transpose of Empty Matrix\n";
    tiny::Mat mat4;
    mat4.print_matrix(true);

    tiny::Mat transposed4 = mat4.transpose();
    transposed4.print_matrix(true);
}

// Group 5.2: Matrix Minor and Cofactor
void test_matrix_cofactor()
{
    std::cout << "\n[Group 5.2: Matrix Minor and Cofactor Tests]\n";

    // Test 5.2.1: Minor of 3x3 Matrix - Standard Case
    std::cout << "\n[Test 5.2.1] Minor of 3x3 Matrix (Remove Row 1, Col 1)\n";
    tiny::Mat mat1(3, 3);
    int val = 1;
    for (int i = 0; i < 3; ++i)
        for (int j = 0; j < 3; ++j)
            mat1(i, j) = val++;

    std::cout << "Original 3x3 Matrix:\n";
    mat1.print_matrix(true);

    tiny::Mat minor1 = mat1.minor(1, 1);
    std::cout << "Minor Matrix (remove row 1, col 1, no sign):\n";
    minor1.print_matrix(true);  // Expected: [[1,3],[7,9]]

    // Test 5.2.2: Cofactor of 3x3 Matrix - Same position
    std::cout << "\n[Test 5.2.2] Cofactor of 3x3 Matrix (Remove Row 1, Col 1)\n";
    std::cout << "Note: Cofactor matrix is the same as minor matrix.\n";
    std::cout << "      The sign (-1)^(i+j) is applied when computing cofactor value, not to matrix elements.\n";
    tiny::Mat cof1 = mat1.cofactor(1, 1);
    std::cout << "Cofactor Matrix (same as minor):\n";
    cof1.print_matrix(true);  // Expected: [[1,3],[7,9]] (same as minor)

    // Test 5.2.3: Minor - Remove first row and first column
    std::cout << "\n[Test 5.2.3] Minor (Remove Row 0, Col 0)\n";
    tiny::Mat minor2 = mat1.minor(0, 0);
    minor2.print_matrix(true);  // Expected: [[5,6],[8,9]]

    // Test 5.2.4: Cofactor - Remove first row and first column
    std::cout << "\n[Test 5.2.4] Cofactor (Remove Row 0, Col 0)\n";
    std::cout << "Note: Cofactor matrix is the same as minor matrix.\n";
    tiny::Mat cof2 = mat1.cofactor(0, 0);
    cof2.print_matrix(true);  // Expected: [[5,6],[8,9]] (same as minor)

    // Test 5.2.5: Cofactor - Remove row 0, col 1
    std::cout << "\n[Test 5.2.5] Cofactor (Remove Row 0, Col 1)\n";
    std::cout << "Note: Cofactor matrix is the same as minor matrix.\n";
    std::cout << "      When computing cofactor value, sign (-1)^(0+1) = -1 would be applied.\n";
    tiny::Mat cof2_neg = mat1.cofactor(0, 1);
    std::cout << "Cofactor Matrix (same as minor):\n";
    cof2_neg.print_matrix(true);  // Expected: [[4,6],[7,9]] (same as minor, no sign in matrix)

    // Test 5.2.6: Minor - Remove last row and last column
    std::cout << "\n[Test 5.2.6] Minor (Remove Row 2, Col 2)\n";
    tiny::Mat minor3 = mat1.minor(2, 2);
    minor3.print_matrix(true);  // Expected: [[1,2],[4,5]]

    // Test 5.2.7: Cofactor - Remove last row and last column
    std::cout << "\n[Test 5.2.7] Cofactor (Remove Row 2, Col 2)\n";
    std::cout << "Note: Cofactor matrix is the same as minor matrix.\n";
    tiny::Mat cof3 = mat1.cofactor(2, 2);
    cof3.print_matrix(true);  // Expected: [[1,2],[4,5]] (same as minor)

    // Test 5.2.8: 4x4 Matrix Example - Minor
    std::cout << "\n[Test 5.2.8] Minor of 4x4 Matrix (Remove Row 2, Col 1)\n";
    tiny::Mat mat4(4, 4);
    val = 1;
    for (int i = 0; i < 4; ++i)
        for (int j = 0; j < 4; ++j)
            mat4(i, j) = val++;

    mat4.print_matrix(true);
    tiny::Mat minor4 = mat4.minor(2, 1);
    std::cout << "Minor Matrix:\n";
    minor4.print_matrix(true);

    // Test 5.2.9: 4x4 Matrix Example - Cofactor
    std::cout << "\n[Test 5.2.9] Cofactor of 4x4 Matrix (Remove Row 2, Col 1)\n";
    std::cout << "Note: Cofactor matrix is the same as minor matrix.\n";
    std::cout << "      When computing cofactor value, sign (-1)^(2+1) = -1 would be applied.\n";
    tiny::Mat cof4 = mat4.cofactor(2, 1);
    std::cout << "Cofactor Matrix (same as minor):\n";
    cof4.print_matrix(true);

    // Test 5.2.10: Non-square Matrix (Expect Error)
    std::cout << "\n[Test 5.2.10] Non-square Matrix (Expect Error)\n";
    tiny::Mat rectMat(3, 4);
    std::cout << "Testing minor():\n";
    rectMat.minor(1, 1).print_matrix(true);  // Should trigger error and return empty matrix
    std::cout << "Testing cofactor():\n";
    rectMat.cofactor(1, 1).print_matrix(true);  // Should trigger error and return empty matrix
}

// Group 5.3: Matrix Determinant
void test_matrix_determinant()
{
    std::cout << "\n[Group 5.3: Matrix Determinant Tests]\n";

    // Test 5.3.1: 1x1 Matrix
    std::cout << "\n[Test 5.3.1] 1x1 Matrix Determinant\n";
    tiny::Mat mat1(1, 1);
    mat1(0, 0) = 7;
    std::cout << "Matrix:\n";
    mat1.print_matrix(true);
    std::cout << "Determinant: " << mat1.determinant() << "  (Expected: 7)\n";

    // Test 5.3.2: 2x2 Matrix
    std::cout << "\n[Test 5.3.2] 2x2 Matrix Determinant\n";
    tiny::Mat mat2(2, 2);
    mat2(0, 0) = 3; mat2(0, 1) = 8;
    mat2(1, 0) = 4; mat2(1, 1) = 6;
    std::cout << "Matrix:\n";
    mat2.print_matrix(true);
    std::cout << "Determinant: " << mat2.determinant() << "  (Expected: -14)\n";

    // Test 5.3.3: 3x3 Matrix
    std::cout << "\n[Test 5.3.3] 3x3 Matrix Determinant\n";
    tiny::Mat mat3(3, 3);
    mat3(0,0) = 1; mat3(0,1) = 2; mat3(0,2) = 3;
    mat3(1,0) = 0; mat3(1,1) = 4; mat3(1,2) = 5;
    mat3(2,0) = 1; mat3(2,1) = 0; mat3(2,2) = 6;
    std::cout << "Matrix:\n";
    mat3.print_matrix(true);
    std::cout << "Determinant: " << mat3.determinant() << "  (Expected: 22)\n";

    // Test 5.3.4: 4x4 Matrix
    std::cout << "\n[Test 5.3.4] 4x4 Matrix Determinant\n";
    tiny::Mat mat4(4, 4);
    int val = 1;
    for (int i = 0; i < 4; ++i)
        for (int j = 0; j < 4; ++j)
            mat4(i, j) = val++;
    std::cout << "Matrix:\n";
    mat4.print_matrix(true);
    std::cout << "Note: This matrix has linearly dependent rows (each row differs by constant 4),\n";
    std::cout << "      so the determinant should be 0.\n";
    std::cout << "Determinant: " << mat4.determinant() << "  (Expected: 0)\n";  

    // Test 5.3.5: 5x5 Matrix (Tests Auto-select Mechanism)
    std::cout << "\n[Test 5.3.5] 5x5 Matrix Determinant (Tests Auto-select to LU Method)\n";
    tiny::Mat mat5_basic(5, 5);
    // Create a well-conditioned 5x5 matrix
    mat5_basic(0,0) = 2; mat5_basic(0,1) = 1; mat5_basic(0,2) = 0; mat5_basic(0,3) = 0; mat5_basic(0,4) = 0;
    mat5_basic(1,0) = 1; mat5_basic(1,1) = 2; mat5_basic(1,2) = 1; mat5_basic(1,3) = 0; mat5_basic(1,4) = 0;
    mat5_basic(2,0) = 0; mat5_basic(2,1) = 1; mat5_basic(2,2) = 2; mat5_basic(2,3) = 1; mat5_basic(2,4) = 0;
    mat5_basic(3,0) = 0; mat5_basic(3,1) = 0; mat5_basic(3,2) = 1; mat5_basic(3,3) = 2; mat5_basic(3,4) = 1;
    mat5_basic(4,0) = 0; mat5_basic(4,1) = 0; mat5_basic(4,2) = 0; mat5_basic(4,3) = 1; mat5_basic(4,4) = 2;
    std::cout << "Matrix (5x5, tridiagonal):\n";
    mat5_basic.print_matrix(true);
    float det5_basic = mat5_basic.determinant();
    std::cout << "Determinant (auto-select, should use LU for n > 4): " << det5_basic << "\n";
    std::cout << "Note: For n = 5 > 4, auto-select should use LU decomposition (O(n³)).\n";

    // Test 5.3.6: Non-square Matrix (Expect Error)
    std::cout << "\n[Test 5.3.6] Non-square Matrix (Expect Error)\n";
    tiny::Mat rectMat(3, 4);
    std::cout << "Matrix (3x4, non-square):\n";
    rectMat.print_matrix(true);
    float det_rect = rectMat.determinant();  // should trigger error
    std::cout << "Determinant: " << det_rect << "  (Expected: 0 with error message)\n";

    // Test 5.3.7: Comparison of Different Methods (5x5 Matrix)
    std::cout << "\n[Test 5.3.7] Comparison of Different Methods (5x5 Matrix)\n";
    tiny::Mat mat_test(5, 5);
    // Create a test matrix
    for (int i = 0; i < 5; ++i)
    {
        for (int j = 0; j < 5; ++j)
        {
            mat_test(i, j) = static_cast<float>((i + 1) * (j + 1) + (i == j ? 1.0f : 0.0f));
        }
    }
    std::cout << "Matrix (5x5):\n";
    mat_test.print_matrix(true);
    float det_auto = mat_test.determinant();
    float det_laplace = mat_test.determinant_laplace();
    float det_lu = mat_test.determinant_lu();
    float det_gaussian = mat_test.determinant_gaussian();
    std::cout << "Determinant (auto-select): " << det_auto << "  (should use LU for n > 4)\n";
    std::cout << "Determinant (Laplace):     " << det_laplace << "  (O(n!), slow for n=5)\n";
    std::cout << "Determinant (LU):          " << det_lu << "  (O(n³), efficient)\n";
    std::cout << "Determinant (Gaussian):    " << det_gaussian << "  (O(n³), efficient)\n";
    std::cout << "Note: All methods should give the same result (within numerical precision).\n";
    std::cout << "      Auto-select should use LU for n > 4, avoiding slow Laplace expansion.\n";

    // Test 5.3.8: Large Matrix (6x6) - Tests Efficient Methods
    std::cout << "\n[Test 5.3.8] Large Matrix (6x6) - Tests Efficient Methods\n";
    tiny::Mat mat6(6, 6);
    for (int i = 0; i < 6; ++i)
    {
        for (int j = 0; j < 6; ++j)
        {
            mat6(i, j) = static_cast<float>((i + 1) * (j + 1) + (i == j ? 0.5f : 0.0f));
        }
    }
    std::cout << "Matrix (6x6, showing first 4x4 block):\n";
    for (int i = 0; i < 4; ++i)
    {
        for (int j = 0; j < 4; ++j)
        {
            std::cout << std::setw(10) << mat6(i, j) << " ";
        }
        std::cout << "...\n";
    }
    std::cout << "...\n";
    float det6_auto = mat6.determinant();
    float det6_lu = mat6.determinant_lu();
    float det6_gaussian = mat6.determinant_gaussian();
    std::cout << "Determinant (auto-select, uses LU): " << det6_auto << "\n";
    std::cout << "Determinant (LU):                   " << det6_lu << "\n";
    std::cout << "Determinant (Gaussian):             " << det6_gaussian << "\n";
    std::cout << "Note: For n > 4, auto-select uses LU decomposition (O(n³) instead of O(n!)).\n";

    // Test 5.3.9: Large Matrix (8x8) - Performance Test
    std::cout << "\n[Test 5.3.9] Large Matrix (8x8) - Performance Comparison\n";
    tiny::Mat mat8(8, 8);
    for (int i = 0; i < 8; ++i)
    {
        for (int j = 0; j < 8; ++j)
        {
            mat8(i, j) = static_cast<float>((i + 1) * (j + 1));
        }
    }
    std::cout << "Matrix (8x8, showing first 4x4 block):\n";
    // Print partial matrix for display
    for (int i = 0; i < 4; ++i)
    {
        for (int j = 0; j < 4; ++j)
        {
            std::cout << std::setw(10) << mat8(i, j) << " ";
        }
        std::cout << "...\n";
    }
    std::cout << "...\n";
    float det8_lu = mat8.determinant_lu();
    float det8_gaussian = mat8.determinant_gaussian();
    std::cout << "Determinant (LU):       " << det8_lu << "\n";
    std::cout << "Determinant (Gaussian): " << det8_gaussian << "\n";
    std::cout << "Note: Both methods are O(n³) and should be much faster than Laplace expansion.\n";

}

// Group 5.4: Matrix Adjoint
void test_matrix_adjoint()
{
    std::cout << "\n[Group 5.4: Matrix Adjoint Tests]\n";

    // Test 5.4.1: 1x1 Matrix
    std::cout << "\n[Test 5.4.1] Adjoint of 1x1 Matrix\n";
    tiny::Mat mat1(1, 1);
    mat1(0, 0) = 5;
    std::cout << "Original Matrix:\n";
    mat1.print_matrix(true);
    tiny::Mat adj1 = mat1.adjoint();
    std::cout << "Adjoint Matrix:\n";
    adj1.print_matrix(true);  // Expected: [1]

    // Test 5.4.2: 2x2 Matrix
    std::cout << "\n[Test 5.4.2] Adjoint of 2x2 Matrix\n";
    tiny::Mat mat2(2, 2);
    mat2(0, 0) = 1; mat2(0, 1) = 2;
    mat2(1, 0) = 3; mat2(1, 1) = 4;
    std::cout << "Original Matrix:\n";
    mat2.print_matrix(true);
    tiny::Mat adj2 = mat2.adjoint();
    std::cout << "Adjoint Matrix:\n";
    adj2.print_matrix(true);  // Expected: [4, -2; -3, 1]

    // Test 5.4.3: 3x3 Matrix
    std::cout << "\n[Test 5.4.3] Adjoint of 3x3 Matrix\n";
    tiny::Mat mat3(3, 3);
    mat3(0,0) = 1; mat3(0,1) = 2; mat3(0,2) = 3;
    mat3(1,0) = 0; mat3(1,1) = 4; mat3(1,2) = 5;
    mat3(2,0) = 1; mat3(2,1) = 0; mat3(2,2) = 6;
    std::cout << "Original Matrix:\n";
    mat3.print_matrix(true);
    tiny::Mat adj3 = mat3.adjoint();
    std::cout << "Adjoint Matrix:\n";
    adj3.print_matrix(true);
    // No simple expected value, but should compute correctly

    // Test 5.4.4: Non-Square Matrix (Expect Error)
    std::cout << "\n[Test 5.4.4] Adjoint of Non-Square Matrix (Expect Error)\n";
    tiny::Mat rectMat(2, 3);
    std::cout << "Original Matrix (2x3, non-square):\n";
    rectMat.print_matrix(true);
    tiny::Mat adjRect = rectMat.adjoint();
    std::cout << "Adjoint Matrix (should be empty due to error):\n";
    adjRect.print_matrix(true);  // Should be empty or default matrix

}

// Group 5.5: Matrix Normalization
void test_matrix_normalize()
{
    std::cout << "\n[Group 5.5: Matrix Normalization Tests]\n";

    // Test 5.5.1: Standard normalization
    std::cout << "\n[Test 5.5.1] Normalize a Standard 2x2 Matrix\n";
    tiny::Mat mat1(2, 2);
    mat1(0, 0) = 3.0f; mat1(0, 1) = 4.0f;
    mat1(1, 0) = 3.0f; mat1(1, 1) = 4.0f;

    std::cout << "Before normalization:\n";
    mat1.print_matrix(true);

    mat1.normalize();

    std::cout << "After normalization (Expected L2 norm = 1):\n";
    mat1.print_matrix(true);

    // Test 5.5.2: Matrix with padding
    std::cout << "\n[Test 5.5.2] Normalize a 2x2 Matrix with Stride=4 (Padding Test)\n";
    float data_with_padding[8] = {3.0f, 4.0f, 0.0f, 0.0f, 3.0f, 4.0f, 0.0f, 0.0f};
    tiny::Mat mat2(data_with_padding, 2, 2, 4);  // 2x2 matrix, stride 4

    std::cout << "Before normalization:\n";
    mat2.print_matrix(true);

    mat2.normalize();

    std::cout << "After normalization:\n";
    mat2.print_matrix(true);

    // Test 5.5.3: Zero matrix normalization
    std::cout << "\n[Test 5.5.3] Normalize a Zero Matrix (Expect Warning)\n";
    tiny::Mat mat3(2, 2);
    mat3.clear();  // Assuming clear() sets all elements to zero

    mat3.print_matrix(true);
    mat3.normalize();  // Should trigger warning
}

// Group 5.6: Matrix Norm Calculation
void test_matrix_norm()
{
    std::cout << "\n[Group 5.6: Matrix Norm Calculation Tests]\n";

    // Test 5.6.1: Simple 2x2 Matrix
    std::cout << "\n[Test 5.6.1] 2x2 Matrix Norm (Expect 5.0)\n";
    tiny::Mat mat1(2, 2);
    mat1(0, 0) = 3.0f; mat1(0, 1) = 4.0f;
    mat1(1, 0) = 0.0f; mat1(1, 1) = 0.0f;
    std::cout << "Matrix:\n";
    mat1.print_matrix(true);
    float norm1 = mat1.norm();
    std::cout << "Calculated Norm: " << norm1 << "\n";

    // Test 5.6.2: Zero Matrix
    std::cout << "\n[Test 5.6.2] Zero Matrix Norm (Expect 0.0)\n";
    tiny::Mat mat2(3, 3);
    mat2.clear();  // Assuming clear() sets all elements to zero
    std::cout << "Matrix:\n";
    mat2.print_matrix(true);
    float norm2 = mat2.norm();
    std::cout << "Calculated Norm: " << norm2 << "\n";

    // Test 5.6.3: Matrix with Negative Values
    std::cout << "\n[Test 5.6.3] Matrix with Negative Values\n";
    tiny::Mat mat3(2, 2);
    mat3(0, 0) = -1.0f; mat3(0, 1) = -2.0f;
    mat3(1, 0) = -3.0f; mat3(1, 1) = -4.0f;
    std::cout << "Matrix:\n";
    mat3.print_matrix(true);
    float norm3 = mat3.norm();
    std::cout << "Calculated Norm: " << norm3 << "  (Expect sqrt(30) ≈ 5.477)\n";

    // Test 5.6.4: Matrix with Padding
    std::cout << "\n[Test 5.6.4] 2x2 Matrix with Stride=4 (Padding Test)\n";
    float data4[8] = {1.0f, 2.0f, 0.0f, 0.0f, 3.0f, 4.0f, 0.0f, 0.0f};
    tiny::Mat mat4(data4, 2, 2, 4);  // 2x2 matrix, stride 4
    std::cout << "Matrix:\n";
    mat4.print_matrix(true);
    float norm4 = mat4.norm();
    std::cout << "Calculated Norm: " << norm4 << "  (Expect sqrt(30) ≈ 5.477)\n";
}

// Group 5.7: Matrix Inversion
void test_inverse_adjoint_adjoint()
{
    std::cout << "\n[Group 5.7: Matrix Inversion Tests]\n";

    // Test 5.7.1: 2x2 Regular Matrix
    std::cout << "\n[Test 5.7.1] Inverse of 2x2 Matrix\n";
    tiny::Mat mat1(2, 2);
    mat1(0, 0) = 4;  mat1(0, 1) = 7;
    mat1(1, 0) = 2;  mat1(1, 1) = 6;
    std::cout << "Original Matrix:\n";
    mat1.print_matrix(true);
    tiny::Mat inv1 = mat1.inverse_adjoint();
    std::cout << "Inverse Matrix:\n";
    inv1.print_matrix(true);
    std::cout << "Expected Approx:\n[ 0.6  -0.7 ]\n[ -0.2  0.4 ]\n";

    // Test 5.7.2: Singular Matrix (Determinant = 0)
    std::cout << "\n[Test 5.7.2] Singular Matrix (Expect Error)\n";
    tiny::Mat mat2(2, 2);
    mat2(0, 0) = 1;  mat2(0, 1) = 2;
    mat2(1, 0) = 2;  mat2(1, 1) = 4;   // Rank-deficient, det = 0
    std::cout << "Original Matrix:\n";
    mat2.print_matrix(true);
    std::cout << "Note: This matrix is singular (determinant = 0), so inverse should fail.\n";
    tiny::Mat inv2 = mat2.inverse_adjoint();
    std::cout << "Inverse Matrix (Should be zero matrix):\n";
    inv2.print_matrix(true);

    // Test 5.7.3: 3x3 Regular Matrix
    std::cout << "\n[Test 5.7.3] Inverse of 3x3 Matrix\n";
    tiny::Mat mat3(3, 3);
    mat3(0,0) = 3; mat3(0,1) = 0; mat3(0,2) = 2;
    mat3(1,0) = 2; mat3(1,1) = 0; mat3(1,2) = -2;
    mat3(2,0) = 0; mat3(2,1) = 1; mat3(2,2) = 1;
    std::cout << "Original Matrix:\n";
    mat3.print_matrix(true);
    tiny::Mat inv3 = mat3.inverse_adjoint();
    std::cout << "Inverse Matrix:\n";
    inv3.print_matrix(true);

    // Test 5.7.4: Non-Square Matrix (Expect Error)
    std::cout << "\n[Test 5.7.4] Non-Square Matrix (Expect Error)\n";
    tiny::Mat mat4(2, 3);
    std::cout << "Original Matrix (2x3, non-square):\n";
    mat4.print_matrix(true);
    tiny::Mat inv4 = mat4.inverse_adjoint();
    std::cout << "Inverse Matrix (should be empty due to error):\n";
    inv4.print_matrix(true);
}

// Group 5.8: Matrix Utilities
void test_matrix_utilities()
{
    std::cout << "\n[Group 5.8: Matrix Utilities Tests]\n";

    // Test 5.8.1: Identity Matrix (eye)
    std::cout << "\n[Test 5.8.1] Generate Identity Matrix (eye)\n";
    tiny::Mat I3 = tiny::Mat::eye(3);
    std::cout << "3x3 Identity Matrix:\n";
    I3.print_matrix(true);

    tiny::Mat I5 = tiny::Mat::eye(5);
    std::cout << "5x5 Identity Matrix:\n";
    I5.print_matrix(true);

    // Test 5.8.2: Ones Matrix
    std::cout << "\n[Test 5.8.2] Generate Ones Matrix\n";
    tiny::Mat ones_3x4 = tiny::Mat::ones(3, 4);
    std::cout << "3x4 Ones Matrix:\n";
    ones_3x4.print_matrix(true);

    tiny::Mat ones_4x4 = tiny::Mat::ones(4);
    std::cout << "4x4 Ones Matrix (Square):\n";
    ones_4x4.print_matrix(true);

    // Test 5.8.3: Matrix Augmentation
    std::cout << "\n[Test 5.8.3] Augment Two Matrices Horizontally [A | B]\n";

    // Prepare matrices A (2x2) and B (2x3)
    tiny::Mat A(2, 2);
    A(0,0) = 1;  A(0,1) = 2;
    A(1,0) = 3;  A(1,1) = 4;

    tiny::Mat B(2, 3);
    B(0,0) = 5;  B(0,1) = 6;  B(0,2) = 7;
    B(1,0) = 8;  B(1,1) = 9;  B(1,2) = 10;

    std::cout << "Matrix A:\n";
    A.print_matrix(true);
    std::cout << "Matrix B:\n";
    B.print_matrix(true);

    tiny::Mat AB = tiny::Mat::augment(A, B);
    std::cout << "Augmented Matrix [A | B]:\n";
    AB.print_matrix(true);

    // Test 5.8.4: Row mismatch case
    std::cout << "\n[Test 5.8.4] Augment with Row Mismatch (Expect Error)\n";
    tiny::Mat C(3, 2);  // 3x2 matrix
    tiny::Mat invalidAug = tiny::Mat::augment(A, C);
    invalidAug.print_info();  // Should show empty matrix due to error

    // Test 5.8.5: Vertical Stack (vstack)
    std::cout << "\n[Test 5.8.5] Vertically Stack Two Matrices [A; B]\n";

    // Prepare matrices A (2x3) and B (2x3)
    tiny::Mat A_vstack(2, 3);
    A_vstack(0,0) = 1;  A_vstack(0,1) = 2;  A_vstack(0,2) = 3;
    A_vstack(1,0) = 4;  A_vstack(1,1) = 5;  A_vstack(1,2) = 6;

    tiny::Mat B_vstack(2, 3);
    B_vstack(0,0) = 7;  B_vstack(0,1) = 8;  B_vstack(0,2) = 9;
    B_vstack(1,0) = 10; B_vstack(1,1) = 11; B_vstack(1,2) = 12;

    std::cout << "Matrix A (top):\n";
    A_vstack.print_matrix(true);
    std::cout << "Matrix B (bottom):\n";
    B_vstack.print_matrix(true);

    tiny::Mat AB_vstack = tiny::Mat::vstack(A_vstack, B_vstack);
    std::cout << "Vertically Stacked Matrix [A; B]:\n";
    AB_vstack.print_matrix(true);
    std::cout << "Expected: 4x3 matrix with A on top, B on bottom\n";

    // Test 5.8.6: Vertical Stack with different row counts
    std::cout << "\n[Test 5.8.6] Vertical Stack with Different Row Counts (Same Columns)\n";
    tiny::Mat A_small(1, 3);
    A_small(0,0) = 1; A_small(0,1) = 2; A_small(0,2) = 3;

    tiny::Mat B_large(3, 3);
    B_large(0,0) = 4;  B_large(0,1) = 5;  B_large(0,2) = 6;
    B_large(1,0) = 7;  B_large(1,1) = 8;  B_large(1,2) = 9;
    B_large(2,0) = 10; B_large(2,1) = 11; B_large(2,2) = 12;

    std::cout << "Matrix A (1x3):\n";
    A_small.print_matrix(true);
    std::cout << "Matrix B (3x3):\n";
    B_large.print_matrix(true);

    tiny::Mat AB_mixed = tiny::Mat::vstack(A_small, B_large);
    std::cout << "Vertically Stacked Matrix [A; B] (1x3 + 3x3 = 4x3):\n";
    AB_mixed.print_matrix(true);

    // Test 5.8.7: Column mismatch case (Expect Error)
    std::cout << "\n[Test 5.8.7] VStack with Column Mismatch (Expect Error)\n";
    tiny::Mat A_col(2, 2);
    A_col(0,0) = 1; A_col(0,1) = 2;
    A_col(1,0) = 3; A_col(1,1) = 4;

    tiny::Mat B_col(2, 3);  // Different column count
    B_col(0,0) = 5; B_col(0,1) = 6; B_col(0,2) = 7;
    B_col(1,0) = 8; B_col(1,1) = 9; B_col(1,2) = 10;

    std::cout << "Matrix A (2x2):\n";
    A_col.print_matrix(true);
    std::cout << "Matrix B (2x3, different columns):\n";
    B_col.print_matrix(true);

    tiny::Mat invalidVStack = tiny::Mat::vstack(A_col, B_col);
    std::cout << "Result (should be empty due to error):\n";
    invalidVStack.print_info();  // Should show empty matrix due to error

}

// Group 5.9: Gaussian Elimination
void test_gaussian_eliminate()
{
    std::cout << "\n[Group 5.9: Gaussian Elimination Tests]\n";

    // Test 5.9.1: Simple 3x3 System
    std::cout << "\n[Test 5.9.1] 3x3 Matrix (Simple Upper Triangular)\n";
    tiny::Mat mat1(3, 3);
    mat1(0,0) = 2; mat1(0,1) = 1; mat1(0,2) = -1;
    mat1(1,0) = -3; mat1(1,1) = -1; mat1(1,2) = 2;
    mat1(2,0) = -2; mat1(2,1) = 1; mat1(2,2) = 2;

    std::cout << "Original Matrix:\n";
    mat1.print_matrix(true);

    tiny::Mat result1 = mat1.gaussian_eliminate();

    std::cout << "After Gaussian Elimination (Should be upper triangular):\n";
    result1.print_matrix(true);

    // Test 5.9.2: 3x4 Augmented Matrix
    std::cout << "\n[Test 5.9.2] 3x4 Augmented Matrix (Linear System Ax = b)\n";
    tiny::Mat mat2(3, 4);
    mat2(0,0) = 1; mat2(0,1) = 2; mat2(0,2) = -1; mat2(0,3) =  8;
    mat2(1,0) = -3; mat2(1,1) = -1; mat2(1,2) = 2; mat2(1,3) = -11;
    mat2(2,0) = -2; mat2(2,1) = 1; mat2(2,2) = 2; mat2(2,3) = -3;

    std::cout << "Original Augmented Matrix [A | b]:\n";
    mat2.print_matrix(true);

    tiny::Mat result2 = mat2.gaussian_eliminate();

    std::cout << "After Gaussian Elimination (Row Echelon Form):\n";
    result2.print_matrix(true);

    // Test 5.9.3: Singular Matrix
    std::cout << "\n[Test 5.9.3] Singular Matrix (No Unique Solution)\n";
    tiny::Mat mat3(2, 2);
    mat3(0,0) = 1; mat3(0,1) = 2;
    mat3(1,0) = 2; mat3(1,1) = 4;  // Linearly dependent rows

    std::cout << "Original Singular Matrix:\n";
    mat3.print_matrix(true);

    tiny::Mat result3 = mat3.gaussian_eliminate();
    std::cout << "After Gaussian Elimination (Should show rows of zeros):\n";
    result3.print_matrix(true);

    // Test 5.9.4: Zero Matrix
    std::cout << "\n[Test 5.9.4] Zero Matrix\n";
    tiny::Mat mat4(3, 3);
    mat4.clear();  // Assuming clear() sets all elements to zero
    mat4.print_matrix(true);

    tiny::Mat result4 = mat4.gaussian_eliminate();
    std::cout << "After Gaussian Elimination (Should be a zero matrix):\n";
    result4.print_matrix(true);
}


// Group 5.10: Row Reduce from Gaussian (RREF Calculation)
void test_row_reduce_from_gaussian()
{
    std::cout << "\n[Group 5.10: Row Reduce from Gaussian (RREF) Tests]\n";

    // Test 5.10.1: Simple 3x4 augmented matrix (representing a system of equations)
    std::cout << "\n[Test 5.10.1] 3x4 Augmented Matrix\n";
    tiny::Mat mat1(3, 4);

    // Matrix:
    // [ 1  2 -1  -4 ]
    // [ 2  3 -1 -11 ]
    // [-2  0 -3  22 ]
    mat1(0,0) = 1;  mat1(0,1) = 2;  mat1(0,2) = -1; mat1(0,3) = -4;
    mat1(1,0) = 2;  mat1(1,1) = 3;  mat1(1,2) = -1; mat1(1,3) = -11;
    mat1(2,0) = -2; mat1(2,1) = 0;  mat1(2,2) = -3; mat1(2,3) = 22;

    std::cout << "Original Matrix:\n";
    mat1.print_matrix(true);

    tiny::Mat rref1 = mat1.gaussian_eliminate().row_reduce_from_gaussian();
    std::cout << "RREF Result:\n";
    rref1.print_matrix(true);

    // Test 5.10.2: 2x3 Matrix
    std::cout << "\n[Test 5.10.2] 2x3 Matrix\n";
    tiny::Mat mat2(2, 3);
    mat2(0,0) = 1; mat2(0,1) = 2;  mat2(0,2) = 3;
    mat2(1,0) = 4; mat2(1,1) = 5;  mat2(1,2) = 6;

    std::cout << "Original Matrix:\n";
    mat2.print_matrix(true);

    tiny::Mat rref2 = mat2.gaussian_eliminate().row_reduce_from_gaussian();
    std::cout << "RREF Result:\n";
    rref2.print_matrix(true);

    // Test 5.10.3: Already reduced matrix (should remain the same)
    std::cout << "\n[Test 5.10.3] Already Reduced Matrix\n";
    tiny::Mat mat3(2, 3);
    mat3(0,0) = 1; mat3(0,1) = 0; mat3(0,2) = 2;
    mat3(1,0) = 0; mat3(1,1) = 1; mat3(1,2) = 3;

    std::cout << "Original Matrix:\n";
    mat3.print_matrix(true);

    tiny::Mat rref3 = mat3.row_reduce_from_gaussian();
    std::cout << "RREF Result:\n";
    rref3.print_matrix(true);
}

// Group 5.11: Gaussian Inverse
void test_inverse_gje()
{
    std::cout << "\n[Group 5.11: Gaussian Inverse Tests]\n";

    // Test 5.11.1: Regular 2x2 Matrix
    std::cout << "\n[Test 5.11.1] 2x2 Matrix Inverse\n";
    tiny::Mat mat1(2, 2);
    mat1(0, 0) = 4; mat1(0, 1) = 7;
    mat1(1, 0) = 2; mat1(1, 1) = 6;
    std::cout << "Original matrix (mat1):\n";
    mat1.print_matrix(true);

    tiny::Mat invMat1 = mat1.inverse_gje();
    std::cout << "Inverse matrix (mat1):\n";
    invMat1.print_matrix(true);

    // Test 5.11.2: Identity Matrix (should return identity matrix)
    std::cout << "\n[Test 5.11.2] Identity Matrix Inverse\n";
    tiny::Mat mat2 = tiny::Mat::eye(3);
    std::cout << "Original matrix (Identity):\n";
    mat2.print_matrix(true);

    tiny::Mat invMat2 = mat2.inverse_gje();
    std::cout << "Inverse matrix (Identity):\n";
    invMat2.print_matrix(true); // Expected: Identity matrix

    // Test 5.11.3: Singular Matrix (should return empty matrix or indicate error)
    std::cout << "\n[Test 5.11.3] Singular Matrix (Expected: No Inverse)\n";
    tiny::Mat mat3(3, 3);
    mat3(0, 0) = 1; mat3(0, 1) = 2; mat3(0, 2) = 3;
    mat3(1, 0) = 4; mat3(1, 1) = 5; mat3(1, 2) = 6;
    mat3(2, 0) = 7; mat3(2, 1) = 8; mat3(2, 2) = 9;  // Determinant is 0
    std::cout << "Original matrix (singular):\n";
    mat3.print_matrix(true);

    tiny::Mat invMat3 = mat3.inverse_gje();
    std::cout << "Inverse matrix (singular):\n";
    invMat3.print_matrix(true); // Expected: empty matrix or error message

    // Test 5.11.4: 3x3 Matrix with a valid inverse
    std::cout << "\n[Test 5.11.4] 3x3 Matrix Inverse\n";
    tiny::Mat mat4(3, 3);
    mat4(0, 0) = 4; mat4(0, 1) = 7; mat4(0, 2) = 2;
    mat4(1, 0) = 3; mat4(1, 1) = 5; mat4(1, 2) = 1;
    mat4(2, 0) = 8; mat4(2, 1) = 6; mat4(2, 2) = 9;
    std::cout << "Original matrix (mat4):\n";
    mat4.print_matrix(true);

    tiny::Mat invMat4 = mat4.inverse_gje();
    std::cout << "Inverse matrix (mat4):\n";
    invMat4.print_matrix(true); // Check that the inverse is calculated correctly

    // Test 5.11.5: Non-square Matrix (should return error or empty matrix)
    std::cout << "\n[Test 5.11.5] Non-square Matrix Inverse (Expected Error)\n";
    tiny::Mat mat5(2, 3);
    mat5(0, 0) = 1; mat5(0, 1) = 2; mat5(0, 2) = 3;
    mat5(1, 0) = 4; mat5(1, 1) = 5; mat5(1, 2) = 6;
    std::cout << "Original matrix (non-square):\n";
    mat5.print_matrix(true);

    tiny::Mat invMat5 = mat5.inverse_gje();
    std::cout << "Inverse matrix (non-square):\n";
    invMat5.print_matrix(true); // Expected: Error message or empty matrix
}

// Group 5.12: Dot Product
void test_dotprod()
{
    std::cout << "\n[Group 5.12: Dot Product Tests]\n";

    // Test 5.12.1: Valid Dot Product Calculation (Same Length Vectors)
    std::cout << "\n[Test 5.12.1] Valid Dot Product (Same Length Vectors)\n";
    tiny::Mat vectorA(3, 1);  // Create a 3x1 vector
    tiny::Mat vectorB(3, 1);  // Create a 3x1 vector

    // Initialize vectors
    vectorA(0, 0) = 1.0f;
    vectorA(1, 0) = 2.0f;
    vectorA(2, 0) = 3.0f;

    vectorB(0, 0) = 4.0f;
    vectorB(1, 0) = 5.0f;
    vectorB(2, 0) = 6.0f;

    std::cout << "Vector A:\n";
    vectorA.print_matrix(true);
    std::cout << "Vector B:\n";
    vectorB.print_matrix(true);

    // Compute the dot product
    float result = vectorA.dotprod(vectorA, vectorB);
    std::cout << "Dot product of vectorA and vectorB: " << result << std::endl;  // Expected result: 1*4 + 2*5 + 3*6 = 32

    // Test 5.12.2: Dot Product with Dimension Mismatch (Different Length Vectors)
    std::cout << "\n[Test 5.12.2] Invalid Dot Product (Dimension Mismatch)\n";
    tiny::Mat vectorC(2, 1);  // Create a 2x1 vector (different size)
    vectorC(0, 0) = 1.0f;
    vectorC(1, 0) = 2.0f;

    std::cout << "Vector A (3x1):\n";
    vectorA.print_matrix(true);
    std::cout << "Vector C (2x1, different size):\n";
    vectorC.print_matrix(true);

    float invalidResult = vectorA.dotprod(vectorA, vectorC);  // Should print an error and return 0
    std::cout << "Dot product (dimension mismatch): " << invalidResult << std::endl;  // Expected: 0 and error message

    // Test 5.12.3: Dot Product of Zero Vectors
    std::cout << "\n[Test 5.12.3] Dot Product of Zero Vectors\n";
    tiny::Mat zeroVectorA(3, 1);  // Create a 3x1 zero vector
    tiny::Mat zeroVectorB(3, 1);  // Create a 3x1 zero vector

    // Initialize vectors
    zeroVectorA(0, 0) = 0.0f;
    zeroVectorA(1, 0) = 0.0f;
    zeroVectorA(2, 0) = 0.0f;

    zeroVectorB(0, 0) = 0.0f;
    zeroVectorB(1, 0) = 0.0f;
    zeroVectorB(2, 0) = 0.0f;

    std::cout << "Zero Vector A:\n";
    zeroVectorA.print_matrix(true);
    std::cout << "Zero Vector B:\n";
    zeroVectorB.print_matrix(true);

    float zeroResult = zeroVectorA.dotprod(zeroVectorA, zeroVectorB);
    std::cout << "Dot product of zero vectors: " << zeroResult << std::endl;  // Expected: 0

}

// Group 5.13: Solve Linear System
void test_solve()
{
    std::cout << "\n[Group 5.13: Solve Linear System Tests]\n";

    // Test 5.13.1: Solving a simple 2x2 system
    std::cout << "\n[Test 5.13.1] Solving a Simple 2x2 System Ax = b\n";
    tiny::Mat A(2, 2);
    tiny::Mat b(2, 1);

    A(0, 0) = 2; A(0, 1) = 1;
    A(1, 0) = 1; A(1, 1) = 3;

    b(0, 0) = 5;
    b(1, 0) = 6;

    std::cout << "Matrix A:\n";
    A.print_matrix(true);
    std::cout << "Vector b:\n";
    b.print_matrix(true);

    tiny::Mat solution = A.solve(A, b);
    std::cout << "Solution x:\n";
    solution.print_matrix(true);

    // Test 5.13.2: Solving a 3x3 system
    std::cout << "\n[Test 5.13.2] Solving a 3x3 System Ax = b\n";
    tiny::Mat A2(3, 3);
    tiny::Mat b2(3, 1);

    A2(0, 0) = 1; A2(0, 1) = 2; A2(0, 2) = 1;
    A2(1, 0) = 2; A2(1, 1) = 0; A2(1, 2) = 3;
    A2(2, 0) = 3; A2(2, 1) = 2; A2(2, 2) = 1;

    b2(0, 0) = 9;
    b2(1, 0) = 8;
    b2(2, 0) = 7;

    std::cout << "Matrix A:\n";
    A2.print_matrix(true);
    std::cout << "Vector b:\n";
    b2.print_matrix(true);

    tiny::Mat solution2 = A2.solve(A2, b2);
    std::cout << "Solution x:\n";
    solution2.print_matrix(true);

    // Test 5.13.3: Solving a system where one row is all zeros
    std::cout << "\n[Test 5.13.3] Solving a System Where One Row is All Zeros (Expect Failure or Infinite Solutions)\n";
    tiny::Mat A3(3, 3);
    tiny::Mat b3(3, 1);

    A3(0, 0) = 1; A3(0, 1) = 2; A3(0, 2) = 3;
    A3(1, 0) = 0; A3(1, 1) = 0; A3(1, 2) = 0; // Zero row
    A3(2, 0) = 4; A3(2, 1) = 5; A3(2, 2) = 6;

    b3(0, 0) = 9;
    b3(1, 0) = 0; // Inconsistent, no solution should be possible
    b3(2, 0) = 15;

    std::cout << "Matrix A (has zero row):\n";
    A3.print_matrix(true);
    std::cout << "Vector b:\n";
    b3.print_matrix(true);

    tiny::Mat solution3 = A3.solve(A3, b3);
    std::cout << "Solution x:\n";
    solution3.print_matrix(true);

    // Test 5.13.4: Solving a system with zero determinant (singular matrix)
    std::cout << "\n[Test 5.13.4] Solving a System with Zero Determinant (Singular Matrix)\n";
    tiny::Mat A4(3, 3);
    tiny::Mat b4(3, 1);

    A4(0, 0) = 2; A4(0, 1) = 4; A4(0, 2) = 1;
    A4(1, 0) = 1; A4(1, 1) = 2; A4(1, 2) = 3;
    A4(2, 0) = 3; A4(2, 1) = 6; A4(2, 2) = 2; // The matrix is singular (row 2 = 2 * row 1)

    b4(0, 0) = 5;
    b4(1, 0) = 6;
    b4(2, 0) = 7;

    std::cout << "Matrix A (singular, determinant = 0):\n";
    A4.print_matrix(true);
    std::cout << "Vector b:\n";
    b4.print_matrix(true);

    tiny::Mat solution4 = A4.solve(A4, b4);
    std::cout << "Solution x:\n";
    solution4.print_matrix(true); // Expect no solution or an error message

    // Test 5.13.5: Solving a system with linearly dependent rows
    std::cout << "\n[Test 5.13.5] Solving a System with Linearly Dependent Rows (Expect Failure or Infinite Solutions)\n";
    tiny::Mat A5(3, 3);
    tiny::Mat b5(3, 1);

    A5(0, 0) = 1; A5(0, 1) = 1; A5(0, 2) = 1;
    A5(1, 0) = 2; A5(1, 1) = 2; A5(1, 2) = 2;
    A5(2, 0) = 3; A5(2, 1) = 3; A5(2, 2) = 3; // All rows are linearly dependent

    b5(0, 0) = 6;
    b5(1, 0) = 12;
    b5(2, 0) = 18;

    std::cout << "Matrix A (all rows linearly dependent):\n";
    A5.print_matrix(true);
    std::cout << "Vector b:\n";
    b5.print_matrix(true);

    tiny::Mat solution5 = A5.solve(A5, b5);
    std::cout << "Solution x:\n";
    solution5.print_matrix(true); // Expect an error message or infinite solutions

    // Test 5.13.6: Solving a larger 4x4 system
    std::cout << "\n[Test 5.13.6] Solving a Larger 4x4 System Ax = b\n";
    tiny::Mat A6(4, 4);
    tiny::Mat b6(4, 1);

    A6(0, 0) = 4; A6(0, 1) = 2; A6(0, 2) = 3; A6(0, 3) = 1;
    A6(1, 0) = 2; A6(1, 1) = 5; A6(1, 2) = 1; A6(1, 3) = 2;
    A6(2, 0) = 3; A6(2, 1) = 1; A6(2, 2) = 6; A6(2, 3) = 3;
    A6(3, 0) = 1; A6(3, 1) = 2; A6(3, 2) = 3; A6(3, 3) = 4;

    b6(0, 0) = 10;
    b6(1, 0) = 12;
    b6(2, 0) = 14;
    b6(3, 0) = 16;

    std::cout << "Matrix A:\n";
    A6.print_matrix(true);
    std::cout << "Vector b:\n";
    b6.print_matrix(true);

    tiny::Mat solution6 = A6.solve(A6, b6);
    std::cout << "Solution x:\n";
    solution6.print_matrix(true); // Should print the solution vector

}

// Group 5.14: Band Solve
void test_band_solve()
{
    std::cout << "\n[Group 5.14: Band Solve Tests]\n";

    // Test 5.14.1: Simple 3x3 Band Matrix
    std::cout << "\n[Test 5.14.1] Simple 3x3 Band Matrix\n";
    tiny::Mat A1(3, 3);
    tiny::Mat b1(3, 1);

    // Define the matrix A and vector b for the system Ax = b
    A1(0, 0) = 2; A1(0, 1) = 1; A1(0, 2) = 0;
    A1(1, 0) = 1; A1(1, 1) = 3; A1(1, 2) = 2;
    A1(2, 0) = 0; A1(2, 1) = 1; A1(2, 2) = 4;

    b1(0, 0) = 5;
    b1(1, 0) = 6;
    b1(2, 0) = 7;

    std::cout << "Matrix A:\n";
    A1.print_matrix(true);
    std::cout << "Vector b:\n";
    b1.print_matrix(true);

    // Solve Ax = b using band_solve
    tiny::Mat solution1 = A1.band_solve(A1, b1, 3);
    std::cout << "Solution x:\n";
    solution1.print_matrix(true);

    // Test 5.14.2: 4x4 Band Matrix with different right-hand side vector
    std::cout << "\n[Test 5.14.2] 4x4 Band Matrix\n";
    tiny::Mat A2(4, 4);
    tiny::Mat b2(4, 1);

    // Define the matrix A and vector b
    A2(0, 0) = 2; A2(0, 1) = 1; A2(0, 2) = 0; A2(0, 3) = 0;
    A2(1, 0) = 1; A2(1, 1) = 3; A2(1, 2) = 2; A2(1, 3) = 0;
    A2(2, 0) = 0; A2(2, 1) = 1; A2(2, 2) = 4; A2(2, 3) = 2;
    A2(3, 0) = 0; A2(3, 1) = 0; A2(3, 2) = 1; A2(3, 3) = 5;

    b2(0, 0) = 8;
    b2(1, 0) = 9;
    b2(2, 0) = 10;
    b2(3, 0) = 11;

    std::cout << "Matrix A:\n";
    A2.print_matrix(true);
    std::cout << "Vector b:\n";
    b2.print_matrix(true);

    // Solve Ax = b using band_solve
    tiny::Mat solution2 = A2.band_solve(A2, b2, 3);
    std::cout << "Solution x:\n";
    solution2.print_matrix(true);

    // Test 5.14.3: Incompatible dimensions (expect error)
    std::cout << "\n[Test 5.14.3] Incompatible Dimensions (Expect Error)\n";
    tiny::Mat A3(3, 3);
    tiny::Mat b3(2, 1);  // Incompatible dimension

    A3(0, 0) = 1; A3(0, 1) = 2; A3(0, 2) = 3;
    A3(1, 0) = 4; A3(1, 1) = 5; A3(1, 2) = 6;
    A3(2, 0) = 7; A3(2, 1) = 8; A3(2, 2) = 9;

    b3(0, 0) = 10;
    b3(1, 0) = 11;

    std::cout << "Matrix A (3x3):\n";
    A3.print_matrix(true);
    std::cout << "Vector b (2x1, incompatible):\n";
    b3.print_matrix(true);

    // This should print an error because of incompatible dimensions
    tiny::Mat solution3 = A3.band_solve(A3, b3, 3);
    std::cout << "Solution x:\n";
    solution3.print_matrix(true);

    // Test 5.14.4: Singular Matrix (Should fail)
    std::cout << "\n[Test 5.14.4] Singular Matrix (No Unique Solution)\n";
    tiny::Mat A4(3, 3);
    tiny::Mat b4(3, 1);

    // Define a singular matrix (linearly dependent rows)
    A4(0, 0) = 1; A4(0, 1) = 2; A4(0, 2) = 3;
    A4(1, 0) = 2; A4(1, 1) = 4; A4(1, 2) = 6;
    A4(2, 0) = 3; A4(2, 1) = 6; A4(2, 2) = 9;

    b4(0, 0) = 10;
    b4(1, 0) = 20;
    b4(2, 0) = 30;

    std::cout << "Matrix A (singular, linearly dependent rows):\n";
    A4.print_matrix(true);
    std::cout << "Vector b:\n";
    b4.print_matrix(true);

    // This should print an error as the matrix is singular and does not have a unique solution
    tiny::Mat solution4 = A4.band_solve(A4, b4, 3);
    std::cout << "Solution x:\n";
    solution4.print_matrix(true);
}

// Group 5.15: Roots
void test_roots()
{
    std::cout << "\n[Group 5.15: Roots Tests]\n";

    // Test 5.15.1: Simple 2x2 System
    std::cout << "\n[Test 5.15.1] Solving a Simple 2x2 System Ax = b\n";
    tiny::Mat A1(2, 2);
    tiny::Mat b1(2, 1);

    // Define the matrix A and vector b for the system Ax = b
    A1(0, 0) = 2; A1(0, 1) = 1;
    A1(1, 0) = 1; A1(1, 1) = 3;

    b1(0, 0) = 5;
    b1(1, 0) = 6;

    std::cout << "Matrix A:\n";
    A1.print_matrix(true);
    std::cout << "Vector b:\n";
    b1.print_matrix(true);

    // Solve Ax = b using roots
    tiny::Mat solution1 = A1.roots(A1, b1);
    std::cout << "Solution x:\n";
    solution1.print_matrix(true);

    // Test 5.15.2: 3x3 System
    std::cout << "\n[Test 5.15.2] Solving a 3x3 System Ax = b\n";
    tiny::Mat A2(3, 3);
    tiny::Mat b2(3, 1);

    A2(0, 0) = 1; A2(0, 1) = 2; A2(0, 2) = 1;
    A2(1, 0) = 2; A2(1, 1) = 0; A2(1, 2) = 3;
    A2(2, 0) = 3; A2(2, 1) = 2; A2(2, 2) = 1;

    b2(0, 0) = 9;
    b2(1, 0) = 8;
    b2(2, 0) = 7;

    std::cout << "Matrix A:\n";
    A2.print_matrix(true);
    std::cout << "Vector b:\n";
    b2.print_matrix(true);

    // Solve Ax = b using roots
    tiny::Mat solution2 = A2.roots(A2, b2);
    std::cout << "Solution x:\n";
    solution2.print_matrix(true);

    // Test 5.15.3: Singular Matrix
    std::cout << "\n[Test 5.15.3] Singular Matrix (No Unique Solution)\n";
    tiny::Mat A3(2, 2);
    tiny::Mat b3(2, 1);

    // Define a singular matrix (linearly dependent rows)
    A3(0, 0) = 1; A3(0, 1) = 2;
    A3(1, 0) = 2; A3(1, 1) = 4;

    b3(0, 0) = 5;
    b3(1, 0) = 6;

    std::cout << "Matrix A (singular, linearly dependent rows):\n";
    A3.print_matrix(true);
    std::cout << "Vector b:\n";
    b3.print_matrix(true);

    // This should print an error as the matrix is singular and does not have a unique solution
    tiny::Mat solution3 = A3.roots(A3, b3);
    std::cout << "Solution x:\n";
    solution3.print_matrix(true);

    // Test 5.15.4: Incompatible Dimensions (Expect Error)
    std::cout << "\n[Test 5.15.4] Incompatible Dimensions (Expect Error)\n";
    tiny::Mat A4(3, 3);
    tiny::Mat b4(2, 1);  // Incompatible dimension

    A4(0, 0) = 1; A4(0, 1) = 2; A4(0, 2) = 3;
    A4(1, 0) = 4; A4(1, 1) = 5; A4(1, 2) = 6;
    A4(2, 0) = 7; A4(2, 1) = 8; A4(2, 2) = 9;

    b4(0, 0) = 10;
    b4(1, 0) = 11;

    std::cout << "Matrix A (3x3):\n";
    A4.print_matrix(true);
    std::cout << "Vector b (2x1, incompatible):\n";
    b4.print_matrix(true);

    // This should print an error because of incompatible dimensions
    tiny::Mat solution4 = A4.roots(A4, b4);
    std::cout << "Solution x:\n";
    solution4.print_matrix(true);
}

// ============================================================================
// Group 6: Linear System Solving - Core Application Tests
// ============================================================================
// Purpose: Test linear system solving - the core application of matrix library
// Note: This group includes Gaussian elimination, solve methods, and dot product
// Group 6.1: Gaussian Elimination (moved from Group 5.9)
// Group 6.2: Solve Linear System (moved from Group 5.13)
// Group 6.3: Dot Product (moved from Group 5.12)
// Group 6.4: Band Solve (moved from Group 5.14)
// Group 6.5: Roots (moved from Group 5.15)

// ============================================================================
// Group 10: Auxiliary Functions - Stream Operators Tests
// ============================================================================
// Purpose: Test I/O operations - auxiliary but important for debugging
void test_stream_operators()
{
    std::cout << "\n[Group 10: Auxiliary Functions - Stream Operators Tests]\n";

    // Test 10.1: Test stream insertion operator (<<) for Mat
    std::cout << "\n[Test 10.1] Stream Insertion Operator (<<) for Mat\n";
    tiny::Mat mat1(3, 3);
    mat1(0, 0) = 1; mat1(0, 1) = 2; mat1(0, 2) = 3;
    mat1(1, 0) = 4; mat1(1, 1) = 5; mat1(1, 2) = 6;
    mat1(2, 0) = 7; mat1(2, 1) = 8; mat1(2, 2) = 9;

    std::cout << "Matrix mat1:\n";
    std::cout << mat1 << std::endl; // Use the << operator to print mat1

    // Test 10.2: Test stream insertion operator (<<) for Mat::ROI
    std::cout << "\n[Test 10.2] Stream Insertion Operator (<<) for Mat::ROI\n";
    tiny::Mat::ROI roi(1, 2, 3, 4);
    // ROI constructor: ROI(pos_x, pos_y, width, height)
    // roi(1, 2, 3, 4) means: start at column 1, row 2, with width 3, height 4
    std::cout << "ROI created: ROI(pos_x=1, pos_y=2, width=3, height=4)\n";
    std::cout << "Expected output:\n";
    std::cout << "  row start: 2 (pos_y)\n";
    std::cout << "  col start: 1 (pos_x)\n";
    std::cout << "  row count: 4 (height)\n";
    std::cout << "  col count: 3 (width)\n";
    std::cout << "\nActual output:\n";
    std::cout << roi << std::endl; // Use the << operator to print roi

    // Test 10.3: Test stream extraction operator (>>) for Mat
    std::cout << "\n[Test 10.3] Stream Extraction Operator (>>) for Mat\n";
    tiny::Mat mat2(2, 2);
    // Use istringstream to simulate input (for automated testing)
    std::istringstream input1("10 20 30 40");
    std::cout << "Simulated input: \"10 20 30 40\"\n";
    input1 >> mat2; // Use the >> operator to read from string stream
    std::cout << "Matrix mat2 after input:\n";
    std::cout << mat2 << std::endl; // Use the << operator to print mat2
    std::cout << "Expected: [10, 20; 30, 40]\n";

    // Test 10.4: Test stream extraction operator (>>) for Mat (with different values)
    std::cout << "\n[Test 10.4] Stream Extraction Operator (>>) for Mat (2x3 matrix)\n";
    tiny::Mat mat3(2, 3);
    // Use istringstream to simulate input (for automated testing)
    std::istringstream input2("1.5 2.5 3.5 4.5 5.5 6.5");
    std::cout << "Simulated input: \"1.5 2.5 3.5 4.5 5.5 6.5\"\n";
    input2 >> mat3; // Use the >> operator to read from string stream
    std::cout << "Matrix mat3 after input:\n";
    std::cout << mat3 << std::endl; // Use the << operator to print mat3
    std::cout << "Expected: [1.5, 2.5, 3.5; 4.5, 5.5, 6.5]\n";
}

// ============================================================================
// Group 11: Auxiliary Functions - Global Arithmetic Operators Tests
// ============================================================================
// Purpose: Test global operator overloads - syntactic sugar for convenience
void test_matrix_operations()
{
    std::cout << "\n[Group 11: Auxiliary Functions - Global Arithmetic Operators Tests]\n";

    // Test 11.1: Matrix Addition (operator+)
    std::cout << "\n[Test 11.1] Matrix Addition (operator+)\n";
    tiny::Mat matA(2, 2);
    tiny::Mat matB(2, 2);

    matA(0, 0) = 1; matA(0, 1) = 2;
    matA(1, 0) = 3; matA(1, 1) = 4;

    matB(0, 0) = 5; matB(0, 1) = 6;
    matB(1, 0) = 7; matB(1, 1) = 8;

    std::cout << "Matrix A:\n";
    matA.print_matrix(true);
    std::cout << "Matrix B:\n";
    matB.print_matrix(true);

    tiny::Mat resultAdd = matA + matB;
    std::cout << "matA + matB:\n";
    std::cout << resultAdd << std::endl;  // Expected: [6, 8], [10, 12]

    // Test 11.2: Matrix Addition with Constant (operator+)
    std::cout << "\n[Test 11.2] Matrix Addition with Constant (operator+)\n";
    std::cout << "Matrix A:\n";
    matA.print_matrix(true);
    std::cout << "Constant: 5.0\n";
    tiny::Mat resultAddConst = matA + 5.0f;
    std::cout << "matA + 5.0f:\n";
    std::cout << resultAddConst << std::endl;  // Expected: [6, 7], [8, 9]

    // Test 11.3: Matrix Subtraction (operator-)
    std::cout << "\n[Test 11.3] Matrix Subtraction (operator-)\n";
    std::cout << "Matrix A:\n";
    matA.print_matrix(true);
    std::cout << "Matrix B:\n";
    matB.print_matrix(true);
    tiny::Mat resultSub = matA - matB;
    std::cout << "matA - matB:\n";
    std::cout << resultSub << std::endl;  // Expected: [-4, -4], [-4, -4]

    // Test 11.4: Matrix Subtraction with Constant (operator-)
    std::cout << "\n[Test 11.4] Matrix Subtraction with Constant (operator-)\n";
    std::cout << "Matrix A:\n";
    matA.print_matrix(true);
    std::cout << "Constant: 2.0\n";
    tiny::Mat resultSubConst = matA - 2.0f;
    std::cout << "matA - 2.0f:\n";
    std::cout << resultSubConst << std::endl;  // Expected: [-1, 0], [1, 2]

    // Test 11.5: Matrix Multiplication (operator*)
    std::cout << "\n[Test 11.5] Matrix Multiplication (operator*)\n";
    tiny::Mat matC(2, 3);
    tiny::Mat matD(3, 2);

    matC(0, 0) = 1; matC(0, 1) = 2; matC(0, 2) = 3;
    matC(1, 0) = 4; matC(1, 1) = 5; matC(1, 2) = 6;

    matD(0, 0) = 7; matD(0, 1) = 8;
    matD(1, 0) = 9; matD(1, 1) = 10;
    matD(2, 0) = 11; matD(2, 1) = 12;

    std::cout << "Matrix C (2x3):\n";
    matC.print_matrix(true);
    std::cout << "Matrix D (3x2):\n";
    matD.print_matrix(true);

    tiny::Mat resultMul = matC * matD;
    std::cout << "matC * matD:\n";
    std::cout << resultMul << std::endl;  // Expected: [58, 64], [139, 154]

    // Test 11.6: Matrix Multiplication with Constant (operator*)
    std::cout << "\n[Test 11.6] Matrix Multiplication with Constant (operator*)\n";
    std::cout << "Matrix A:\n";
    matA.print_matrix(true);
    std::cout << "Constant: 2.0\n";
    tiny::Mat resultMulConst = matA * 2.0f;
    std::cout << "matA * 2.0f:\n";
    std::cout << resultMulConst << std::endl;  // Expected: [2, 4], [6, 8]

    // Test 11.7: Matrix Division (operator/)
    std::cout << "\n[Test 11.7] Matrix Division (operator/)\n";
    std::cout << "Matrix A:\n";
    matA.print_matrix(true);
    std::cout << "Constant: 2.0\n";
    tiny::Mat resultDiv = matA / 2.0f;
    std::cout << "matA / 2.0f:\n";
    std::cout << resultDiv << std::endl;  // Expected: [0.5, 1], [1.5, 2]

    // Test 11.8: Matrix Division Element-wise (operator/)
    std::cout << "\n[Test 11.8] Matrix Division Element-wise (operator/)\n";
    std::cout << "Matrix A:\n";
    matA.print_matrix(true);
    std::cout << "Matrix B:\n";
    matB.print_matrix(true);
    tiny::Mat resultDivElem = matA / matB;
    std::cout << "matA / matB:\n";
    std::cout << resultDivElem << std::endl;  // Expected: [0.2, 0.333], [0.428, 0.5]

    // Test 11.9: Matrix Comparison (operator==)
    std::cout << "\n[Test 11.9] Matrix Comparison (operator==)\n";
    tiny::Mat matE(2, 2);
    matE(0, 0) = 1; matE(0, 1) = 2;
    matE(1, 0) = 3; matE(1, 1) = 4;

    tiny::Mat matF(2, 2);
    matF(0, 0) = 1; matF(0, 1) = 2;
    matF(1, 0) = 3; matF(1, 1) = 4;

    std::cout << "Matrix E:\n";
    matE.print_matrix(true);
    std::cout << "Matrix F:\n";
    matF.print_matrix(true);

    bool isEqual = (matE == matF);
    std::cout << "matE == matF: " << (isEqual ? "True" : "False") << std::endl;  // Expected: True

    matF(0, 0) = 5;  // Modify matF
    std::cout << "\nAfter modifying matF(0,0) = 5:\n";
    std::cout << "Matrix E:\n";
    matE.print_matrix(true);
    std::cout << "Matrix F:\n";
    matF.print_matrix(true);
    isEqual = (matE == matF);
    std::cout << "matE == matF after modification: " << (isEqual ? "True" : "False") << std::endl;  // Expected: False
}

// ============================================================================
// Group 12: Quality Assurance - Boundary Conditions and Error Handling Tests
// ============================================================================
// Purpose: Test error handling and edge cases - ensure robustness
void test_boundary_conditions()
{
    std::cout << "\n[Group 12: Quality Assurance - Boundary Conditions and Error Handling Tests]\n";

    // Test 12.1: Null pointer handling in print functions
    std::cout << "\n[Test 12.1] Null Pointer Handling in print_matrix\n";
    tiny::Mat null_mat;
    null_mat.data = nullptr;  // Simulate null pointer
    null_mat.print_matrix(true);  // Should handle gracefully

    // Test 12.2: Null pointer handling in operator<<
    std::cout << "\n[Test 12.2] Null Pointer Handling in operator<<\n";
    tiny::Mat null_mat2;
    null_mat2.data = nullptr;
    std::cout << null_mat2 << std::endl;  // Should handle gracefully

    // Test 12.3: Invalid block parameters
    std::cout << "\n[Test 12.3] Invalid Block Parameters\n";
    tiny::Mat mat(3, 3);
    for (int i = 0; i < 3; ++i)
        for (int j = 0; j < 3; ++j)
            mat(i, j) = i * 3 + j + 1;

    // Negative start position
    tiny::Mat block1 = mat.block(-1, 0, 2, 2);
    std::cout << "block(-1, 0, 2, 2): " << (block1.data == nullptr ? "Empty (correct)" : "Error") << "\n";

    // Block exceeds boundaries
    tiny::Mat block2 = mat.block(2, 2, 2, 2);
    std::cout << "block(2, 2, 2, 2) on 3x3 matrix: " << (block2.data == nullptr ? "Empty (correct)" : "Error") << "\n";

    // Zero or negative block size
    tiny::Mat block3 = mat.block(0, 0, 0, 2);
    std::cout << "block(0, 0, 0, 2): " << (block3.data == nullptr ? "Empty (correct)" : "Error") << "\n";

    // Test 12.4: Invalid swap_rows parameters
    std::cout << "\n[Test 12.4] Invalid swap_rows Parameters\n";
    tiny::Mat mat2(3, 3);
    for (int i = 0; i < 3; ++i)
        for (int j = 0; j < 3; ++j)
            mat2(i, j) = i * 3 + j + 1;

    std::cout << "Before invalid swap_rows:\n";
    mat2.print_matrix(true);

    // Negative index
    mat2.swap_rows(-1, 1);
    std::cout << "After swap_rows(-1, 1):\n";
    mat2.print_matrix(true);

    // Index out of range
    mat2.swap_rows(0, 5);
    std::cout << "After swap_rows(0, 5):\n";
    mat2.print_matrix(true);

    // Test 12.5: Invalid swap_cols parameters
    std::cout << "\n[Test 12.5] Invalid swap_cols Parameters\n";
    tiny::Mat mat2_cols(3, 3);
    for (int i = 0; i < 3; ++i)
        for (int j = 0; j < 3; ++j)
            mat2_cols(i, j) = i * 3 + j + 1;

    std::cout << "Before invalid swap_cols:\n";
    mat2_cols.print_matrix(true);

    // Negative index
    mat2_cols.swap_cols(-1, 1);
    std::cout << "After swap_cols(-1, 1):\n";
    mat2_cols.print_matrix(true);

    // Index out of range
    mat2_cols.swap_cols(0, 5);
    std::cout << "After swap_cols(0, 5):\n";
    mat2_cols.print_matrix(true);

    // Test 12.6: Division by zero
    std::cout << "\n[Test 12.6] Division by Zero\n";
    tiny::Mat mat3(2, 2);
    mat3(0, 0) = 1; mat3(0, 1) = 2;
    mat3(1, 0) = 3; mat3(1, 1) = 4;

    tiny::Mat result = mat3 / 0.0f;
    std::cout << "mat3 / 0.0f: " << (result.data == nullptr ? "Empty (correct)" : "Error") << "\n";

    // Test 12.7: Matrix division with zero elements
    std::cout << "\n[Test 12.7] Matrix Division with Zero Elements\n";
    tiny::Mat mat4(2, 2);
    mat4(0, 0) = 1; mat4(0, 1) = 2;
    mat4(1, 0) = 3; mat4(1, 1) = 4;

    tiny::Mat divisor(2, 2);
    divisor(0, 0) = 1; divisor(0, 1) = 0;  // Contains zero
    divisor(1, 0) = 3; divisor(1, 1) = 4;

    mat4 /= divisor;
    std::cout << "mat4 /= divisor (with zero):\n";
    mat4.print_matrix(true);

    // Test 12.8: Empty matrix operations
    std::cout << "\n[Test 12.8] Empty Matrix Operations\n";
    tiny::Mat empty1, empty2;
    tiny::Mat empty_sum = empty1 + empty2;
    std::cout << "Empty matrix addition: " << (empty_sum.data == nullptr ? "Empty (correct)" : "Error") << "\n";
}

// ============================================================================
// Group 13: Quality Assurance - Performance Benchmarks Tests
// ============================================================================
// Purpose: Test performance characteristics - critical for real-time applications
void test_performance_benchmarks()
{
    std::cout << "\n[Group 13: Quality Assurance - Performance Benchmarks Tests]\n";

    // Ensure current task is added to watchdog before starting performance tests
    #if MCU_PLATFORM_SELECTED == MCU_PLATFORM_ESP32
    ensure_task_wdt_added();
    #endif

    // Test 13.1: Matrix Addition Performance (reduced size to prevent timeout)
    std::cout << "\n[Test 13.1] Matrix Addition Performance\n";
    tiny::Mat A(50, 50);  // Reduced from 100x100 to 50x50
    tiny::Mat B(50, 50);
    for (int i = 0; i < 50; ++i)
    {
        for (int j = 0; j < 50; ++j)
        {
            A(i, j) = static_cast<float>(i * 50 + j);
            B(i, j) = static_cast<float>(i * 50 + j + 1);
        }
    }
    TIME_REPEATED_OPERATION(tiny::Mat C = A + B;, PERFORMANCE_TEST_ITERATIONS, "50x50 Matrix Addition");

    // Test 13.2: Matrix Multiplication Performance (reduced size)
    std::cout << "\n[Test 13.2] Matrix Multiplication Performance\n";
    tiny::Mat D(30, 30);  // Reduced from 50x50 to 30x30
    tiny::Mat E(30, 30);
    for (int i = 0; i < 30; ++i)
    {
        for (int j = 0; j < 30; ++j)
        {
            D(i, j) = static_cast<float>(i * 30 + j);
            E(i, j) = static_cast<float>(i * 30 + j + 1);
        }
    }
    TIME_REPEATED_OPERATION(tiny::Mat F = D * E;, PERFORMANCE_TEST_ITERATIONS, "30x30 Matrix Multiplication");

    // Test 13.3: Matrix Transpose Performance (reduced size)
    std::cout << "\n[Test 13.3] Matrix Transpose Performance\n";
    tiny::Mat G(50, 30);  // Reduced from 100x50 to 50x30
    for (int i = 0; i < 50; ++i)
        for (int j = 0; j < 30; ++j)
            G(i, j) = static_cast<float>(i * 30 + j);
    TIME_REPEATED_OPERATION(tiny::Mat H = G.transpose();, PERFORMANCE_TEST_ITERATIONS, "50x30 Matrix Transpose");

    // Test 13.4: Determinant Performance Comparison
    // Note: Determinant calculation now has multiple methods:
    //   - Laplace expansion: O(n!) - for small matrices (n <= 4)
    //   - LU decomposition: O(n³) - for large matrices (n > 4, auto-selected)
    //   - Gaussian elimination: O(n³) - alternative for large matrices
    std::cout << "\n[Test 13.4] Determinant Calculation Performance Comparison\n";

    // Test 13.4.1: Small Matrix (4x4) - Laplace Expansion
        std::cout << "\n[Test 13.4.1] Small Matrix (4x4) - Laplace Expansion\n";
    tiny::Mat I4(4, 4);
    for (int i = 0; i < 4; ++i)
        for (int j = 0; j < 4; ++j)
            I4(i, j) = static_cast<float>(i * 4 + j + 1);

    feed_watchdog();
    TinyTimeMark_t det4_t0 = tiny_get_running_time();
    for (int i = 0; i < PERFORMANCE_TEST_ITERATIONS_HEAVY; ++i)
    {
        feed_watchdog();
        float det = I4.determinant_laplace();
        (void)det;
        feed_watchdog();
    }
    TinyTimeMark_t det4_t1 = tiny_get_running_time();
    double det4_dt_total_us = (double)(det4_t1 - det4_t0);
    double det4_dt_avg_us = det4_dt_total_us / PERFORMANCE_TEST_ITERATIONS_HEAVY;
    std::cout << "[Performance] 4x4 Determinant (Laplace, " << PERFORMANCE_TEST_ITERATIONS_HEAVY << " iterations): "
              << std::fixed << std::setprecision(2) << det4_dt_total_us << " us total, "
              << det4_dt_avg_us << " us avg\n";

    // Test 13.4.2: Large Matrix (8x8) - LU Decomposition
        std::cout << "\n[Test 13.4.2] Large Matrix (8x8) - LU Decomposition\n";
    tiny::Mat I8(8, 8);
    for (int i = 0; i < 8; ++i)
        for (int j = 0; j < 8; ++j)
            I8(i, j) = static_cast<float>((i + 1) * (j + 1));

    feed_watchdog();
    TinyTimeMark_t det8_lu_t0 = tiny_get_running_time();
    for (int i = 0; i < PERFORMANCE_TEST_ITERATIONS_HEAVY; ++i)
    {
        feed_watchdog();
        float det = I8.determinant_lu();
        (void)det;
        feed_watchdog();
    }
    TinyTimeMark_t det8_lu_t1 = tiny_get_running_time();
    double det8_lu_dt_total_us = (double)(det8_lu_t1 - det8_lu_t0);
    double det8_lu_dt_avg_us = det8_lu_dt_total_us / PERFORMANCE_TEST_ITERATIONS_HEAVY;
    std::cout << "[Performance] 8x8 Determinant (LU, " << PERFORMANCE_TEST_ITERATIONS_HEAVY << " iterations): "
              << std::fixed << std::setprecision(2) << det8_lu_dt_total_us << " us total, "
              << det8_lu_dt_avg_us << " us avg\n";

    // Test 13.4.3: Large Matrix (8x8) - Gaussian Elimination
        std::cout << "\n[Test 13.4.3] Large Matrix (8x8) - Gaussian Elimination\n";
    feed_watchdog();
    TinyTimeMark_t det8_gauss_t0 = tiny_get_running_time();
    for (int i = 0; i < PERFORMANCE_TEST_ITERATIONS_HEAVY; ++i)
    {
        feed_watchdog();
        float det = I8.determinant_gaussian();
        (void)det;
        feed_watchdog();
    }
    TinyTimeMark_t det8_gauss_t1 = tiny_get_running_time();
    double det8_gauss_dt_total_us = (double)(det8_gauss_t1 - det8_gauss_t0);
    double det8_gauss_dt_avg_us = det8_gauss_dt_total_us / PERFORMANCE_TEST_ITERATIONS_HEAVY;
    std::cout << "[Performance] 8x8 Determinant (Gaussian, " << PERFORMANCE_TEST_ITERATIONS_HEAVY << " iterations): "
              << std::fixed << std::setprecision(2) << det8_gauss_dt_total_us << " us total, "
              << det8_gauss_dt_avg_us << " us avg\n";

    // Test 13.4.4: Auto-select Method (8x8) - Should use LU
        std::cout << "\n[Test 13.4.4] Large Matrix (8x8) - Auto-select Method\n";
    feed_watchdog();
    TinyTimeMark_t det8_auto_t0 = tiny_get_running_time();
    for (int i = 0; i < PERFORMANCE_TEST_ITERATIONS_HEAVY; ++i)
    {
        feed_watchdog();
        float det = I8.determinant();  // Auto-selects LU for n > 4
        (void)det;
        feed_watchdog();
    }
    TinyTimeMark_t det8_auto_t1 = tiny_get_running_time();
    double det8_auto_dt_total_us = (double)(det8_auto_t1 - det8_auto_t0);
    double det8_auto_dt_avg_us = det8_auto_dt_total_us / PERFORMANCE_TEST_ITERATIONS_HEAVY;
    std::cout << "[Performance] 8x8 Determinant (auto-select, " << PERFORMANCE_TEST_ITERATIONS_HEAVY << " iterations): "
              << std::fixed << std::setprecision(2) << det8_auto_dt_total_us << " us total, "
              << det8_auto_dt_avg_us << " us avg\n";

    std::cout << "\n[Note] Performance Summary:\n";
    std::cout << "  - Laplace expansion (O(n!)): Suitable only for small matrices (n <= 4)\n";
    std::cout << "  - LU decomposition (O(n³)): Efficient for large matrices, auto-selected for n > 4\n";
    std::cout << "  - Gaussian elimination (O(n³)): Alternative efficient method for large matrices\n";
    std::cout << "  - Auto-select: Automatically chooses the best method based on matrix size\n";

    // Test 13.5: Matrix Copy Performance (with padding, reduced size)
    std::cout << "\n[Test 13.5] Matrix Copy with Padding Performance\n";
    float data[80] = {0};  // Reduced from 150 to 80
    for (int i = 0; i < 80; ++i) data[i] = static_cast<float>(i);
    tiny::Mat J(data, 8, 8, 10);  // Reduced from 10x10 stride 15 to 8x8 stride 10
    TIME_REPEATED_OPERATION(tiny::Mat K = J.copy_roi(0, 0, 8, 8);, PERFORMANCE_TEST_ITERATIONS, "8x8 Copy ROI (with padding)");

    // Test 13.6: Element Access Performance (reduced size)
    std::cout << "\n[Test 13.6] Element Access Performance\n";
    tiny::Mat L(50, 50);  // Reduced from 100x100 to 50x50
    for (int i = 0; i < 50; ++i)
        for (int j = 0; j < 50; ++j)
            L(i, j) = static_cast<float>(i * 50 + j);

    // Test 6: Element Access Performance (custom implementation for multi-line operation)
    float sum = 0.0f;
    std::cout << "[Performance] Computing element access (warmup)...\n";
    feed_watchdog();  // Feed watchdog before starting
    for (int w = 0; w < PERFORMANCE_TEST_WARMUP; ++w)
    {
        feed_watchdog();  // Feed watchdog before each warmup
        sum = 0.0f;
        for (int i = 0; i < 50; ++i)
            for (int j = 0; j < 50; ++j)
                sum += L(i, j);
        feed_watchdog();  // Feed watchdog after each warmup
    }

    TinyTimeMark_t elem_t0 = tiny_get_running_time();
    for (int i = 0; i < PERFORMANCE_TEST_ITERATIONS; ++i)
    {
        if (i % 20 == 0) feed_watchdog();  // Feed watchdog every 20 iterations (element access is fast)
        sum = 0.0f;
        for (int row = 0; row < 50; ++row)
            for (int col = 0; col < 50; ++col)
                sum += L(row, col);
    }
    feed_watchdog();  // Final feed after loop
    TinyTimeMark_t elem_t1 = tiny_get_running_time();
    double elem_dt_total_us = (double)(elem_t1 - elem_t0);
    double dt_avg_us = elem_dt_total_us / PERFORMANCE_TEST_ITERATIONS;
    std::cout << "[Performance] 50x50 Element Access (all elements) (" << PERFORMANCE_TEST_ITERATIONS << " iterations): "
              << std::fixed << std::setprecision(2) << elem_dt_total_us << " us total, "
              << dt_avg_us << " us avg\n";
}

// ============================================================================
// Group 14: Quality Assurance - Memory Layout Tests (Padding and Stride)
// ============================================================================
// Purpose: Test memory layout handling - important for performance and compatibility
void test_memory_layout()
{
    std::cout << "\n[Group 14: Quality Assurance - Memory Layout Tests (Padding and Stride)]\n";

    // Test 14.1: Contiguous memory (pad=0, step=1)
    std::cout << "\n[Test 14.1] Contiguous Memory (no padding)\n";
    tiny::Mat mat1(3, 4);
    for (int i = 0; i < 3; ++i)
        for (int j = 0; j < 4; ++j)
            mat1(i, j) = static_cast<float>(i * 4 + j);
    std::cout << "Matrix 3x4 (stride=4, pad=0):\n";
    mat1.print_info();
    mat1.print_matrix(true);

    // Test 14.2: Padded memory (stride > col)
    std::cout << "\n[Test 14.2] Padded Memory (stride > col)\n";
    float data[15] = {0, 1, 2, 3, 0, 4, 5, 6, 7, 0, 8, 9, 10, 11, 0};
    tiny::Mat mat2(data, 3, 4, 5);
    std::cout << "Matrix 3x4 (stride=5, pad=1):\n";
    mat2.print_info();
    mat2.print_matrix(true);

    // Test 14.3: Operations with padded matrices
    std::cout << "\n[Test 14.3] Addition with Padded Matrices\n";
    float data1[15] = {1, 2, 3, 4, 0, 5, 6, 7, 8, 0, 9, 10, 11, 12, 0};
    float data2[15] = {10, 20, 30, 40, 0, 50, 60, 70, 80, 0, 90, 100, 110, 120, 0};
    tiny::Mat mat3(data1, 3, 4, 5);
    tiny::Mat mat4(data2, 3, 4, 5);
    tiny::Mat mat5 = mat3 + mat4;
    std::cout << "Result of padded matrix addition:\n";
    mat5.print_info();
    mat5.print_matrix(true);

    // Test 14.4: ROI operations with padded matrices
    std::cout << "\n[Test 14.4] ROI Operations with Padded Matrices\n";
    tiny::Mat roi = mat2.view_roi(1, 1, 2, 2);
    std::cout << "ROI (1,1,2,2) from padded matrix:\n";
    roi.print_info();
    roi.print_matrix(true);

    // Test 14.5: Copy operations preserve stride
    std::cout << "\n[Test 14.5] Copy Operations Preserve Stride\n";
    tiny::Mat copied = mat2.copy_roi(0, 0, 3, 4);
    std::cout << "Copied matrix (should have stride=4, no padding):\n";
    copied.print_info();
    copied.print_matrix(true);
}

// ============================================================================
// Group 7: Advanced Linear Algebra - Matrix Decomposition Tests
// ============================================================================
// Purpose: Test matrix decompositions (LU, Cholesky, QR, SVD) - foundation for 
//          stable linear system solving and least squares problems
void test_matrix_decomposition()
{
    std::cout << "\n[Group 7: Advanced Linear Algebra - Matrix Decomposition Tests]\n";

    // Test 7.1: is_positive_definite() - Basic functionality
    std::cout << "\n[Test 7.1] is_positive_definite() - Basic Functionality\n";

    // Test 7.1.1: Positive definite matrix
    {
        std::cout << "\n[Test 7.1.1] Positive Definite 3x3 Matrix\n";
        tiny::Mat pd_mat(3, 3);
        pd_mat(0, 0) = 4.0f; pd_mat(0, 1) = 1.0f; pd_mat(0, 2) = 0.0f;
        pd_mat(1, 0) = 1.0f; pd_mat(1, 1) = 3.0f; pd_mat(1, 2) = 0.0f;
        pd_mat(2, 0) = 0.0f; pd_mat(2, 1) = 0.0f; pd_mat(2, 2) = 2.0f;
        std::cout << "Matrix:\n";
        pd_mat.print_matrix(true);

        bool is_pd = pd_mat.is_positive_definite(1e-6f);
        std::cout << "Is positive definite: " << (is_pd ? "True" : "False") 
                  << " (Expected: True) " << (is_pd ? "[PASS]" : "[FAIL]") << "\n";
    }

    // Test 7.1.2: Non-positive definite matrix
    {
        std::cout << "\n[Test 7.1.2] Non-Positive Definite Matrix\n";
        tiny::Mat non_pd(2, 2);
        non_pd(0, 0) = 1.0f; non_pd(0, 1) = 2.0f;
        non_pd(1, 0) = 2.0f; non_pd(1, 1) = 1.0f;  // Has negative eigenvalue
        std::cout << "Matrix:\n";
        non_pd.print_matrix(true);

        bool is_pd = non_pd.is_positive_definite(1e-6f);
        std::cout << "Is positive definite: " << (is_pd ? "True" : "False") 
                  << " (Expected: False) " << (!is_pd ? "[PASS]" : "[FAIL]") << "\n";
    }

    // Test 7.2: LU Decomposition
    std::cout << "\n[Test 7.2] LU Decomposition\n";

    // Test 7.2.1: Simple 3x3 matrix with pivoting
    {
        std::cout << "\n[Test 7.2.1] 3x3 Matrix - LU Decomposition with Pivoting\n";
        tiny::Mat A(3, 3);
        A(0, 0) = 2.0f; A(0, 1) = 1.0f; A(0, 2) = 1.0f;
        A(1, 0) = 4.0f; A(1, 1) = 3.0f; A(1, 2) = 3.0f;
        A(2, 0) = 2.0f; A(2, 1) = 1.0f; A(2, 2) = 2.0f;
        std::cout << "Matrix A:\n";
        A.print_matrix(true);

        tiny::Mat::LUDecomposition lu = A.lu_decompose(true);
        std::cout << "\n[Results]\n";
        std::cout << "Status: " << (lu.status == TINY_OK ? "OK" : "Error") << "\n";
        if (lu.status == TINY_OK)
        {
            std::cout << "L matrix (lower triangular):\n";
            lu.L.print_matrix(true);
            std::cout << "U matrix (upper triangular):\n";
            lu.U.print_matrix(true);
            if (lu.pivoted)
            {
                std::cout << "P matrix (permutation):\n";
                lu.P.print_matrix(true);
            }

            // Verify: P * A = L * U
            tiny::Mat PA = lu.P * A;
            tiny::Mat LU = lu.L * lu.U;
            std::cout << "\n[Verification] P * A should equal L * U\n";
            float diff = 0.0f;
            for (int i = 0; i < 3; ++i)
            {
                for (int j = 0; j < 3; ++j)
                {
                    diff += fabsf(PA(i, j) - LU(i, j));
                }
            }
            std::cout << "Total difference: " << diff << (diff < 0.01f ? " [PASS]" : " [FAIL]") << "\n";
        }
    }

    // Test 7.2.2: Solve using LU decomposition
    {
        std::cout << "\n[Test 7.2.2] Solve Linear System using LU Decomposition\n";
        tiny::Mat A(3, 3);
        A(0, 0) = 2.0f; A(0, 1) = 1.0f; A(0, 2) = 1.0f;
        A(1, 0) = 4.0f; A(1, 1) = 3.0f; A(1, 2) = 3.0f;
        A(2, 0) = 2.0f; A(2, 1) = 1.0f; A(2, 2) = 2.0f;
        tiny::Mat b(3, 1);
        b(0, 0) = 1.0f;
        b(1, 0) = 2.0f;
        b(2, 0) = 3.0f;

        std::cout << "System: A * x = b\n";
        std::cout << "A:\n";
        A.print_matrix(true);
        std::cout << "b:\n";
        b.print_matrix(true);

        tiny::Mat::LUDecomposition lu = A.lu_decompose(true);
        tiny::Mat x = tiny::Mat::solve_lu(lu, b);

        std::cout << "\n[Results]\n";
        std::cout << "Solution x:\n";
        x.print_matrix(true);

        // Verify: A * x = b
        tiny::Mat Ax = A * x;
        float error = 0.0f;
        for (int i = 0; i < 3; ++i)
        {
            error += fabsf(Ax(i, 0) - b(i, 0));
        }
        std::cout << "Verification error: " << error << (error < 0.01f ? " [PASS]" : " [FAIL]") << "\n";
    }

    // Test 7.3: Cholesky Decomposition
    std::cout << "\n[Test 7.3] Cholesky Decomposition\n";

    // Test 7.3.1: Symmetric positive definite matrix
    {
        std::cout << "\n[Test 7.3.1] SPD Matrix - Cholesky Decomposition\n";
        tiny::Mat spd(3, 3);
        spd(0, 0) = 4.0f; spd(0, 1) = 2.0f; spd(0, 2) = 0.0f;
        spd(1, 0) = 2.0f; spd(1, 1) = 5.0f; spd(1, 2) = 1.0f;
        spd(2, 0) = 0.0f; spd(2, 1) = 1.0f; spd(2, 2) = 3.0f;
        std::cout << "Matrix A (SPD):\n";
        spd.print_matrix(true);

        tiny::Mat::CholeskyDecomposition chol = spd.cholesky_decompose();
        std::cout << "\n[Results]\n";
        std::cout << "Status: " << (chol.status == TINY_OK ? "OK" : "Error") << "\n";
        if (chol.status == TINY_OK)
        {
            std::cout << "L matrix (lower triangular):\n";
            chol.L.print_matrix(true);

            // Verify: A = L * L^T
            tiny::Mat LLT = chol.L * chol.L.transpose();
            std::cout << "\n[Verification] L * L^T should equal A\n";
            float diff = 0.0f;
            for (int i = 0; i < 3; ++i)
            {
                for (int j = 0; j < 3; ++j)
                {
                    diff += fabsf(LLT(i, j) - spd(i, j));
                }
            }
            std::cout << "Total difference: " << diff << (diff < 0.01f ? " [PASS]" : " [FAIL]") << "\n";
        }
    }

    // Test 7.3.2: Solve using Cholesky decomposition
    {
        std::cout << "\n[Test 7.3.2] Solve Linear System using Cholesky Decomposition\n";
        tiny::Mat A(3, 3);
        A(0, 0) = 4.0f; A(0, 1) = 2.0f; A(0, 2) = 0.0f;
        A(1, 0) = 2.0f; A(1, 1) = 5.0f; A(1, 2) = 1.0f;
        A(2, 0) = 0.0f; A(2, 1) = 1.0f; A(2, 2) = 3.0f;
        tiny::Mat b(3, 1);
        b(0, 0) = 2.0f;
        b(1, 0) = 3.0f;
        b(2, 0) = 1.0f;

        tiny::Mat::CholeskyDecomposition chol = A.cholesky_decompose();
        tiny::Mat x = tiny::Mat::solve_cholesky(chol, b);

        std::cout << "Solution x:\n";
        x.print_matrix(true);

        // Verify: A * x = b
        tiny::Mat Ax = A * x;
        float error = 0.0f;
        for (int i = 0; i < 3; ++i)
        {
            error += fabsf(Ax(i, 0) - b(i, 0));
        }
        std::cout << "Verification error: " << error << (error < 0.01f ? " [PASS]" : " [FAIL]") << "\n";
    }

    // Test 7.4: QR Decomposition
    std::cout << "\n[Test 7.4] QR Decomposition\n";

    // Test 7.4.1: General matrix
    {
        std::cout << "\n[Test 7.4.1] General 3x3 Matrix - QR Decomposition\n";
        tiny::Mat A(3, 3);
        A(0, 0) = 1.0f; A(0, 1) = 2.0f; A(0, 2) = 3.0f;
        A(1, 0) = 4.0f; A(1, 1) = 5.0f; A(1, 2) = 6.0f;
        A(2, 0) = 7.0f; A(2, 1) = 8.0f; A(2, 2) = 9.0f;
        std::cout << "Matrix A:\n";
        A.print_matrix(true);

        tiny::Mat::QRDecomposition qr = A.qr_decompose();
        std::cout << "\n[Results]\n";
        std::cout << "Status: " << (qr.status == TINY_OK ? "OK" : "Error") << "\n";
        if (qr.status == TINY_OK)
        {
            std::cout << "Q matrix (orthogonal):\n";
            qr.Q.print_matrix(true);
            std::cout << "R matrix (upper triangular):\n";
            qr.R.print_matrix(true);

            // Verify: A = Q * R
            tiny::Mat QR = qr.Q * qr.R;
            std::cout << "\n[Verification] Q * R should equal A\n";
            float diff = 0.0f;
            for (int i = 0; i < 3; ++i)
            {
                for (int j = 0; j < 3; ++j)
                {
                    diff += fabsf(QR(i, j) - A(i, j));
                }
            }
            std::cout << "Total difference: " << diff << (diff < 0.1f ? " [PASS]" : " [FAIL]") << "\n";

            // Verify Q is orthogonal: Q^T * Q = I
            tiny::Mat QtQ = qr.Q.transpose() * qr.Q;
            tiny::Mat I = tiny::Mat::eye(3);
            float ortho_diff = 0.0f;
            for (int i = 0; i < 3; ++i)
            {
                for (int j = 0; j < 3; ++j)
                {
                    ortho_diff += fabsf(QtQ(i, j) - I(i, j));
                }
            }
            std::cout << "Q orthogonality error: " << ortho_diff << (ortho_diff < 0.1f ? " [PASS]" : " [FAIL]") << "\n";
        }
    }

    // Test 7.4.2: Solve using QR decomposition (least squares)
    {
        std::cout << "\n[Test 7.4.2] Least Squares Solution using QR Decomposition\n";
        tiny::Mat A(3, 2);  // Overdetermined system
        A(0, 0) = 1.0f; A(0, 1) = 1.0f;
        A(1, 0) = 1.0f; A(1, 1) = 2.0f;
        A(2, 0) = 1.0f; A(2, 1) = 3.0f;
        tiny::Mat b(3, 1);
        b(0, 0) = 2.0f;
        b(1, 0) = 3.0f;
        b(2, 0) = 4.0f;

        std::cout << "Overdetermined system: A * x ≈ b\n";
        std::cout << "A:\n";
        A.print_matrix(true);
        std::cout << "b:\n";
        b.print_matrix(true);

        tiny::Mat::QRDecomposition qr = A.qr_decompose();
        tiny::Mat x = tiny::Mat::solve_qr(qr, b);

        std::cout << "\n[Results]\n";
        std::cout << "Least squares solution x:\n";
        x.print_matrix(true);

        // Compute residual: ||A * x - b||
        tiny::Mat Ax = A * x;
        tiny::Mat residual = Ax - b;
        float residual_norm = 0.0f;
        for (int i = 0; i < 3; ++i)
        {
            residual_norm += residual(i, 0) * residual(i, 0);
        }
        residual_norm = sqrtf(residual_norm);
        std::cout << "Residual norm ||A*x - b||: " << residual_norm << "\n";
    }

    // Test 7.5: SVD Decomposition
    std::cout << "\n[Test 7.5] Singular Value Decomposition (SVD)\n";

    // Test 7.5.1: General matrix
    {
        std::cout << "\n[Test 7.5.1] General 3x3 Matrix - SVD Decomposition\n";
        tiny::Mat A(3, 3);
        A(0, 0) = 1.0f; A(0, 1) = 2.0f; A(0, 2) = 3.0f;
        A(1, 0) = 4.0f; A(1, 1) = 5.0f; A(1, 2) = 6.0f;
        A(2, 0) = 7.0f; A(2, 1) = 8.0f; A(2, 2) = 9.0f;
        std::cout << "Matrix A:\n";
        A.print_matrix(true);

        tiny::Mat::SVDDecomposition svd = A.svd_decompose(100, 1e-6f);
        std::cout << "\n[Results]\n";
        std::cout << "Status: " << (svd.status == TINY_OK ? "OK" : "Error") << "\n";
        if (svd.status == TINY_OK)
        {
            std::cout << "Singular values:\n";
            svd.S.print_matrix(true);
            std::cout << "Numerical rank: " << svd.rank << "\n";
            std::cout << "Iterations: " << svd.iterations << "\n";

            // Verify: A ≈ U * S * V^T (for first rank columns)
            if (svd.rank > 0)
            {
                tiny::Mat US(svd.U.row, svd.rank);
                for (int i = 0; i < svd.U.row; ++i)
                {
                    for (int j = 0; j < svd.rank; ++j)
                    {
                        US(i, j) = svd.U(i, j) * svd.S(j, 0);
                    }
                }
                tiny::Mat Vt(svd.rank, svd.V.row);
                for (int i = 0; i < svd.rank; ++i)
                {
                    for (int j = 0; j < svd.V.row; ++j)
                    {
                        Vt(i, j) = svd.V(j, i);  // V^T
                    }
                }
                tiny::Mat USVt = US * Vt;

                float diff = 0.0f;
                for (int i = 0; i < 3; ++i)
                {
                    for (int j = 0; j < 3; ++j)
                    {
                        diff += fabsf(USVt(i, j) - A(i, j));
                    }
                }
                std::cout << "Reconstruction error: " << diff << (diff < 0.5f ? " [PASS]" : " [FAIL]") << "\n";
            }
        }
    }

    // Test 7.5.2: Pseudo-inverse using SVD
    {
        std::cout << "\n[Test 7.5.2] Pseudo-inverse using SVD\n";
        tiny::Mat A(3, 2);  // Non-square matrix
        A(0, 0) = 1.0f; A(0, 1) = 2.0f;
        A(1, 0) = 3.0f; A(1, 1) = 4.0f;
        A(2, 0) = 5.0f; A(2, 1) = 6.0f;

        std::cout << "Matrix A (3x2):\n";
        A.print_matrix(true);

        tiny::Mat::SVDDecomposition svd = A.svd_decompose(100, 1e-6f);
        tiny::Mat A_plus = tiny::Mat::pseudo_inverse(svd, 1e-6f);

        std::cout << "\n[Results]\n";
        std::cout << "Pseudo-inverse A^+ (2x3):\n";
        A_plus.print_matrix(true);

        // Verify: A * A^+ * A ≈ A
        tiny::Mat AAplusA = A * A_plus * A;
        float diff = 0.0f;
        for (int i = 0; i < 3; ++i)
        {
            for (int j = 0; j < 2; ++j)
            {
                diff += fabsf(AAplusA(i, j) - A(i, j));
            }
        }
        std::cout << "Verification error (A * A^+ * A ≈ A): " << diff << (diff < 0.1f ? " [PASS]" : " [FAIL]") << "\n";
    }

    // Test 7.6: Performance Tests
    std::cout << "\n[Test 7.6] Matrix Decomposition Performance Tests\n";

    tiny::Mat perf_mat(4, 4);
    perf_mat(0, 0) = 4.0f; perf_mat(0, 1) = 2.0f; perf_mat(0, 2) = 1.0f; perf_mat(0, 3) = 0.0f;
    perf_mat(1, 0) = 2.0f; perf_mat(1, 1) = 5.0f; perf_mat(1, 2) = 1.0f; perf_mat(1, 3) = 0.0f;
    perf_mat(2, 0) = 1.0f; perf_mat(2, 1) = 1.0f; perf_mat(2, 2) = 3.0f; perf_mat(2, 3) = 1.0f;
    perf_mat(3, 0) = 0.0f; perf_mat(3, 1) = 0.0f; perf_mat(3, 2) = 1.0f; perf_mat(3, 3) = 2.0f;

    // Test 7.6.1: LU decomposition performance
    std::cout << "\n[Test 7.6.1] LU Decomposition Performance\n";
    TIME_OPERATION(
        tiny::Mat::LUDecomposition perf_lu = perf_mat.lu_decompose(true);
        (void)perf_lu;
    , "LU Decomposition (4x4 matrix)");

    // Test 7.6.2: Cholesky decomposition performance
    std::cout << "\n[Test 7.6.2] Cholesky Decomposition Performance\n";
    TIME_OPERATION(
        tiny::Mat::CholeskyDecomposition perf_chol = perf_mat.cholesky_decompose();
        (void)perf_chol;
    , "Cholesky Decomposition (4x4 SPD matrix)");

    // Test 7.6.3: QR decomposition performance
    std::cout << "\n[Test 7.6.3] QR Decomposition Performance\n";
    TIME_OPERATION(
        tiny::Mat::QRDecomposition perf_qr = perf_mat.qr_decompose();
        (void)perf_qr;
    , "QR Decomposition (4x4 matrix)");

    // Test 7.6.4: SVD decomposition performance
    std::cout << "\n[Test 7.6.4] SVD Decomposition Performance\n";
    TIME_OPERATION(
        tiny::Mat::SVDDecomposition perf_svd = perf_mat.svd_decompose(50, 1e-5f);
        (void)perf_svd;
    , "SVD Decomposition (4x4 matrix)");

    std::cout << "\n[Matrix Decomposition Tests Complete]\n";
}

// ============================================================================
// Group 8: Advanced Linear Algebra - Gram-Schmidt Orthogonalization Tests
// ============================================================================
// Purpose: Test Gram-Schmidt orthogonalization process - fundamental operation for
//          QR decomposition, eigenvalue decomposition, and basis transformation
void test_gram_schmidt_orthogonalize()
{
    std::cout << "\n[Group 8: Advanced Linear Algebra - Gram-Schmidt Orthogonalization Tests]\n";

    // Test 8.1: Basic orthogonalization of linearly independent vectors
    {
        std::cout << "\n[Test 8.1] Basic Orthogonalization - Linearly Independent Vectors\n";
        tiny::Mat vectors(3, 3);
        // Create three linearly independent vectors
        vectors(0, 0) = 1.0f; vectors(0, 1) = 1.0f; vectors(0, 2) = 0.0f;
        vectors(1, 0) = 0.0f; vectors(1, 1) = 1.0f; vectors(1, 2) = 1.0f;
        vectors(2, 0) = 1.0f; vectors(2, 1) = 0.0f; vectors(2, 2) = 1.0f;

        std::cout << "Input vectors (each column is a vector):\n";
        vectors.print_matrix(true);

        tiny::Mat Q, R;
        bool success = tiny::Mat::gram_schmidt_orthogonalize(vectors, Q, R, 1e-6f);

        std::cout << "\n[Results]\n";
        std::cout << "Status: " << (success ? "OK" : "Error") << "\n";
        if (success)
        {
            std::cout << "Orthogonalized vectors Q (each column is orthogonal):\n";
            Q.print_matrix(true);
            std::cout << "Coefficients R (upper triangular):\n";
            R.print_matrix(true);

            // Verify orthogonality: Q^T * Q should be identity (or close to it)
            tiny::Mat QtQ = Q.transpose() * Q;
            tiny::Mat I = tiny::Mat::eye(3);
            float ortho_error = 0.0f;
            for (int i = 0; i < 3; ++i)
            {
                for (int j = 0; j < 3; ++j)
                {
                    ortho_error += fabsf(QtQ(i, j) - I(i, j));
                }
            }
            std::cout << "\n[Verification] Q^T * Q should be identity\n";
            std::cout << "Orthogonality error: " << ortho_error 
                      << (ortho_error < 0.1f ? " [PASS]" : " [FAIL]") << "\n";

            // Verify normalization: each column of Q should be unit vector
            std::cout << "\n[Verification] Each column of Q should be normalized\n";
            bool all_normalized = true;
            for (int j = 0; j < 3; ++j)
            {
                float norm = 0.0f;
                for (int i = 0; i < 3; ++i)
                {
                    norm += Q(i, j) * Q(i, j);
                }
                norm = sqrtf(norm);
                float norm_error = fabsf(norm - 1.0f);
                std::cout << "  Column " << j << " norm: " << norm 
                          << " (error: " << norm_error << ")";
                if (norm_error > 0.01f)
                {
                    all_normalized = false;
                    std::cout << " [FAIL]";
                }
                else
                {
                    std::cout << " [PASS]";
                }
                std::cout << "\n";
            }

            // Verify reconstruction: vectors should equal Q * R (approximately)
            tiny::Mat QR = Q * R;
            float recon_error = 0.0f;
            for (int i = 0; i < 3; ++i)
            {
                for (int j = 0; j < 3; ++j)
                {
                    recon_error += fabsf(QR(i, j) - vectors(i, j));
                }
            }
            std::cout << "\n[Verification] Q * R should reconstruct original vectors\n";
            std::cout << "Reconstruction error: " << recon_error 
                      << (recon_error < 0.1f ? " [PASS]" : " [FAIL]") << "\n";
        }
    }

    // Test 8.2: Orthogonalization with near-linear-dependent vectors
    {
        std::cout << "\n[Test 8.2] Orthogonalization - Near-Linear-Dependent Vectors\n";
        tiny::Mat vectors(3, 3);
        // Create vectors where third is almost a linear combination of first two
        vectors(0, 0) = 1.0f; vectors(0, 1) = 0.0f; vectors(0, 2) = 1.0f;
        vectors(1, 0) = 0.0f; vectors(1, 1) = 1.0f; vectors(1, 2) = 1.0f;
        vectors(2, 0) = 0.0f; vectors(2, 1) = 0.0f; vectors(2, 2) = 0.001f;  // Very small third component

        std::cout << "Input vectors (third vector is nearly linear dependent):\n";
        vectors.print_matrix(true);

        tiny::Mat Q, R;
        bool success = tiny::Mat::gram_schmidt_orthogonalize(vectors, Q, R, 1e-6f);

        std::cout << "\n[Results]\n";
        std::cout << "Status: " << (success ? "OK" : "Error") << "\n";
        if (success)
        {
            std::cout << "Orthogonalized vectors Q:\n";
            Q.print_matrix(true);
            std::cout << "Coefficients R:\n";
            R.print_matrix(true);

            // Check if third column was handled correctly (should be zero or orthogonal)
            float third_col_norm = 0.0f;
            for (int i = 0; i < 3; ++i)
            {
                third_col_norm += Q(i, 2) * Q(i, 2);
            }
            third_col_norm = sqrtf(third_col_norm);
            std::cout << "\n[Note] Third column norm: " << third_col_norm 
                      << " (should be 0 if linearly dependent, or 1 if orthogonalized)\n";
        }
    }

    // Test 8.3: Orthogonalization of 2D vectors
    {
        std::cout << "\n[Test 8.3] Orthogonalization - 2D Vectors (2x2)\n";
        tiny::Mat vectors(2, 2);
        vectors(0, 0) = 3.0f; vectors(0, 1) = 1.0f;
        vectors(1, 0) = 1.0f; vectors(1, 1) = 2.0f;

        std::cout << "Input vectors:\n";
        vectors.print_matrix(true);

        tiny::Mat Q, R;
        bool success = tiny::Mat::gram_schmidt_orthogonalize(vectors, Q, R, 1e-6f);

        std::cout << "\n[Results]\n";
        std::cout << "Status: " << (success ? "OK" : "Error") << "\n";
        if (success)
        {
            std::cout << "Orthogonalized vectors Q:\n";
            Q.print_matrix(true);
            std::cout << "Coefficients R:\n";
            R.print_matrix(true);

            // Verify orthogonality
            float dot_product = 0.0f;
            for (int i = 0; i < 2; ++i)
            {
                dot_product += Q(i, 0) * Q(i, 1);
            }
            std::cout << "\n[Verification] Dot product of Q columns: " << dot_product 
                      << " (should be ~0 for orthogonal) " 
                      << (fabsf(dot_product) < 0.01f ? "[PASS]" : "[FAIL]") << "\n";
        }
    }

    // Test 8.4: Error handling - invalid input
    {
        std::cout << "\n[Test 8.4] Error Handling - Invalid Input\n";
        tiny::Mat empty_mat;  // Empty matrix
        tiny::Mat Q, R;
        bool success = tiny::Mat::gram_schmidt_orthogonalize(empty_mat, Q, R, 1e-6f);
        std::cout << "Empty matrix test: " << (success ? "FAIL (should return false)" : "PASS (correctly rejected)") << "\n";
    }
}

// ============================================================================
// Group 9: System Identification - Eigenvalue and Eigenvector Decomposition Tests
// ============================================================================
// Purpose: Test eigenvalue decomposition - critical for SHM and system identification
//          applications (modal analysis, natural frequencies, mode shapes)
void test_eigenvalue_decomposition()
{
    std::cout << "\n[Group 9: System Identification - Eigenvalue and Eigenvector Decomposition Tests]\n";

    // Test 9.1: is_symmetric() - Basic functionality
    std::cout << "\n[Test 9.1] is_symmetric() - Basic Functionality\n";

    // Test 9.1.1: Symmetric matrix
    {
        std::cout << "[Test 9.1.1] Symmetric 3x3 Matrix\n";
        tiny::Mat sym_mat1(3, 3);
        sym_mat1(0, 0) = 4.0f; sym_mat1(0, 1) = 1.0f; sym_mat1(0, 2) = 2.0f;
        sym_mat1(1, 0) = 1.0f; sym_mat1(1, 1) = 3.0f; sym_mat1(1, 2) = 0.0f;
        sym_mat1(2, 0) = 2.0f; sym_mat1(2, 1) = 0.0f; sym_mat1(2, 2) = 5.0f;
        bool is_sym1 = sym_mat1.is_symmetric(1e-5f);
        std::cout << "Matrix:\n";
        sym_mat1.print_matrix(true);
        std::cout << "Is symmetric: " << (is_sym1 ? "True" : "False") << " (Expected: True)\n";
    }

    // Test 9.1.2: Non-symmetric matrix (keep for later tests)
    tiny::Mat non_sym_mat(3, 3);
    {
        std::cout << "\n[Test 9.1.2] Non-Symmetric 3x3 Matrix\n";
        non_sym_mat(0, 0) = 1.0f; non_sym_mat(0, 1) = 2.0f; non_sym_mat(0, 2) = 3.0f;
        non_sym_mat(1, 0) = 4.0f; non_sym_mat(1, 1) = 5.0f; non_sym_mat(1, 2) = 6.0f;
        non_sym_mat(2, 0) = 7.0f; non_sym_mat(2, 1) = 8.0f; non_sym_mat(2, 2) = 9.0f;
        bool is_sym2 = non_sym_mat.is_symmetric(1e-5f);
        std::cout << "Matrix:\n";
        non_sym_mat.print_matrix(true);
        std::cout << "Is symmetric: " << (is_sym2 ? "True" : "False") << " (Expected: False)\n";
    }

    // Test 9.1.3: Non-square matrix
    {
        std::cout << "\n[Test 9.1.3] Non-Square Matrix (2x3)\n";
        tiny::Mat rect_mat(2, 3);
        bool is_sym3 = rect_mat.is_symmetric(1e-5f);
        std::cout << "Is symmetric: " << (is_sym3 ? "True" : "False") << " (Expected: False)\n";
    }

    // Test 9.1.4: Symmetric matrix with small numerical errors
    {
        std::cout << "\n[Test 9.1.4] Symmetric Matrix with Small Numerical Errors\n";
        tiny::Mat sym_mat2(2, 2);
        // Use 1e-5 error which is within float precision (float has ~7 significant digits)
        // For 2.0, we can represent 2.00001 accurately
        float error_value = 1e-5f;
        sym_mat2(0, 0) = 1.0f; 
        sym_mat2(0, 1) = 2.0f + error_value;
        sym_mat2(1, 0) = 2.0f; 
        sym_mat2(1, 1) = 3.0f;
        std::cout << "Matrix with error " << error_value << ":\n";
        sym_mat2.print_matrix(true);
        float diff = fabsf(sym_mat2(0, 1) - sym_mat2(1, 0));
        std::cout << "Difference: |A(0,1) - A(1,0)| = ";
        // Use scientific notation for small values
        if (diff < 1e-3f)
        {
            std::cout << std::scientific << std::setprecision(6) << diff << std::fixed;
        }
        else
        {
            std::cout << std::setprecision(6) << diff;
        }
        std::cout << " (Expected: " << error_value << ")\n";

        // Verify the difference is actually stored
        float stored_value = sym_mat2(0, 1);
        float expected_stored = 2.0f + error_value;
        std::cout << "A(0,1) stored value: " << std::setprecision(8) << stored_value 
                  << " (Expected: " << expected_stored << ")\n";

        bool is_sym4 = sym_mat2.is_symmetric(1e-4f); // tolerance > error, should pass
        std::cout << "Is symmetric (tolerance=1e-4): " << (is_sym4 ? "True" : "False") 
                  << " (Expected: True, tolerance > error) ";
        std::cout << (is_sym4 ? "[PASS]" : "[FAIL]") << "\n";

        bool is_sym5 = sym_mat2.is_symmetric(1e-6f); // tolerance < error, should fail
        std::cout << "Is symmetric (tolerance=1e-6): " << (is_sym5 ? "True" : "False") 
                  << " (Expected: False, tolerance < error) ";
        bool correct_result = !is_sym5; // Should be False (not symmetric)
        std::cout << (correct_result ? "[PASS]" : "[FAIL]") << "\n";

        // Additional check: verify the difference is close to expected
        float diff_error = fabsf(diff - error_value);
        std::cout << "Difference accuracy: |actual_diff - expected_diff| = " 
                  << std::scientific << std::setprecision(2) << diff_error << std::fixed;
        bool diff_accurate = (diff_error < error_value * 0.1f); // Within 10% of error value
        std::cout << " " << (diff_accurate ? "[PASS - difference stored correctly]" : "[FAIL - float precision issue]") << "\n";
    }

    // Test 9.2: power_iteration() - Dominant eigenvalue
    std::cout << "\n[Test 9.2] power_iteration() - Dominant Eigenvalue\n";

    // Test 9.2.1: Simple 2x2 symmetric matrix (known eigenvalues)
    tiny::Mat mat2x2(2, 2);
    {
        std::cout << "\n[Test 9.2.1] Simple 2x2 Matrix\n";
        mat2x2(0, 0) = 2.0f; mat2x2(0, 1) = 1.0f;
        mat2x2(1, 0) = 1.0f; mat2x2(1, 1) = 2.0f;
        std::cout << "Matrix:\n";
        mat2x2.print_matrix(true);

        // Expected values: eigenvalues are 3 and 1 (for matrix [2,1; 1,2])
        // Characteristic equation: det([2-λ, 1; 1, 2-λ]) = (2-λ)² - 1 = λ² - 4λ + 3 = 0
        // Solutions: λ = (4 ± √(16-12))/2 = (4 ± 2)/2 = 3 or 1
        std::cout << "\n[Expected Results]\n";
        std::cout << "  Expected eigenvalues: 3.0 (largest), 1.0 (smallest)\n";
        std::cout << "  Expected dominant eigenvector (for λ=3): approximately [0.707, 0.707] or [-0.707, -0.707] (normalized)\n";
        std::cout << "  Expected dominant eigenvector (for λ=1): approximately [0.707, -0.707] or [-0.707, 0.707] (normalized)\n";

        tiny::Mat::EigenPair result_power = mat2x2.power_iteration(1000, 1e-6f);
        std::cout << "\n[Actual Results]\n";
        std::cout << "  Dominant eigenvalue: " << result_power.eigenvalue 
                  << " (Expected: 3.0, largest eigenvalue)\n";
        std::cout << "  Iterations: " << result_power.iterations << "\n";
        std::cout << "  Status: " << (result_power.status == TINY_OK ? "OK" : "Error") << "\n";
        std::cout << "  Dominant eigenvector:\n";
        result_power.eigenvector.print_matrix(true);

        // Check if result matches expected
        float error = fabsf(result_power.eigenvalue - 3.0f);
        std::cout << "  Error from expected (3.0): " << error << (error < 0.01f ? " [PASS]" : " [FAIL]") << "\n";
    }

    // Test 9.2.2: 3x3 matrix (SHM-like stiffness matrix) - keep for later tests
    tiny::Mat stiffness(3, 3);
    {
        std::cout << "\n[Test 9.2.2] 3x3 Stiffness Matrix (SHM Application)\n";
        stiffness(0, 0) = 2.0f; stiffness(0, 1) = -1.0f; stiffness(0, 2) = 0.0f;
        stiffness(1, 0) = -1.0f; stiffness(1, 1) = 2.0f; stiffness(1, 2) = -1.0f;
        stiffness(2, 0) = 0.0f; stiffness(2, 1) = -1.0f; stiffness(2, 2) = 2.0f;
        std::cout << "Stiffness Matrix:\n";
        stiffness.print_matrix(true);

        // Expected values for 3x3 tridiagonal symmetric matrix [2,-1,0; -1,2,-1; 0,-1,2]
        // This is a standard tridiagonal matrix with known eigenvalues
        // Approximate eigenvalues: λ₁ ≈ 3.414, λ₂ ≈ 2.000, λ₃ ≈ 0.586
        std::cout << "\n[Expected Results]\n";
        std::cout << "  Expected eigenvalues (approximate): 3.414 (largest), 2.000, 0.586 (smallest)\n";
        std::cout << "  Expected primary frequency: sqrt(3.414) ≈ 1.848 rad/s\n";

        tiny::Mat::EigenPair result_stiff = stiffness.power_iteration(500, 1e-6f);
        std::cout << "\n[Actual Results]\n";
        std::cout << "  Dominant eigenvalue (primary frequency squared): " << result_stiff.eigenvalue << "\n";
        std::cout << "  Primary frequency: " << sqrtf(result_stiff.eigenvalue) << " rad/s (Expected: ~1.848 rad/s)\n";
        std::cout << "  Iterations: " << result_stiff.iterations << "\n";
        std::cout << "  Status: " << (result_stiff.status == TINY_OK ? "OK" : "Error") << "\n";

        float expected_eigen = 3.414f;
        float error = fabsf(result_stiff.eigenvalue - expected_eigen);
        std::cout << "  Error from expected (" << expected_eigen << "): " << error << (error < 0.1f ? " [PASS]" : " [FAIL]") << "\n";
    }

    // Test 9.2.3: Non-square matrix (should fail)
    {
        std::cout << "\n[Test 9.2.3] Non-Square Matrix (Expect Error)\n";
        tiny::Mat non_square(2, 3);
        tiny::Mat::EigenPair result_error = non_square.power_iteration(100, 1e-6f);
        std::cout << "Status: " << (result_error.status == TINY_OK ? "OK" : "Error (Expected)") << "\n";
    }

    // Test 9.2.4: inverse_power_iteration() - Smallest eigenvalue (Critical for System Identification)
    std::cout << "\n[Test 9.2.4] inverse_power_iteration() - Smallest Eigenvalue (System Identification)\n";

    // Test 9.2.4.1: Simple 2x2 symmetric matrix (known eigenvalues)
    {
        std::cout << "\n[Test 9.2.4.1] Simple 2x2 Matrix - Smallest Eigenvalue\n";
        std::cout << "Matrix (same as Test 9.2.1):\n";
        mat2x2.print_matrix(true);

        // Expected values: eigenvalues are 3 and 1 (for matrix [2,1; 1,2])
        // Power iteration finds λ_max = 3, inverse power iteration should find λ_min = 1
        std::cout << "\n[Expected Results]\n";
        std::cout << "  Expected eigenvalues: 3.0 (largest), 1.0 (smallest)\n";
        std::cout << "  Expected smallest eigenvalue: 1.0\n";
        std::cout << "  Expected smallest eigenvector (for λ=1): approximately [0.707, -0.707] or [-0.707, 0.707] (normalized)\n";
        std::cout << "  Note: This is critical for system identification - smallest eigenvalue = fundamental frequency\n";

        tiny::Mat::EigenPair result_inv_power = mat2x2.inverse_power_iteration(1000, 1e-6f);
        std::cout << "\n[Actual Results]\n";
        std::cout << "  Smallest eigenvalue: " << result_inv_power.eigenvalue 
                  << " (Expected: 1.0, smallest eigenvalue)\n";
        std::cout << "  Iterations: " << result_inv_power.iterations << "\n";
        std::cout << "  Status: " << (result_inv_power.status == TINY_OK ? "OK" : "Error") << "\n";
        std::cout << "  Smallest eigenvector:\n";
        result_inv_power.eigenvector.print_matrix(true);

        // Check if result matches expected
        float error = fabsf(result_inv_power.eigenvalue - 1.0f);
        std::cout << "  Error from expected (1.0): " << error << (error < 0.01f ? " [PASS]" : " [FAIL]") << "\n";

        // Compare with power iteration results (recompute for comparison)
        tiny::Mat::EigenPair result_power_compare = mat2x2.power_iteration(1000, 1e-6f);
        std::cout << "\n[Comparison] Power vs Inverse Power Iteration:\n";
        std::cout << "  Power iteration (λ_max): " << result_power_compare.eigenvalue << "\n";
        std::cout << "  Inverse power iteration (λ_min): " << result_inv_power.eigenvalue << "\n";
        std::cout << "  Ratio (λ_max/λ_min): " << (result_power_compare.eigenvalue / result_inv_power.eigenvalue) 
                  << " (Expected: ~3.0) " << (fabsf(result_power_compare.eigenvalue / result_inv_power.eigenvalue - 3.0f) < 0.1f ? "[PASS]" : "[FAIL]") << "\n";
    }

    // Test 9.2.4.2: 3x3 stiffness matrix - Smallest eigenvalue (SHM Application)
    {
        std::cout << "\n[Test 9.2.4.2] 3x3 Stiffness Matrix - Smallest Eigenvalue (SHM Application)\n";
        std::cout << "Stiffness Matrix (same as Test 9.2.2):\n";
        stiffness.print_matrix(true);

        // Expected values for 3x3 tridiagonal symmetric matrix [2,-1,0; -1,2,-1; 0,-1,2]
        // Approximate eigenvalues: λ₁ ≈ 3.414 (largest), λ₂ ≈ 2.000, λ₃ ≈ 0.586 (smallest)
        std::cout << "\n[Expected Results]\n";
        std::cout << "  Expected eigenvalues (approximate): 3.414 (largest), 2.000, 0.586 (smallest)\n";
        std::cout << "  Expected smallest eigenvalue: ~0.586 (fundamental frequency squared)\n";
        std::cout << "  Expected fundamental frequency: sqrt(0.586) ≈ 0.765 rad/s\n";
        std::cout << "  Note: Smallest eigenvalue is critical for system identification - represents fundamental mode\n";

        tiny::Mat::EigenPair result_inv_stiff = stiffness.inverse_power_iteration(500, 1e-6f);
        std::cout << "\n[Actual Results]\n";
        std::cout << "  Smallest eigenvalue (fundamental frequency squared): " << result_inv_stiff.eigenvalue << "\n";
        std::cout << "  Fundamental frequency: " << sqrtf(result_inv_stiff.eigenvalue) << " rad/s (Expected: ~0.765 rad/s)\n";
        std::cout << "  Iterations: " << result_inv_stiff.iterations << "\n";
        std::cout << "  Status: " << (result_inv_stiff.status == TINY_OK ? "OK" : "Error") << "\n";
        std::cout << "  Smallest eigenvector (fundamental mode shape):\n";
        result_inv_stiff.eigenvector.print_matrix(true);

        float expected_eigen = 0.586f;
        float error = fabsf(result_inv_stiff.eigenvalue - expected_eigen);
        std::cout << "  Error from expected (" << expected_eigen << "): " << error << (error < 0.1f ? " [PASS]" : " [FAIL]") << "\n";

        // Compare with power iteration (recompute for comparison)
        tiny::Mat::EigenPair result_stiff_compare = stiffness.power_iteration(500, 1e-6f);
        std::cout << "\n[Comparison] Power vs Inverse Power Iteration for SHM:\n";
        std::cout << "  Power iteration (primary frequency²): " << result_stiff_compare.eigenvalue 
                  << " → frequency: " << sqrtf(result_stiff_compare.eigenvalue) << " rad/s\n";
        std::cout << "  Inverse power iteration (fundamental frequency²): " << result_inv_stiff.eigenvalue 
                  << " → frequency: " << sqrtf(result_inv_stiff.eigenvalue) << " rad/s\n";
        std::cout << "  Frequency ratio: " << (sqrtf(result_stiff_compare.eigenvalue) / sqrtf(result_inv_stiff.eigenvalue))
                  << " (Expected: ~2.4, ratio of highest to lowest mode)\n";
    }

    // Test 9.2.4.3: Non-square matrix (should fail)
    {
        std::cout << "\n[Test 9.2.4.3] Non-Square Matrix (Expect Error)\n";
        tiny::Mat non_square(2, 3);
        tiny::Mat::EigenPair result_error = non_square.inverse_power_iteration(100, 1e-6f);
        std::cout << "Status: " << (result_error.status == TINY_OK ? "OK" : "Error (Expected)") << "\n";
        bool correct = (result_error.status != TINY_OK);
        std::cout << "Error handling: " << (correct ? "[PASS]" : "[FAIL]") << "\n";
    }

    // Test 9.2.4.4: Near-singular matrix (should handle gracefully)
    {
        std::cout << "\n[Test 9.2.4.4] Near-Singular Matrix (Edge Case)\n";
        tiny::Mat near_singular(3, 3);
        // Create a matrix that is close to singular but still invertible
        near_singular(0, 0) = 1.0f; near_singular(0, 1) = 0.0f; near_singular(0, 2) = 0.0f;
        near_singular(1, 0) = 0.0f; near_singular(1, 1) = 1.0f; near_singular(1, 2) = 0.001f;
        near_singular(2, 0) = 0.0f; near_singular(2, 1) = 0.001f; near_singular(2, 2) = 1.0f;
        std::cout << "Matrix (near-singular but invertible):\n";
        near_singular.print_matrix(true);

        tiny::Mat::EigenPair result_near_sing = near_singular.inverse_power_iteration(500, 1e-5f);
        std::cout << "\n[Results]\n";
        std::cout << "  Status: " << (result_near_sing.status == TINY_OK ? "OK" : "Error") << "\n";
        if (result_near_sing.status == TINY_OK)
        {
            std::cout << "  Smallest eigenvalue: " << result_near_sing.eigenvalue << "\n";
            std::cout << "  Iterations: " << result_near_sing.iterations << "\n";
            std::cout << "  Note: Successfully handled near-singular matrix [PASS]\n";
        }
        else
        {
            std::cout << "  Note: Correctly detected problematic matrix [PASS]\n";
        }
    }

    // Test 9.3: eigendecompose_jacobi() - Symmetric matrix decomposition
    std::cout << "\n[Test 9.3] eigendecompose_jacobi() - Symmetric Matrix Decomposition\n";

    // Test 9.3.1: Simple 2x2 symmetric matrix
    {
        std::cout << "\n[Test 9.3.1] 2x2 Symmetric Matrix - Complete Decomposition\n";
        std::cout << "[Expected Results]\n";
        std::cout << "  Expected eigenvalues: 3.0, 1.0 (in any order)\n";
        std::cout << "  Expected eigenvectors (for λ=3): [0.707, 0.707] or [-0.707, -0.707] (normalized)\n";
        std::cout << "  Expected eigenvectors (for λ=1): [0.707, -0.707] or [-0.707, 0.707] (normalized)\n";

        tiny::Mat::EigenDecomposition result_jacobi1 = mat2x2.eigendecompose_jacobi(1e-6f, 100);
        std::cout << "\n[Actual Results]\n";
        std::cout << "Eigenvalues:\n";
        result_jacobi1.eigenvalues.print_matrix(true);
        std::cout << "Eigenvectors (each column is an eigenvector):\n";
        result_jacobi1.eigenvectors.print_matrix(true);
        std::cout << "Iterations: " << result_jacobi1.iterations << "\n";
        std::cout << "Status: " << (result_jacobi1.status == TINY_OK ? "OK" : "Error") << "\n";

        // Check eigenvalues
        float ev1 = result_jacobi1.eigenvalues(0, 0);
        float ev2 = result_jacobi1.eigenvalues(1, 0);
        bool ev_check = ((fabsf(ev1 - 3.0f) < 0.01f && fabsf(ev2 - 1.0f) < 0.01f) ||
                         (fabsf(ev1 - 1.0f) < 0.01f && fabsf(ev2 - 3.0f) < 0.01f));
        std::cout << "Eigenvalue check (should be 3.0 and 1.0): " << (ev_check ? "[PASS]" : "[FAIL]") << "\n";

        // Verify: A * v = lambda * v
        std::cout << "\n[Verification] Check A * v = lambda * v for first eigenvector:\n";
        tiny::Mat Av = mat2x2 * result_jacobi1.eigenvectors.block(0, 0, 2, 1);
        tiny::Mat lambda_v = result_jacobi1.eigenvalues(0, 0) * result_jacobi1.eigenvectors.block(0, 0, 2, 1);
        std::cout << "A * v:\n";
        Av.print_matrix(true);
        std::cout << "lambda * v:\n";
        lambda_v.print_matrix(true);
        bool verify1 = matrices_approximately_equal(Av, lambda_v, 1e-4f);
        std::cout << "Verification (A*v = λ*v): " << (verify1 ? "[PASS]" : "[FAIL]") << "\n";
    }

    // Test 9.3.2: 3x3 symmetric matrix (SHM stiffness matrix)
    {
        std::cout << "\n[Test 9.3.2] 3x3 Stiffness Matrix (SHM Application)\n";
        std::cout << "[Expected Results]\n";
        std::cout << "  Expected eigenvalues (approximate): 3.414, 2.000, 0.586\n";
        std::cout << "  Expected natural frequencies: 1.848, 1.414, 0.765 rad/s\n";
        std::cout << "  Note: Eigenvalues may appear in any order\n";

        tiny::Mat::EigenDecomposition result_jacobi2 = stiffness.eigendecompose_jacobi(1e-5f, 100);
        std::cout << "\n[Actual Results]\n";
        std::cout << "Eigenvalues (natural frequencies squared):\n";
        result_jacobi2.eigenvalues.print_matrix(true);
        std::cout << "Natural frequencies (rad/s):\n";
        float expected_freqs[3] = {1.848f, 1.414f, 0.765f};
        for (int i = 0; i < result_jacobi2.eigenvalues.row; ++i)
        {
            float freq = sqrtf(result_jacobi2.eigenvalues(i, 0));
            std::cout << "  Mode " << i << ": " << freq << " rad/s";
            // Check if frequency matches any expected value
            bool matched = false;
            for (int j = 0; j < 3; ++j)
            {
                if (fabsf(freq - expected_freqs[j]) < 0.1f)
                {
                    std::cout << " (Expected: ~" << expected_freqs[j] << " rad/s) [PASS]";
                    matched = true;
                    break;
                }
            }
            if (!matched) std::cout << " [CHECK]";
            std::cout << "\n";
        }
        std::cout << "Eigenvectors (mode shapes):\n";
        result_jacobi2.eigenvectors.print_matrix(true);
        std::cout << "Iterations: " << result_jacobi2.iterations << "\n";
        std::cout << "Status: " << (result_jacobi2.status == TINY_OK ? "OK" : "Error") << "\n";
    }

    // Test 9.3.3: Diagonal matrix (trivial case)
    {
        std::cout << "\n[Test 9.3.3] Diagonal Matrix (Eigenvalues on diagonal)\n";
        tiny::Mat diag_mat(3, 3);
        diag_mat(0, 0) = 5.0f; diag_mat(0, 1) = 0.0f; diag_mat(0, 2) = 0.0f;
        diag_mat(1, 0) = 0.0f; diag_mat(1, 1) = 3.0f; diag_mat(1, 2) = 0.0f;
        diag_mat(2, 0) = 0.0f; diag_mat(2, 1) = 0.0f; diag_mat(2, 2) = 1.0f;
        std::cout << "Matrix:\n";
        diag_mat.print_matrix(true);
        std::cout << "\n[Expected Results]\n";
        std::cout << "  Expected eigenvalues: 5.0, 3.0, 1.0 (diagonal elements, may be in any order)\n";
        std::cout << "  Expected eigenvectors: standard basis vectors [1,0,0], [0,1,0], [0,0,1] (or their negatives)\n";
        std::cout << "  Expected iterations: 1 (diagonal matrix should converge immediately)\n";

        tiny::Mat::EigenDecomposition result_diag = diag_mat.eigendecompose_jacobi(1e-6f, 10);
        std::cout << "\n[Actual Results]\n";
        std::cout << "Eigenvalues:\n";
        result_diag.eigenvalues.print_matrix(true);
        std::cout << "Eigenvectors:\n";
        result_diag.eigenvectors.print_matrix(true);
        std::cout << "Iterations: " << result_diag.iterations << " (Expected: 1)\n";

        // Check eigenvalues
        float ev1 = result_diag.eigenvalues(0, 0);
        float ev2 = result_diag.eigenvalues(1, 0);
        float ev3 = result_diag.eigenvalues(2, 0);
        bool ev_check = ((fabsf(ev1 - 5.0f) < 0.01f || fabsf(ev1 - 3.0f) < 0.01f || fabsf(ev1 - 1.0f) < 0.01f) &&
                         (fabsf(ev2 - 5.0f) < 0.01f || fabsf(ev2 - 3.0f) < 0.01f || fabsf(ev2 - 1.0f) < 0.01f) &&
                         (fabsf(ev3 - 5.0f) < 0.01f || fabsf(ev3 - 3.0f) < 0.01f || fabsf(ev3 - 1.0f) < 0.01f));
        std::cout << "Eigenvalue check (should be 5.0, 3.0, 1.0): " << (ev_check ? "[PASS]" : "[FAIL]") << "\n";
    }

    // Test 9.4: eigendecompose_qr() - General matrix decomposition
    std::cout << "\n[Test 9.4] eigendecompose_qr() - General Matrix Decomposition\n";

    // Test 9.4.1: General 2x2 matrix
    {
        std::cout << "\n[Test 9.4.1] General 2x2 Matrix\n";
        tiny::Mat gen_mat(2, 2);
        gen_mat(0, 0) = 1.0f; gen_mat(0, 1) = 2.0f;
        gen_mat(1, 0) = 3.0f; gen_mat(1, 1) = 4.0f;
        std::cout << "Matrix:\n";
        gen_mat.print_matrix(true);

        // Expected values for matrix [1,2; 3,4]
        // Characteristic equation: det([1-λ, 2; 3, 4-λ]) = (1-λ)(4-λ) - 6 = λ² - 5λ - 2 = 0
        // Solutions: λ = (5 ± √(25+8))/2 = (5 ± √33)/2 ≈ 5.372, -0.372
        std::cout << "\n[Expected Results]\n";
        std::cout << "  Expected eigenvalues: (5+√33)/2 ≈ 5.372, (5-√33)/2 ≈ -0.372\n";
        std::cout << "  Note: This is a non-symmetric matrix, eigenvalues are real but may have complex eigenvectors\n";

        tiny::Mat::EigenDecomposition result_qr1 = gen_mat.eigendecompose_qr(100, 1e-5f);
        std::cout << "\n[Actual Results]\n";
        std::cout << "Eigenvalues:\n";
        result_qr1.eigenvalues.print_matrix(true);
        std::cout << "Eigenvectors:\n";
        result_qr1.eigenvectors.print_matrix(true);
        std::cout << "Iterations: " << result_qr1.iterations << "\n";
        std::cout << "Status: " << (result_qr1.status == TINY_OK ? "OK" : "Error") << "\n";

        // Check eigenvalues with detailed error reporting
        float ev1 = result_qr1.eigenvalues(0, 0);
        float ev2 = result_qr1.eigenvalues(1, 0);
        float expected_ev1 = 5.372f;
        float expected_ev2 = -0.372f;

        // Match eigenvalues to expected values
        float error1a = fabsf(ev1 - expected_ev1);
        float error1b = fabsf(ev1 - expected_ev2);
        float error2a = fabsf(ev2 - expected_ev1);
        float error2b = fabsf(ev2 - expected_ev2);

        bool match1 = (error1a < error1b); // ev1 matches expected_ev1 better
        float matched_ev1 = match1 ? expected_ev1 : expected_ev2;
        float matched_ev2 = match1 ? expected_ev2 : expected_ev1;
        float actual_error1 = match1 ? error1a : error1b;
        float actual_error2 = match1 ? error2b : error2a;
        float rel_error1 = actual_error1 / fabsf(matched_ev1);
        float rel_error2 = actual_error2 / fabsf(matched_ev2);

        std::cout << "Eigenvalue 1: " << ev1 << " (Expected: " << matched_ev1 << ", Error: " << actual_error1 
                  << ", Rel Error: " << (rel_error1 * 100.0f) << "%) ";
        bool pass1 = (rel_error1 < 0.05f); // 5% relative error tolerance
        std::cout << (pass1 ? "[PASS]" : "[FAIL - error too large]") << "\n";

        std::cout << "Eigenvalue 2: " << ev2 << " (Expected: " << matched_ev2 << ", Error: " << actual_error2 
                  << ", Rel Error: " << (rel_error2 * 100.0f) << "%) ";
        bool pass2 = (rel_error2 < 0.05f); // 5% relative error tolerance
        std::cout << (pass2 ? "[PASS]" : "[FAIL - error too large]") << "\n";

        bool ev_check = pass1 && pass2;
        std::cout << "Overall eigenvalue check: " << (ev_check ? "[PASS]" : "[FAIL]") << "\n";
    }

    // Test 9.4.2: Non-symmetric 3x3 matrix
    {
        std::cout << "\n[Test 9.4.2] Non-Symmetric 3x3 Matrix\n";
        std::cout << "Matrix [1,2,3; 4,5,6; 7,8,9]:\n";
        non_sym_mat.print_matrix(true);

        // Expected values for matrix [1,2,3; 4,5,6; 7,8,9]
        // Characteristic equation: λ³ - 15λ² - 18λ = 0
        // Solutions: λ(λ² - 15λ - 18) = 0
        // λ₁ = 0, λ₂,₃ = (15 ± √(225+72))/2 = (15 ± √297)/2 ≈ 16.12, -1.12
        // However, QR algorithm may have numerical errors, especially for non-symmetric matrices
        std::cout << "\n[Expected Results]\n";
        std::cout << "  Expected eigenvalues (theoretical): 16.12, -1.12, 0.00\n";
        std::cout << "  Note: This matrix is rank-deficient (determinant = 0), so one eigenvalue is 0\n";
        std::cout << "  Note: QR algorithm may have numerical errors, especially for non-symmetric matrices\n";
        std::cout << "  Acceptable range: largest eigenvalue ~15-18, smallest eigenvalue near 0\n";

        tiny::Mat::EigenDecomposition result_qr2 = non_sym_mat.eigendecompose_qr(100, 1e-5f);
        std::cout << "\n[Actual Results]\n";
        std::cout << "Eigenvalues:\n";
        result_qr2.eigenvalues.print_matrix(true);
        std::cout << "Eigenvectors:\n";
        result_qr2.eigenvectors.print_matrix(true);
        std::cout << "Iterations: " << result_qr2.iterations << "\n";
        std::cout << "Status: " << (result_qr2.status == TINY_OK ? "OK" : "Error") << "\n";

        // Check results with detailed error reporting
        float expected_evs[3] = {16.12f, -1.12f, 0.0f};
        bool matched[3] = {false, false, false};
        float errors[3] = {0.0f, 0.0f, 0.0f};
        float rel_errors[3] = {0.0f, 0.0f, 0.0f};

        // Match each computed eigenvalue to the closest expected value
        for (int i = 0; i < result_qr2.eigenvalues.row; ++i)
        {
            float ev = result_qr2.eigenvalues(i, 0);
            float min_error = 1e10f;
            int best_match = -1;

            // Find closest expected eigenvalue
            for (int j = 0; j < 3; ++j)
            {
                if (!matched[j])
                {
                    float error = fabsf(ev - expected_evs[j]);
                    if (error < min_error)
                    {
                        min_error = error;
                        best_match = j;
                    }
                }
            }

            if (best_match >= 0)
            {
                matched[best_match] = true;
                errors[best_match] = min_error;
                float expected = expected_evs[best_match];
                rel_errors[best_match] = (fabsf(expected) > 1e-6f) ? (min_error / fabsf(expected)) : min_error;

                std::cout << "Eigenvalue " << i << ": " << ev << " (Expected: " << expected 
                          << ", Error: " << min_error << ", Rel Error: " << (rel_errors[best_match] * 100.0f) << "%) ";

                // For zero eigenvalue, use absolute tolerance; for others, use relative tolerance
                bool pass = (fabsf(expected) < 0.1f) ? (min_error < 0.1f) : (rel_errors[best_match] < 0.15f); // 15% tolerance for QR
                std::cout << (pass ? "[PASS]" : "[FAIL - error too large]") << "\n";
            }
        }

        // Overall check
        bool overall_pass = true;
        for (int i = 0; i < 3; ++i)
        {
            bool pass = (fabsf(expected_evs[i]) < 0.1f) ? (errors[i] < 0.1f) : (rel_errors[i] < 0.15f);
            if (!pass) overall_pass = false;
        }
        std::cout << "Overall eigenvalue check: " << (overall_pass ? "[PASS]" : "[FAIL - some eigenvalues have large errors]") << "\n";
    }

    // Test 9.5: eigendecompose() - Automatic method selection
    std::cout << "\n[Test 9.5] eigendecompose() - Automatic Method Selection\n";

    // Test 9.5.1: Symmetric matrix (should use Jacobi)
    {
        std::cout << "\n[Test 9.5.1] Symmetric Matrix (Auto-select: Jacobi)\n";
        tiny::Mat sym_mat1(3, 3);
        sym_mat1(0, 0) = 4.0f; sym_mat1(0, 1) = 1.0f; sym_mat1(0, 2) = 2.0f;
        sym_mat1(1, 0) = 1.0f; sym_mat1(1, 1) = 3.0f; sym_mat1(1, 2) = 0.0f;
        sym_mat1(2, 0) = 2.0f; sym_mat1(2, 1) = 0.0f; sym_mat1(2, 2) = 5.0f;
        std::cout << "Matrix:\n";
        sym_mat1.print_matrix(true);
        std::cout << "\n[Expected Results]\n";
        std::cout << "  Method: Should automatically use Jacobi (symmetric matrix detected)\n";
        std::cout << "  Expected eigenvalues (approximate): 6.67, 3.48, 1.85\n";
        std::cout << "  Note: Eigenvalues may appear in any order\n";

        tiny::Mat::EigenDecomposition result_auto1 = sym_mat1.eigendecompose(1e-5f);
        std::cout << "\n[Actual Results]\n";
        std::cout << "Eigenvalues:\n";
        result_auto1.eigenvalues.print_matrix(true);
        std::cout << "Iterations: " << result_auto1.iterations << "\n";
        std::cout << "Status: " << (result_auto1.status == TINY_OK ? "OK" : "Error") << "\n";
        std::cout << "Method used: Jacobi (auto-selected for symmetric matrix)\n";
    }

    // Test 9.5.2: Non-symmetric matrix (should use QR)
    {
        std::cout << "\n[Test 9.5.2] Non-Symmetric Matrix (Auto-select: QR)\n";
        std::cout << "[Expected Results]\n";
        std::cout << "  Method: Should automatically use QR (non-symmetric matrix detected)\n";
        std::cout << "  Expected eigenvalues (theoretical): 16.12, -1.12, 0.00\n";
        std::cout << "  Note: One eigenvalue should be near 0 (rank-deficient matrix)\n";
        std::cout << "  Note: QR algorithm may have numerical errors for non-symmetric matrices\n";
        std::cout << "  Acceptable: largest ~15-18, smallest near 0, one near -1 to -3\n";

        tiny::Mat::EigenDecomposition result_auto2 = non_sym_mat.eigendecompose(1e-5f);
        std::cout << "\n[Actual Results]\n";
        std::cout << "Eigenvalues:\n";
        result_auto2.eigenvalues.print_matrix(true);
        std::cout << "Iterations: " << result_auto2.iterations << "\n";
        std::cout << "Status: " << (result_auto2.status == TINY_OK ? "OK" : "Error") << "\n";
        std::cout << "Method used: QR (auto-selected for non-symmetric matrix)\n";

        // Check results with detailed error reporting (same as Test 4.2)
        float expected_evs[3] = {16.12f, -1.12f, 0.0f};
        bool matched[3] = {false, false, false};
        float errors[3] = {0.0f, 0.0f, 0.0f};
        float rel_errors[3] = {0.0f, 0.0f, 0.0f};

        for (int i = 0; i < result_auto2.eigenvalues.row; ++i)
        {
            float ev = result_auto2.eigenvalues(i, 0);
            float min_error = 1e10f;
            int best_match = -1;

            for (int j = 0; j < 3; ++j)
            {
                if (!matched[j])
                {
                    float error = fabsf(ev - expected_evs[j]);
                    if (error < min_error)
                    {
                        min_error = error;
                        best_match = j;
                    }
                }
            }

            if (best_match >= 0)
            {
                matched[best_match] = true;
                errors[best_match] = min_error;
                float expected = expected_evs[best_match];
                rel_errors[best_match] = (fabsf(expected) > 1e-6f) ? (min_error / fabsf(expected)) : min_error;

                std::cout << "Eigenvalue " << i << ": " << ev << " (Expected: " << expected 
                          << ", Error: " << min_error << ", Rel Error: " << (rel_errors[best_match] * 100.0f) << "%) ";

                bool pass = (fabsf(expected) < 0.1f) ? (min_error < 0.1f) : (rel_errors[best_match] < 0.15f);
                std::cout << (pass ? "[PASS]" : "[FAIL - error too large]") << "\n";
            }
        }

        bool overall_pass = true;
        for (int i = 0; i < 3; ++i)
        {
            bool pass = (fabsf(expected_evs[i]) < 0.1f) ? (errors[i] < 0.1f) : (rel_errors[i] < 0.15f);
            if (!pass) overall_pass = false;
        }
        std::cout << "Overall eigenvalue check: " << (overall_pass ? "[PASS]" : "[FAIL - some eigenvalues have large errors]") << "\n";
    }

    // Test 9.6: SHM Application Scenario - Structural Dynamics
    std::cout << "\n[Test 9.6] SHM Application - Structural Dynamics Analysis\n";

    // Create a simple 4-DOF structural system (mass-spring system)
    {
        std::cout << "\n[Test 9.6.1] 4-DOF Mass-Spring System\n";
        tiny::Mat K(4, 4);  // Stiffness matrix
        K(0, 0) = 2.0f; K(0, 1) = -1.0f; K(0, 2) = 0.0f; K(0, 3) = 0.0f;
        K(1, 0) = -1.0f; K(1, 1) = 2.0f; K(1, 2) = -1.0f; K(1, 3) = 0.0f;
        K(2, 0) = 0.0f; K(2, 1) = -1.0f; K(2, 2) = 2.0f; K(2, 3) = -1.0f;
        K(3, 0) = 0.0f; K(3, 1) = 0.0f; K(3, 2) = -1.0f; K(3, 3) = 1.0f;

        std::cout << "Stiffness Matrix K:\n";
        K.print_matrix(true);
        std::cout << "Is symmetric: " << (K.is_symmetric(1e-6f) ? "Yes" : "No") << "\n";

        // Quick frequency identification using power iteration
        std::cout << "\n[Quick Analysis] Primary frequency using power_iteration():\n";
        std::cout << "[Expected Results]\n";
        std::cout << "  Expected primary eigenvalue: ~3.53 (largest eigenvalue)\n";
        std::cout << "  Expected primary frequency: sqrt(3.53) ≈ 1.88 rad/s\n";

        tiny::Mat::EigenPair primary = K.power_iteration(500, 1e-6f);
        std::cout << "\n[Actual Results]\n";
        std::cout << "  Primary eigenvalue: " << primary.eigenvalue << " (Expected: ~3.53)\n";
        std::cout << "  Primary frequency: " << sqrtf(primary.eigenvalue) << " rad/s (Expected: ~1.88 rad/s)\n";
        std::cout << "  Iterations: " << primary.iterations << "\n";
        float error_primary = fabsf(primary.eigenvalue - 3.53f);
        std::cout << "  Error from expected: " << error_primary << (error_primary < 0.2f ? " [PASS]" : " [FAIL]") << "\n";

        // Complete modal analysis using Jacobi
        std::cout << "\n[Complete Analysis] Full modal analysis using eigendecompose_jacobi():\n";
        std::cout << "[Expected Results]\n";
        std::cout << "  Expected eigenvalues (approximate): 3.53, 2.35, 1.00, 0.12\n";
        std::cout << "  Expected natural frequencies: 1.88, 1.53, 1.00, 0.35 rad/s\n";
        std::cout << "  Note: These are approximate values for the 4-DOF system\n";

        tiny::Mat::EigenDecomposition modal = K.eigendecompose_jacobi(1e-5f, 100);
        std::cout << "\n[Actual Results]\n";
        std::cout << "All eigenvalues (natural frequencies squared):\n";
        modal.eigenvalues.print_matrix(true);
        std::cout << "Natural frequencies (rad/s):\n";
        float expected_freqs_4dof[4] = {1.88f, 1.53f, 1.00f, 0.35f};
        for (int i = 0; i < modal.eigenvalues.row; ++i)
        {
            float freq = sqrtf(modal.eigenvalues(i, 0));
            std::cout << "  Mode " << i << ": " << freq << " rad/s";
            // Check if frequency matches any expected value
            bool matched = false;
            for (int j = 0; j < 4; ++j)
            {
                if (fabsf(freq - expected_freqs_4dof[j]) < 0.15f)
                {
                    std::cout << " (Expected: ~" << expected_freqs_4dof[j] << " rad/s) [PASS]";
                    matched = true;
                    break;
                }
            }
            if (!matched) std::cout << " [CHECK]";
            std::cout << "\n";
        }
        std::cout << "Mode shapes (eigenvectors):\n";
        modal.eigenvectors.print_matrix(true);
        std::cout << "Total iterations: " << modal.iterations << "\n";
    }

    // Test 9.7: Edge Cases and Error Handling
    std::cout << "\n[Test 9.7] Edge Cases and Error Handling\n";

    // Test 9.7.1: 1x1 matrix
    {
        std::cout << "\n[Test 9.7.1] 1x1 Matrix\n";
        tiny::Mat mat1x1(1, 1);
        mat1x1(0, 0) = 5.0f;
        std::cout << "Matrix: [5.0]\n";
        std::cout << "[Expected Results]\n";
        std::cout << "  Expected eigenvalue: 5.0 (the matrix element itself)\n";
        std::cout << "  Expected eigenvector: [1.0] (normalized)\n";

        tiny::Mat::EigenDecomposition result_1x1 = mat1x1.eigendecompose(1e-6f);
        std::cout << "\n[Actual Results]\n";
        std::cout << "Eigenvalue: " << result_1x1.eigenvalues(0, 0) << " (Expected: 5.0)\n";
        std::cout << "Eigenvector:\n";
        result_1x1.eigenvectors.print_matrix(true);
        float error = fabsf(result_1x1.eigenvalues(0, 0) - 5.0f);
        std::cout << "Error from expected: " << error << (error < 0.01f ? " [PASS]" : " [FAIL]") << "\n";
    }

    // Test 9.7.2: Zero matrix
    {
        std::cout << "\n[Test 9.7.2] Zero Matrix\n";
        tiny::Mat zero_mat(3, 3);
        zero_mat.clear();
        tiny::Mat::EigenPair result_zero = zero_mat.power_iteration(100, 1e-6f);
        std::cout << "Status: " << (result_zero.status == TINY_OK ? "OK" : "Error (Expected)") << "\n";
    }

    // Test 9.7.3: Identity matrix
    {
        std::cout << "\n[Test 9.7.3] Identity Matrix\n";
        tiny::Mat I = tiny::Mat::eye(3);
        std::cout << "Matrix (3x3 Identity):\n";
        I.print_matrix(true);
        std::cout << "\n[Expected Results]\n";
        std::cout << "  Expected eigenvalues: 1.0, 1.0, 1.0 (all eigenvalues are 1)\n";
        std::cout << "  Expected eigenvectors: Any orthonormal basis (e.g., standard basis vectors)\n";
        std::cout << "  Expected iterations: 1 (should converge immediately)\n";

        tiny::Mat::EigenDecomposition result_I = I.eigendecompose_jacobi(1e-6f, 10);
        std::cout << "\n[Actual Results]\n";
        std::cout << "Eigenvalues (should all be 1.0):\n";
        result_I.eigenvalues.print_matrix(true);
        std::cout << "Eigenvectors:\n";
        result_I.eigenvectors.print_matrix(true);
        std::cout << "Iterations: " << result_I.iterations << " (Expected: 1)\n";

        // Check all eigenvalues are 1.0
        bool all_one = true;
        for (int i = 0; i < result_I.eigenvalues.row; ++i)
        {
            if (fabsf(result_I.eigenvalues(i, 0) - 1.0f) > 0.01f)
            {
                all_one = false;
                break;
            }
        }
        std::cout << "All eigenvalues = 1.0: " << (all_one ? "[PASS]" : "[FAIL]") << "\n";
    }

    // Test 9.8: Performance Test for SHM Applications
    std::cout << "\n[Test 9.8] Performance Test for SHM Applications\n";

    // Test 9.8.1: Power iteration performance (fast method for dominant eigenvalue)
    std::cout << "\n[Test 9.8.1] Power Iteration Performance (Real-time SHM - Dominant Eigenvalue)\n";
    TIME_OPERATION(
        tiny::Mat::EigenPair perf_result = stiffness.power_iteration(500, 1e-6f);
        (void)perf_result;
    , "Power Iteration (3x3 matrix)");

    // Test 9.8.2: Inverse power iteration performance (system identification - smallest eigenvalue)
    std::cout << "\n[Test 9.8.2] Inverse Power Iteration Performance (System Identification - Smallest Eigenvalue)\n";
    TIME_OPERATION(
        tiny::Mat::EigenPair perf_inv_result = stiffness.inverse_power_iteration(500, 1e-6f);
        (void)perf_inv_result;
    , "Inverse Power Iteration (3x3 matrix)");

    // Test 9.8.3: Jacobi method performance (complete eigendecomposition for symmetric matrices)
    std::cout << "\n[Test 9.8.3] Jacobi Method Performance (Complete Eigendecomposition - Symmetric Matrices)\n";
    TIME_OPERATION(
        tiny::Mat::EigenDecomposition perf_jacobi = stiffness.eigendecompose_jacobi(1e-5f, 100);
        (void)perf_jacobi;
    , "Jacobi Decomposition (3x3 symmetric matrix)");

    // Test 9.8.4: QR method performance (complete eigendecomposition for general matrices)
    std::cout << "\n[Test 9.8.4] QR Method Performance (Complete Eigendecomposition - General Matrices)\n";
    TIME_OPERATION(
        tiny::Mat::EigenDecomposition perf_qr = non_sym_mat.eigendecompose_qr(100, 1e-5f);
        (void)perf_qr;
    , "QR Decomposition (3x3 general matrix)");

    std::cout << "\n[Eigenvalue Decomposition Tests Complete]\n";
}

void tiny_matrix_test()
{
    std::cout << "============ [tiny_matrix_test start] ============\n";
    std::cout << "\n[Test Organization: Application-Oriented Logic]\n";
    std::cout << "  Foundation → Basic Ops → Properties → Linear Systems → Decompositions → Applications → Quality\n\n";

    // ========================================================================
    // Phase 1: Object Foundation (Groups 1-3)
    // ========================================================================
    // Purpose: Learn to create and manipulate matrix objects
    // Group 1: Constructor & Destructor
    test_constructor_destructor();

    // Group 2: Element Access
    test_element_access();

    // Group 3: ROI Operations
    test_roi_operations();

    // ========================================================================
    // Phase 2: Basic Operations (Group 4)
    // ========================================================================
    // Purpose: Learn basic arithmetic operations
    // Group 4: Arithmetic Operators
    test_assignment_operator();
    test_matrix_addition();
    test_constant_addition();
    test_matrix_subtraction();
    test_constant_subtraction();
    test_matrix_division();
    test_constant_division();
    test_matrix_exponentiation();

    // ========================================================================
    // Phase 3: Matrix Properties (Group 5)
    // ========================================================================
    // Purpose: Understand matrix properties and basic linear algebra
    // Group 5: Matrix Properties
    test_matrix_transpose();
    test_matrix_cofactor();
    test_matrix_determinant();
    test_matrix_adjoint();
    test_matrix_normalize();
    test_matrix_norm();
    test_inverse_adjoint_adjoint();
    test_matrix_utilities();

    // ========================================================================
    // Phase 4: Linear System Solving (Group 6)
    // ========================================================================
    // Purpose: Core application - solving linear systems Ax = b
    // Group 6: Linear System Solving
    test_gaussian_eliminate();
    test_row_reduce_from_gaussian();
    test_inverse_gje();
    test_dotprod();
    test_solve();
    test_band_solve();
    test_roots();

    // ========================================================================
    // Phase 5: Advanced Linear Algebra (Groups 7-8)
    // ========================================================================
    // Purpose: Advanced linear algebra operations for stable and efficient solving
    // Group 7: Matrix Decomposition
    test_matrix_decomposition();

    // Group 8: Gram-Schmidt Orthogonalization
    test_gram_schmidt_orthogonalize();

    // ========================================================================
    // Phase 6: System Identification Applications (Group 9)
    // ========================================================================
    // Purpose: Eigenvalue decomposition for SHM and modal analysis
    // Group 9: Eigenvalue Decomposition
    test_eigenvalue_decomposition();

    // ========================================================================
    // Phase 7: Auxiliary Functions (Groups 10-11)
    // ========================================================================
    // Purpose: Convenience functions and I/O operations
    // Group 10: Stream Operators
    test_stream_operators();

    // Group 11: Global Arithmetic Operators
    test_matrix_operations();

    // ========================================================================
    // Phase 8: Quality Assurance (Groups 12-14)
    // ========================================================================
    // Purpose: Ensure robustness, performance, and correctness
    // Group 12: Boundary Conditions and Error Handling
    test_boundary_conditions();

    // Group 13: Performance Benchmarks
    test_performance_benchmarks();

    // Group 14: Memory Layout
    test_memory_layout();

    std::cout << "============ [tiny_matrix_test end] ============\n";

    // Remove current task from watchdog after all tests complete
    // This prevents watchdog timeout after app_main() returns
#if MCU_PLATFORM_SELECTED == MCU_PLATFORM_ESP32
    if (task_wdt_added)
    {
        esp_task_wdt_delete(NULL);  // Remove current task from watchdog
        task_wdt_added = false;
    }
#endif
}

结果输出

PHASE I: 对象基础 (组 1-3)

目的:学习创建和操作矩阵对象

============ [tiny_matrix_test start] ============

[Test Organization: Application-Oriented Logic]
  Foundation → Basic Ops → Properties → Linear Systems → Decompositions → Applications → Quality


[Group 1: Object Foundation - Constructor & Destructor Tests]
[Test 1.1] Default Constructor
Matrix Info >>>
rows            1
cols            1
elements        1
paddings        0
stride          1
memory          1
data pointer    0x3fce9a78
temp pointer    0
ext_buff        0
sub_matrix      0
<<< Matrix Info
Matrix Elements >>>
           0       |
<<< Matrix Elements

[Test 1.2] Constructor with Rows and Cols
Matrix Info >>>
rows            3
cols            4
elements        12
paddings        0
stride          4
memory          12
data pointer    0x3fce9a9c
temp pointer    0
ext_buff        0
sub_matrix      0
<<< Matrix Info
Matrix Elements >>>
           0            0            0            0       |
           0            0            0            0       |
           0            0            0            0       |
<<< Matrix Elements

[Test 1.3] Constructor with Rows, Cols and Stride
Matrix Info >>>
rows            3
cols            4
elements        12
paddings        1
stride          5
memory          15
data pointer    0x3fce9ad0
temp pointer    0
ext_buff        0
sub_matrix      0
<<< Matrix Info
Matrix Elements >>>
           0            0            0            0       |      0 
           0            0            0            0       |      0 
           0            0            0            0       |      0 
<<< Matrix Elements

[Test 1.4] Constructor with External Data
Matrix Info >>>
rows            3
cols            4
elements        12
paddings        0
stride          4
memory          12
data pointer    0x3fc9928c
temp pointer    0
ext_buff        1   (External buffer or View)
sub_matrix      0
<<< Matrix Info
Matrix Elements >>>
           0            1            2            3       |
           4            5            6            7       |
           8            9           10           11       |
<<< Matrix Elements

[Test 1.5] Constructor with External Data and Stride
Matrix Info >>>
rows            3
cols            4
elements        12
paddings        1
stride          5
memory          15
data pointer    0x3fc992e0
temp pointer    0
ext_buff        1   (External buffer or View)
sub_matrix      0
<<< Matrix Info
Matrix Elements >>>
           0            1            2            3       |      0 
           4            5            6            7       |      0 
           8            9           10           11       |      0 
<<< Matrix Elements

[Test 1.6] Copy Constructor
Matrix Info >>>
rows            3
cols            4
elements        12
paddings        1
stride          5
memory          15
data pointer    0x3fce9bd8
temp pointer    0
ext_buff        0
sub_matrix      0
<<< Matrix Info
Matrix Elements >>>
           0            1            2            3       |      0 
           4            5            6            7       |      0 
           8            9           10           11       |      0 
<<< Matrix Elements


[Group 2: Object Foundation - Element Access Tests]
[Test 2.1] Non-const Access
Matrix Info >>>
rows            2
cols            3
elements        6
paddings        0
stride          3
memory          6
data pointer    0x3fce9a9c
temp pointer    0
ext_buff        0
sub_matrix      0
<<< Matrix Info
Matrix Elements >>>
         1.1          2.2          3.3       |
         4.4          5.5          6.6       |
<<< Matrix Elements

[Test 2.2] Const Access
const_mat(0, 0): 1.1

[Group 3: Object Foundation - Data Manipulation Tests (ROI Operations)]
[Material Matrices]
matA:
Matrix Info >>>
rows            2
cols            3
elements        6
paddings        0
stride          3
memory          6
data pointer    0x3fce9a9c
temp pointer    0
ext_buff        0
sub_matrix      0
<<< Matrix Info
Matrix Elements >>>
         0.1          0.2          0.3       |
         0.4          0.5          0.6       |
<<< Matrix Elements

matB:
Matrix Info >>>
rows            3
cols            4
elements        12
paddings        1
stride          5
memory          15
data pointer    0x3fc991c4
temp pointer    0
ext_buff        1   (External buffer or View)
sub_matrix      0
<<< Matrix Info
Matrix Elements >>>
           0            1            2            3       |      0 
           4            5            6            7       |      0 
           8            9           10           11       |      0 
<<< Matrix Elements

matC:
Matrix Info >>>
rows            1
cols            1
elements        1
paddings        0
stride          1
memory          1
data pointer    0x3fce9a78
temp pointer    0
ext_buff        0
sub_matrix      0
<<< Matrix Info
Matrix Elements >>>
           0       |
<<< Matrix Elements

[Test 3.1] Copy ROI - Over Range Case
[>>> Error ! <<<] Invalid column position 
matB after copy_paste matA at (1, 2):
Matrix Elements >>>
           0            1            2            3       |      0 
           4            5            6            7       |      0 
           8            9           10           11       |      0 
<<< Matrix Elements

nothing changed.
[Test 3.1] Copy ROI - Suitable Range Case
matB after copy_paste matA at (1, 1):
Matrix Info >>>
rows            3
cols            4
elements        12
paddings        1
stride          5
memory          15
data pointer    0x3fc991c4
temp pointer    0
ext_buff        1   (External buffer or View)
sub_matrix      0
<<< Matrix Info
Matrix Elements >>>
           0            1            2            3       |      0 
           4          0.1          0.2          0.3       |      0 
           8          0.4          0.5          0.6       |      0 
<<< Matrix Elements

successfully copied.
[Test 3.2] Copy Head
matC after copy_head matB:
Matrix Info >>>
rows            3
cols            4
elements        12
paddings        1
stride          5
memory          15
data pointer    0x3fc991c4
temp pointer    0
ext_buff        1   (External buffer or View)
sub_matrix      0
<<< Matrix Info
Matrix Elements >>>
           0            1            2            3       |      0 
           4          0.1          0.2          0.3       |      0 
           8          0.4          0.5          0.6       |      0 
<<< Matrix Elements

[Test 3.2] Copy Head - Memory Sharing Check
matB(0, 0) = 99.99f
matC:
Matrix Info >>>
rows            3
cols            4
elements        12
paddings        1
stride          5
memory          15
data pointer    0x3fc991c4
temp pointer    0
ext_buff        1   (External buffer or View)
sub_matrix      0
<<< Matrix Info
Matrix Elements >>>
       99.99            1            2            3       |      0 
           4          0.1          0.2          0.3       |      0 
           8          0.4          0.5          0.6       |      0 
<<< Matrix Elements

[Test 3.3] Get a View of ROI - Low Level Function
get a view of ROI with overrange dimensions - rows:
[Error] Invalid ROI request.
get a view of ROI with overrange dimensions - cols:
[Error] Invalid ROI request.
get a view of ROI with suitable dimensions:
roi3:
Matrix Info >>>
rows            2
cols            2
elements        4
paddings        3
stride          5
memory          10
data pointer    0x3fc991dc
temp pointer    0
ext_buff        1   (External buffer or View)
sub_matrix      1   (This is a Sub-Matrix View)
<<< Matrix Info
Matrix Elements >>>
         0.1          0.2       |    0.3            0            8 
         0.4          0.5       |    0.6            0   4.2039e-45 
<<< Matrix Elements

[Test 3.4] Get a View of ROI - Using ROI Structure
Matrix Info >>>
rows            2
cols            2
elements        4
paddings        3
stride          5
memory          10
data pointer    0x3fc991dc
temp pointer    0
ext_buff        1   (External buffer or View)
sub_matrix      1   (This is a Sub-Matrix View)
<<< Matrix Info
Matrix Elements >>>
         0.1          0.2       |    0.3            0            8 
         0.4          0.5       |    0.6            0   4.2039e-45 
<<< Matrix Elements

[Test 3.5] Copy ROI - Low Level Function
Matrix Info >>>
rows            2
cols            2
elements        4
paddings        0
stride          2
memory          4
data pointer    0x3fce9bfc
temp pointer    0
ext_buff        0
sub_matrix      0
<<< Matrix Info
Matrix Elements >>>
         0.1          0.2       |
         0.4          0.5       |
<<< Matrix Elements

[Test 3.6] Copy ROI - Using ROI Structure
time for copy_roi using ROI structure: 28 ms
Matrix Info >>>
rows            2
cols            2
elements        4
paddings        0
stride          2
memory          4
data pointer    0x3fce9c10
temp pointer    0
ext_buff        0
sub_matrix      0
<<< Matrix Info
Matrix Elements >>>
         0.1          0.2       |
         0.4          0.5       |
<<< Matrix Elements

[Test 3.7] Block
time for block: 34 ms
Matrix Info >>>
rows            2
cols            2
elements        4
paddings        0
stride          2
memory          4
data pointer    0x3fce9c24
temp pointer    0
ext_buff        0
sub_matrix      0
<<< Matrix Info
Matrix Elements >>>
         0.1          0.2       |
         0.4          0.5       |
<<< Matrix Elements

[Test 3.8] Swap Rows
matB before swap rows:
Matrix Info >>>
rows            3
cols            4
elements        12
paddings        1
stride          5
memory          15
data pointer    0x3fc991c4
temp pointer    0
ext_buff        1   (External buffer or View)
sub_matrix      0
<<< Matrix Info
Matrix Elements >>>
       99.99            1            2            3       |      0 
           4          0.1          0.2          0.3       |      0 
           8          0.4          0.5          0.6       |      0 
<<< Matrix Elements

matB after swap_rows(0, 2):
Matrix Info >>>
rows            3
cols            4
elements        12
paddings        1
stride          5
memory          15
data pointer    0x3fc991c4
temp pointer    0
ext_buff        1   (External buffer or View)
sub_matrix      0
<<< Matrix Info
Matrix Elements >>>
           8          0.4          0.5          0.6       |      0 
           4          0.1          0.2          0.3       |      0 
       99.99            1            2            3       |      0 
<<< Matrix Elements

[Test 3.9] Swap Columns
matB before swap columns:
Matrix Info >>>
rows            3
cols            4
elements        12
paddings        1
stride          5
memory          15
data pointer    0x3fc991c4
temp pointer    0
ext_buff        1   (External buffer or View)
sub_matrix      0
<<< Matrix Info
Matrix Elements >>>
           8          0.4          0.5          0.6       |      0 
           4          0.1          0.2          0.3       |      0 
       99.99            1            2            3       |      0 
<<< Matrix Elements

matB after swap_cols(0, 2):
Matrix Info >>>
rows            3
cols            4
elements        12
paddings        1
stride          5
memory          15
data pointer    0x3fc991c4
temp pointer    0
ext_buff        1   (External buffer or View)
sub_matrix      0
<<< Matrix Info
Matrix Elements >>>
         0.5          0.4            8          0.6       |      0 
         0.2          0.1            4          0.3       |      0 
           2            1        99.99            3       |      0 
<<< Matrix Elements

[Test 3.10] Clear
matB before clear:
Matrix Info >>>
rows            3
cols            4
elements        12
paddings        1
stride          5
memory          15
data pointer    0x3fc991c4
temp pointer    0
ext_buff        1   (External buffer or View)
sub_matrix      0
<<< Matrix Info
Matrix Elements >>>
         0.5          0.4            8          0.6       |      0 
         0.2          0.1            4          0.3       |      0 
           2            1        99.99            3       |      0 
<<< Matrix Elements

matB after clear:
Matrix Info >>>
rows            3
cols            4
elements        12
paddings        1
stride          5
memory          15
data pointer    0x3fc991c4
temp pointer    0
ext_buff        1   (External buffer or View)
sub_matrix      0
<<< Matrix Info
Matrix Elements >>>
           0            0            0            0       |      0 
           0            0            0            0       |      0 
           0            0            0            0       |      0 
<<< Matrix Elements

============ [tiny_matrix_test end] ============

PHASE II: 基本运算 (组 4)

目的:学习基本算术运算

============ [tiny_matrix_test start] ============

[Test Organization: Application-Oriented Logic]
  Foundation → Basic Ops → Properties → Linear Systems → Decompositions → Applications → Quality


[Group 4.1: Basic Operations - Assignment Operator Tests]

[Test 4.1.1] Assignment (Same Dimensions)
Matrix Elements >>>
           1            2            3       |
           4            5            6       |
<<< Matrix Elements


[Test 4.1.2] Assignment (Different Dimensions)
Matrix Elements >>>
           1            2            3       |
           4            5            6       |
<<< Matrix Elements


[Test 4.1.3] Assignment to Sub-Matrix (Expect Error)
[Error] Assignment to a sub-matrix is not allowed.
Matrix Elements >>>
           5            6       |      7            0            8 
           9           10       |     11            0   4.2039e-45 
<<< Matrix Elements


[Test 4.1.4] Self-Assignment
Matrix Elements >>>
           1            2            3       |
           4            5            6       |
<<< Matrix Elements


[Group 4.2: Matrix Addition Tests]

[Test 4.2.1] Matrix Addition (Same Dimensions)
Matrix Elements >>>
           2            3            4       |
           5            6            7       |
<<< Matrix Elements


[Test 4.2.2] Sub-Matrix Addition
Matrix Elements >>>
          10           12       |      7            0            8 
          18           20       |     11            0           12 
<<< Matrix Elements


[Test 4.2.3] Full Matrix + Sub-Matrix Addition
Matrix Elements >>>
          12           14       |
          20           22       |
<<< Matrix Elements


[Test 4.2.4] Addition Dimension Mismatch (Expect Error)
[Error] Matrix addition failed: Dimension mismatch (2x2 vs 3x3)

[Group 4.3: Constant Addition Tests]

[Test 4.3.1] Full Matrix + Constant
Matrix Elements >>>
           5            6            7       |
           8            9           10       |
<<< Matrix Elements


[Test 4.3.2] Sub-Matrix + Constant
Matrix Elements >>>
           8            9       |      7            0            8 
          12           13       |     11            0           12 
<<< Matrix Elements


[Test 4.3.3] Add Zero
Matrix Elements >>>
           1            2       |
           3            4       |
<<< Matrix Elements


[Test 4.3.4] Add Negative Constant
Matrix Elements >>>
          -5            5       |
          15           25       |
<<< Matrix Elements


[Group 4.4: Matrix Subtraction Tests]

[Test 4.4.1] Matrix Subtraction
Matrix Elements >>>
           4            5       |
           6            7       |
<<< Matrix Elements


[Test 4.4.2] Subtraction Dimension Mismatch (Expect Error)
[Error] Matrix subtraction failed: Dimension mismatch (2x2 vs 3x3)

[Group 4.5: Constant Subtraction Tests]

[Test 4.5.1] Full Matrix - Constant
Matrix Elements >>>
          -1            0            1       |
           2            3            4       |
<<< Matrix Elements


[Test 4.5.2] Sub-Matrix - Constant
Matrix Elements >>>
         3.5          4.5       |      7            0            8 
         7.5          8.5       |     11            0   4.2039e-45 
<<< Matrix Elements


[Group 4.6: Matrix Element-wise Division Tests]

[Test 4.6.1] Element-wise Division (Same Dimensions, No Zero)
Matrix Elements >>>
           5            5       |
           6            5       |
<<< Matrix Elements


[Test 4.6.2] Dimension Mismatch (Expect Error)
[Error] Matrix division failed: Dimension mismatch (2x2 vs 3x3)

[Test 4.6.3] Division by Matrix Containing Zero (Expect Error)
[Error] Matrix division failed: Division by zero detected.
Matrix Elements >>>
           5           10       |
          15           20       |
<<< Matrix Elements


[Group 4.7: Matrix Division by Constant Tests]

[Test 4.7.1] Divide Full Matrix by Positive Constant
Matrix Elements >>>
           1          1.5            2       |
         2.5            3          3.5       |
<<< Matrix Elements


[Test 4.7.2] Divide Matrix by Negative Constant
Matrix Elements >>>
          -2           -4       |
          -6           -8       |
<<< Matrix Elements


[Test 4.7.3] Division by Zero Constant (Expect Error)
[Error] Matrix division by zero is undefined.
Matrix Elements >>>
           1            2       |
           3            4       |
<<< Matrix Elements


[Group 4.8: Matrix Exponentiation Tests]

[Test 4.8.1] Raise Each Element to Power of 2
Matrix Elements >>>
           4            9       |
          16           25       |
<<< Matrix Elements


[Test 4.8.2] Raise Each Element to Power of 0
Matrix Elements >>>
           1            1       |
           1            1       |
<<< Matrix Elements


[Test 4.8.3] Raise Each Element to Power of 1
Matrix Elements >>>
           9            8       |
           7            6       |
<<< Matrix Elements


[Test 4.8.4] Raise Each Element to Power of -1 (Expect Error or Warning)
[Error] Negative exponent not supported in operator^.
Matrix Elements >>>
           1            2       |
           4            5       |
<<< Matrix Elements


[Test 4.8.5] Raise Matrix Containing Zero to Power of 3
Matrix Elements >>>
           0            8       |
          -1           27       |
<<< Matrix Elements

============ [tiny_matrix_test end] ============

PHASE III: 矩阵属性 (组 5)

目的:理解矩阵属性和基本线性代数

============ [tiny_matrix_test start] ============

[Test Organization: Application-Oriented Logic]
  Foundation → Basic Ops → Properties → Linear Systems → Decompositions → Applications → Quality


[Group 5.1: Matrix Properties - Matrix Transpose Tests]

[Test 5.1.1] Transpose of 2x3 Matrix
Original 2x3 Matrix:
Matrix Elements >>>
           1            2            3       |
           4            5            6       |
<<< Matrix Elements

Transposed 3x2 Matrix:
Matrix Elements >>>
           1            4       |
           2            5       |
           3            6       |
<<< Matrix Elements


[Test 5.1.2] Transpose of 3x3 Square Matrix
Original 3x3 Matrix:
Matrix Elements >>>
           1            2            3       |
           4            5            6       |
           7            8            9       |
<<< Matrix Elements

Transposed 3x3 Matrix:
Matrix Elements >>>
           1            4            7       |
           2            5            8       |
           3            6            9       |
<<< Matrix Elements


[Test 5.1.3] Transpose of Matrix with Padding
Original 4x2 Matrix (with padding):
Matrix Elements >>>
           1            2       |      0 
           3            4       |      0 
           5            6       |      0 
           7            8       |      0 
<<< Matrix Elements

Transposed 2x4 Matrix:
Matrix Elements >>>
           1            3            5            7       |
           2            4            6            8       |
<<< Matrix Elements


[Test 5.1.4] Transpose of Empty Matrix
Matrix Elements >>>
           0       |
<<< Matrix Elements

Matrix Elements >>>
           0       |
<<< Matrix Elements


[Group 5.2: Matrix Minor and Cofactor Tests]

[Test 5.2.1] Minor of 3x3 Matrix (Remove Row 1, Col 1)
Original 3x3 Matrix:
Matrix Elements >>>
           1            2            3       |
           4            5            6       |
           7            8            9       |
<<< Matrix Elements

Minor Matrix (remove row 1, col 1, no sign):
Matrix Elements >>>
           1            3       |
           7            9       |
<<< Matrix Elements


[Test 5.2.2] Cofactor of 3x3 Matrix (Remove Row 1, Col 1)
Note: Cofactor matrix is the same as minor matrix.
      The sign (-1)^(i+j) is applied when computing cofactor value, not to matrix elements.
Cofactor Matrix (same as minor):
Matrix Elements >>>
           1            3       |
           7            9       |
<<< Matrix Elements


[Test 5.2.3] Minor (Remove Row 0, Col 0)
Matrix Elements >>>
           5            6       |
           8            9       |
<<< Matrix Elements


[Test 5.2.4] Cofactor (Remove Row 0, Col 0)
Note: Cofactor matrix is the same as minor matrix.
Matrix Elements >>>
           5            6       |
           8            9       |
<<< Matrix Elements


[Test 5.2.5] Cofactor (Remove Row 0, Col 1)
Note: Cofactor matrix is the same as minor matrix.
      When computing cofactor value, sign (-1)^(0+1) = -1 would be applied.
Cofactor Matrix (same as minor):
Matrix Elements >>>
           4            6       |
           7            9       |
<<< Matrix Elements


[Test 5.2.6] Minor (Remove Row 2, Col 2)
Matrix Elements >>>
           1            2       |
           4            5       |
<<< Matrix Elements


[Test 5.2.7] Cofactor (Remove Row 2, Col 2)
Note: Cofactor matrix is the same as minor matrix.
Matrix Elements >>>
           1            2       |
           4            5       |
<<< Matrix Elements


[Test 5.2.8] Minor of 4x4 Matrix (Remove Row 2, Col 1)
Matrix Elements >>>
           1            2            3            4       |
           5            6            7            8       |
           9           10           11           12       |
          13           14           15           16       |
<<< Matrix Elements

Minor Matrix:
Matrix Elements >>>
           1            3            4       |
           5            7            8       |
          13           15           16       |
<<< Matrix Elements


[Test 5.2.9] Cofactor of 4x4 Matrix (Remove Row 2, Col 1)
Note: Cofactor matrix is the same as minor matrix.
      When computing cofactor value, sign (-1)^(2+1) = -1 would be applied.
Cofactor Matrix (same as minor):
Matrix Elements >>>
           1            3            4       |
           5            7            8       |
          13           15           16       |
<<< Matrix Elements


[Test 5.2.10] Non-square Matrix (Expect Error)
Testing minor():
[Error] Minor requires square matrix.
Matrix Elements >>>
           0       |
<<< Matrix Elements

Testing cofactor():
[Error] Minor requires square matrix.
Matrix Elements >>>
           0       |
<<< Matrix Elements


[Group 5.3: Matrix Determinant Tests]

[Test 5.3.1] 1x1 Matrix Determinant
Matrix:
Matrix Elements >>>
           7       |
<<< Matrix Elements

Determinant: 7  (Expected: 7)

[Test 5.3.2] 2x2 Matrix Determinant
Matrix:
Matrix Elements >>>
           3            8       |
           4            6       |
<<< Matrix Elements

Determinant: -14  (Expected: -14)

[Test 5.3.3] 3x3 Matrix Determinant
Matrix:
Matrix Elements >>>
           1            2            3       |
           0            4            5       |
           1            0            6       |
<<< Matrix Elements

Determinant: 22  (Expected: 22)

[Test 5.3.4] 4x4 Matrix Determinant
Matrix:
Matrix Elements >>>
           1            2            3            4       |
           5            6            7            8       |
           9           10           11           12       |
          13           14           15           16       |
<<< Matrix Elements

Note: This matrix has linearly dependent rows (each row differs by constant 4),
      so the determinant should be 0.
Determinant: 0  (Expected: 0)

[Test 5.3.5] 5x5 Matrix Determinant (Tests Auto-select to LU Method)
Matrix (5x5, tridiagonal):
Matrix Elements >>>
           2            1            0            0            0       |
           1            2            1            0            0       |
           0            1            2            1            0       |
           0            0            1            2            1       |
           0            0            0            1            2       |
<<< Matrix Elements

Determinant (auto-select, should use LU for n > 4): 6
Note: For n = 5 > 4, auto-select should use LU decomposition (O(n³)).

[Test 5.3.6] Non-square Matrix (Expect Error)
Matrix (3x4, non-square):
Matrix Elements >>>
           0            0            0            0       |
           0            0            0            0       |
           0            0            0            0       |
<<< Matrix Elements

[Error] Determinant requires a square matrix.
Determinant: 0  (Expected: 0 with error message)

[Test 5.3.7] Comparison of Different Methods (5x5 Matrix)
Matrix (5x5):
Matrix Elements >>>
           2            2            3            4            5       |
           2            5            6            8           10       |
           3            6           10           12           15       |
           4            8           12           17           20       |
           5           10           15           20           26       |
<<< Matrix Elements

Determinant (auto-select): 56  (should use LU for n > 4)
Determinant (Laplace):     56  (O(n!), slow for n=5)
Determinant (LU):          56  (O(n³), efficient)
Determinant (Gaussian):    56  (O(n³), efficient)
Note: All methods should give the same result (within numerical precision).
      Auto-select should use LU for n > 4, avoiding slow Laplace expansion.

[Test 5.3.8] Large Matrix (6x6) - Tests Efficient Methods
Matrix (6x6, showing first 4x4 block):
       1.5          2          3          4 ...
         2        4.5          6          8 ...
         3          6        9.5         12 ...
         4          8         12       16.5 ...
...
Determinant (auto-select, uses LU): 2.85938
Determinant (LU):                   2.85938
Determinant (Gaussian):             2.85938
Note: For n > 4, auto-select uses LU decomposition (O(n³) instead of O(n!)).

[Test 5.3.9] Large Matrix (8x8) - Performance Comparison
Matrix (8x8, showing first 4x4 block):
         1          2          3          4 ...
         2          4          6          8 ...
         3          6          9         12 ...
         4          8         12         16 ...
...
[Error] LU decomposition: Matrix is singular or near-singular.
Determinant (LU):       0
Determinant (Gaussian): 0
Note: Both methods are O(n³) and should be much faster than Laplace expansion.

[Group 5.4: Matrix Adjoint Tests]

[Test 5.4.1] Adjoint of 1x1 Matrix
Original Matrix:
Matrix Elements >>>
           5       |
<<< Matrix Elements

Adjoint Matrix:
Matrix Elements >>>
           0       |
<<< Matrix Elements


[Test 5.4.2] Adjoint of 2x2 Matrix
Original Matrix:
Matrix Elements >>>
           1            2       |
           3            4       |
<<< Matrix Elements

Adjoint Matrix:
Matrix Elements >>>
           4            2       |
           3            1       |
<<< Matrix Elements


[Test 5.4.3] Adjoint of 3x3 Matrix
Original Matrix:
Matrix Elements >>>
           1            2            3       |
           0            4            5       |
           1            0            6       |
<<< Matrix Elements

Adjoint Matrix:
Matrix Elements >>>
          24           12           -2       |
          -5            3            5       |
          -4           -2            4       |
<<< Matrix Elements


[Test 5.4.4] Adjoint of Non-Square Matrix (Expect Error)
Original Matrix (2x3, non-square):
Matrix Elements >>>
           0            0            0       |
           0            0            0       |
<<< Matrix Elements

[Error] Adjoint requires a square matrix.
Adjoint Matrix (should be empty due to error):
Matrix Elements >>>
           0       |
<<< Matrix Elements


[Group 5.5: Matrix Normalization Tests]

[Test 5.5.1] Normalize a Standard 2x2 Matrix
Before normalization:
Matrix Elements >>>
           3            4       |
           3            4       |
<<< Matrix Elements

After normalization (Expected L2 norm = 1):
Matrix Elements >>>
    0.424264     0.565685       |
    0.424264     0.565685       |
<<< Matrix Elements


[Test 5.5.2] Normalize a 2x2 Matrix with Stride=4 (Padding Test)
Before normalization:
Matrix Elements >>>
           3            4       |      0            0 
           3            4       |      0            0 
<<< Matrix Elements

After normalization:
Matrix Elements >>>
    0.424264     0.565685       |      0            0 
    0.424264     0.565685       |      0            0 
<<< Matrix Elements


[Test 5.5.3] Normalize a Zero Matrix (Expect Warning)
Matrix Elements >>>
           0            0       |
           0            0       |
<<< Matrix Elements


[Group 5.6: Matrix Norm Calculation Tests]

[Test 5.6.1] 2x2 Matrix Norm (Expect 5.0)
Matrix:
Matrix Elements >>>
           3            4       |
           0            0       |
<<< Matrix Elements

Calculated Norm: 5

[Test 5.6.2] Zero Matrix Norm (Expect 0.0)
Matrix:
Matrix Elements >>>
           0            0            0       |
           0            0            0       |
           0            0            0       |
<<< Matrix Elements

Calculated Norm: 0

[Test 5.6.3] Matrix with Negative Values
Matrix:
Matrix Elements >>>
          -1           -2       |
          -3           -4       |
<<< Matrix Elements

Calculated Norm: 5.47723  (Expect sqrt(30) ≈ 5.477)

[Test 5.6.4] 2x2 Matrix with Stride=4 (Padding Test)
Matrix:
Matrix Elements >>>
           1            2       |      0            0 
           3            4       |      0            0 
<<< Matrix Elements

Calculated Norm: 5.47723  (Expect sqrt(30) ≈ 5.477)

[Group 5.7: Matrix Inversion Tests]

[Test 5.7.1] Inverse of 2x2 Matrix
Original Matrix:
Matrix Elements >>>
           4            7       |
           2            6       |
<<< Matrix Elements

Inverse Matrix:
Matrix Elements >>>
         0.6          0.7       |
         0.2          0.4       |
<<< Matrix Elements

Expected Approx:
[ 0.6  -0.7 ]
[ -0.2  0.4 ]

[Test 5.7.2] Singular Matrix (Expect Error)
Original Matrix:
Matrix Elements >>>
           1            2       |
           2            4       |
<<< Matrix Elements

Note: This matrix is singular (determinant = 0), so inverse should fail.
[Error] Matrix is singular, cannot compute inverse.
Inverse Matrix (Should be zero matrix):
Matrix Elements >>>
           0       |
<<< Matrix Elements


[Test 5.7.3] Inverse of 3x3 Matrix
Original Matrix:
Matrix Elements >>>
           3            0            2       |
           2            0           -2       |
           0            1            1       |
<<< Matrix Elements

Inverse Matrix:
Matrix Elements >>>
         0.2         -0.2           -0       |
         0.2          0.3           -1       |
         0.2          0.3            0       |
<<< Matrix Elements


[Test 5.7.4] Non-Square Matrix (Expect Error)
Original Matrix (2x3, non-square):
Matrix Elements >>>
           0            0            0       |
           0            0            0       |
<<< Matrix Elements

[Error] Determinant requires a square matrix.
[Error] Matrix is singular, cannot compute inverse.
Inverse Matrix (should be empty due to error):
Matrix Elements >>>
           0       |
<<< Matrix Elements


[Group 5.8: Matrix Utilities Tests]

[Test 5.8.1] Generate Identity Matrix (eye)
3x3 Identity Matrix:
Matrix Elements >>>
           1            0            0       |
           0            1            0       |
           0            0            1       |
<<< Matrix Elements

5x5 Identity Matrix:
Matrix Elements >>>
           1            0            0            0            0       |
           0            1            0            0            0       |
           0            0            1            0            0       |
           0            0            0            1            0       |
           0            0            0            0            1       |
<<< Matrix Elements


[Test 5.8.2] Generate Ones Matrix
3x4 Ones Matrix:
Matrix Elements >>>
           1            1            1            1       |
           1            1            1            1       |
           1            1            1            1       |
<<< Matrix Elements

4x4 Ones Matrix (Square):
Matrix Elements >>>
           1            1            1            1       |
           1            1            1            1       |
           1            1            1            1       |
           1            1            1            1       |
<<< Matrix Elements


[Test 5.8.3] Augment Two Matrices Horizontally [A | B]
Matrix A:
Matrix Elements >>>
           1            2       |
           3            4       |
<<< Matrix Elements

Matrix B:
Matrix Elements >>>
           5            6            7       |
           8            9           10       |
<<< Matrix Elements

Augmented Matrix [A | B]:
Matrix Elements >>>
           1            2            5            6            7       |
           3            4            8            9           10       |
<<< Matrix Elements


[Test 5.8.4] Augment with Row Mismatch (Expect Error)
[Error] Cannot augment matrices: Row counts do not match (2 vs 3)
Matrix Info >>>
rows            1
cols            1
elements        1
paddings        0
stride          1
memory          1
data pointer    0x3fce9cf0
temp pointer    0
ext_buff        0
sub_matrix      0
<<< Matrix Info

[Test 5.8.5] Vertically Stack Two Matrices [A; B]
Matrix A (top):
Matrix Elements >>>
           1            2            3       |
           4            5            6       |
<<< Matrix Elements

Matrix B (bottom):
Matrix Elements >>>
           7            8            9       |
          10           11           12       |
<<< Matrix Elements

Vertically Stacked Matrix [A; B]:
Matrix Elements >>>
           1            2            3       |
           4            5            6       |
           7            8            9       |
          10           11           12       |
<<< Matrix Elements

Expected: 4x3 matrix with A on top, B on bottom

[Test 5.8.6] Vertical Stack with Different Row Counts (Same Columns)
Matrix A (1x3):
Matrix Elements >>>
           1            2            3       |
<<< Matrix Elements

Matrix B (3x3):
Matrix Elements >>>
           4            5            6       |
           7            8            9       |
          10           11           12       |
<<< Matrix Elements

Vertically Stacked Matrix [A; B] (1x3 + 3x3 = 4x3):
Matrix Elements >>>
           1            2            3       |
           4            5            6       |
           7            8            9       |
          10           11           12       |
<<< Matrix Elements


[Test 5.8.7] VStack with Column Mismatch (Expect Error)
Matrix A (2x2):
Matrix Elements >>>
           1            2       |
           3            4       |
<<< Matrix Elements

Matrix B (2x3, different columns):
Matrix Elements >>>
           5            6            7       |
           8            9           10       |
<<< Matrix Elements

[Error] Cannot vstack matrices: Column counts do not match (2 vs 3)
Result (should be empty due to error):
Matrix Info >>>
rows            1
cols            1
elements        1
paddings        0
stride          1
memory          1
data pointer    0x3fce9db0
temp pointer    0
ext_buff        0
sub_matrix      0
<<< Matrix Info
============ [tiny_matrix_test end] ============

PHASE IV: 线性系统求解 (组 6)

目的:核心应用 - 求解线性方程组 Ax = b

============ [tiny_matrix_test start] ============

[Test Organization: Application-Oriented Logic]
  Foundation → Basic Ops → Properties → Linear Systems → Decompositions → Applications → Quality


[Group 5.9: Gaussian Elimination Tests]

[Test 5.9.1] 3x3 Matrix (Simple Upper Triangular)
Original Matrix:
Matrix Elements >>>
           2            1           -1       |
          -3           -1            2       |
          -2            1            2       |
<<< Matrix Elements

After Gaussian Elimination (Should be upper triangular):
Matrix Elements >>>
           2            1           -1       |
           0          0.5          0.5       |
           0            0           -1       |
<<< Matrix Elements


[Test 5.9.2] 3x4 Augmented Matrix (Linear System Ax = b)
Original Augmented Matrix [A | b]:
Matrix Elements >>>
           1            2           -1            8       |
          -3           -1            2          -11       |
          -2            1            2           -3       |
<<< Matrix Elements

After Gaussian Elimination (Row Echelon Form):
Matrix Elements >>>
           1            2           -1            8       |
           0            5           -1           13       |
           0            0            1            0       |
<<< Matrix Elements


[Test 5.9.3] Singular Matrix (No Unique Solution)
Original Singular Matrix:
Matrix Elements >>>
           1            2       |
           2            4       |
<<< Matrix Elements

After Gaussian Elimination (Should show rows of zeros):
Matrix Elements >>>
           1            2       |
           0            0       |
<<< Matrix Elements


[Test 5.9.4] Zero Matrix
Matrix Elements >>>
           0            0            0       |
           0            0            0       |
           0            0            0       |
<<< Matrix Elements

After Gaussian Elimination (Should be a zero matrix):
Matrix Elements >>>
           0            0            0       |
           0            0            0       |
           0            0            0       |
<<< Matrix Elements


[Group 5.10: Row Reduce from Gaussian (RREF) Tests]

[Test 5.10.1] 3x4 Augmented Matrix
Original Matrix:
Matrix Elements >>>
           1            2           -1           -4       |
           2            3           -1          -11       |
          -2            0           -3           22       |
<<< Matrix Elements

RREF Result:
Matrix Elements >>>
           1            0            0           -8       |
           0            1            0            1       |
           0            0            1           -2       |
<<< Matrix Elements


[Test 5.10.2] 2x3 Matrix
Original Matrix:
Matrix Elements >>>
           1            2            3       |
           4            5            6       |
<<< Matrix Elements

RREF Result:
Matrix Elements >>>
           1            0           -1       |
           0            1            2       |
<<< Matrix Elements


[Test 5.10.3] Already Reduced Matrix
Original Matrix:
Matrix Elements >>>
           1            0            2       |
           0            1            3       |
<<< Matrix Elements

RREF Result:
Matrix Elements >>>
           1            0            2       |
           0            1            3       |
<<< Matrix Elements


[Group 5.11: Gaussian Inverse Tests]

[Test 5.11.1] 2x2 Matrix Inverse
Original matrix (mat1):
Matrix Elements >>>
           4            7       |
           2            6       |
<<< Matrix Elements

Inverse matrix (mat1):
Matrix Elements >>>
         0.6         -0.7       |
        -0.2          0.4       |
<<< Matrix Elements


[Test 5.11.2] Identity Matrix Inverse
Original matrix (Identity):
Matrix Elements >>>
           1            0            0       |
           0            1            0       |
           0            0            1       |
<<< Matrix Elements

Inverse matrix (Identity):
Matrix Elements >>>
           1            0            0       |
           0            1            0       |
           0            0            1       |
<<< Matrix Elements


[Test 5.11.3] Singular Matrix (Expected: No Inverse)
Original matrix (singular):
Matrix Elements >>>
           1            2            3       |
           4            5            6       |
           7            8            9       |
<<< Matrix Elements

[Error] Matrix is singular, cannot compute inverse.
Inverse matrix (singular):
Matrix Elements >>>
           0       |
<<< Matrix Elements


[Test 5.11.4] 3x3 Matrix Inverse
Original matrix (mat4):
Matrix Elements >>>
           4            7            2       |
           3            5            1       |
           8            6            9       |
<<< Matrix Elements

Inverse matrix (mat4):
Matrix Elements >>>
    -1.85714      2.42857     0.142857       |
    0.904762    -0.952381   -0.0952381       |
     1.04762     -1.52381     0.047619       |
<<< Matrix Elements


[Test 5.11.5] Non-square Matrix Inverse (Expected Error)
Original matrix (non-square):
Matrix Elements >>>
           1            2            3       |
           4            5            6       |
<<< Matrix Elements

[Error] Inversion requires a square matrix.
Inverse matrix (non-square):
Matrix Elements >>>
           0       |
<<< Matrix Elements


[Group 5.12: Dot Product Tests]

[Test 5.12.1] Valid Dot Product (Same Length Vectors)
Vector A:
Matrix Elements >>>
           1       |
           2       |
           3       |
<<< Matrix Elements

Vector B:
Matrix Elements >>>
           4       |
           5       |
           6       |
<<< Matrix Elements

Dot product of vectorA and vectorB: 32

[Test 5.12.2] Invalid Dot Product (Dimension Mismatch)
Vector A (3x1):
Matrix Elements >>>
           1       |
           2       |
           3       |
<<< Matrix Elements

Vector C (2x1, different size):
Matrix Elements >>>
           1       |
           2       |
<<< Matrix Elements

[Error] Dot product requires matrices of the same size.
Dot product (dimension mismatch): 0

[Test 5.12.3] Dot Product of Zero Vectors
Zero Vector A:
Matrix Elements >>>
           0       |
           0       |
           0       |
<<< Matrix Elements

Zero Vector B:
Matrix Elements >>>
           0       |
           0       |
           0       |
<<< Matrix Elements

Dot product of zero vectors: 0

[Group 5.13: Solve Linear System Tests]

[Test 5.13.1] Solving a Simple 2x2 System Ax = b
Matrix A:
Matrix Elements >>>
           2            1       |
           1            3       |
<<< Matrix Elements

Vector b:
Matrix Elements >>>
           5       |
           6       |
<<< Matrix Elements

Solution x:
Matrix Elements >>>
         1.8       |
         1.4       |
<<< Matrix Elements


[Test 5.13.2] Solving a 3x3 System Ax = b
Matrix A:
Matrix Elements >>>
           1            2            1       |
           2            0            3       |
           3            2            1       |
<<< Matrix Elements

Vector b:
Matrix Elements >>>
           9       |
           8       |
           7       |
<<< Matrix Elements

Solution x:
Matrix Elements >>>
          -1       |
     3.33333       |
     3.33333       |
<<< Matrix Elements


[Test 5.13.3] Solving a System Where One Row is All Zeros (Expect Failure or Infinite Solutions)
Matrix A (has zero row):
Matrix Elements >>>
           1            2            3       |
           0            0            0       |
           4            5            6       |
<<< Matrix Elements

Vector b:
Matrix Elements >>>
           9       |
           0       |
          15       |
<<< Matrix Elements

[Error] Pivot is zero, matrix is singular.
Solution x:
Matrix Elements >>>
           0       |
<<< Matrix Elements


[Test 5.13.4] Solving a System with Zero Determinant (Singular Matrix)
Matrix A (singular, determinant = 0):
Matrix Elements >>>
           2            4            1       |
           1            2            3       |
           3            6            2       |
<<< Matrix Elements

Vector b:
Matrix Elements >>>
           5       |
           6       |
           7       |
<<< Matrix Elements

[Error] Pivot is zero, matrix is singular.
Solution x:
Matrix Elements >>>
           0       |
<<< Matrix Elements


[Test 5.13.5] Solving a System with Linearly Dependent Rows (Expect Failure or Infinite Solutions)
Matrix A (all rows linearly dependent):
Matrix Elements >>>
           1            1            1       |
           2            2            2       |
           3            3            3       |
<<< Matrix Elements

Vector b:
Matrix Elements >>>
           6       |
          12       |
          18       |
<<< Matrix Elements

[Error] Pivot is zero, matrix is singular.
Solution x:
Matrix Elements >>>
           0       |
<<< Matrix Elements


[Test 5.13.6] Solving a Larger 4x4 System Ax = b
Matrix A:
Matrix Elements >>>
           4            2            3            1       |
           2            5            1            2       |
           3            1            6            3       |
           1            2            3            4       |
<<< Matrix Elements

Vector b:
Matrix Elements >>>
          10       |
          12       |
          14       |
          16       |
<<< Matrix Elements

Solution x:
Matrix Elements >>>
     1.80645       |
    0.258065       |
   -0.516129       |
     3.80645       |
<<< Matrix Elements


[Group 5.14: Band Solve Tests]

[Test 5.14.1] Simple 3x3 Band Matrix
Matrix A:
Matrix Elements >>>
           2            1            0       |
           1            3            2       |
           0            1            4       |
<<< Matrix Elements

Vector b:
Matrix Elements >>>
           5       |
           6       |
           7       |
<<< Matrix Elements

Solution x:
Matrix Elements >>>
         2.5       |
           0       |
        1.75       |
<<< Matrix Elements


[Test 5.14.2] 4x4 Band Matrix
Matrix A:
Matrix Elements >>>
           2            1            0            0       |
           1            3            2            0       |
           0            1            4            2       |
           0            0            1            5       |
<<< Matrix Elements

Vector b:
Matrix Elements >>>
           8       |
           9       |
          10       |
          11       |
<<< Matrix Elements

Solution x:
Matrix Elements >>>
     3.51429       |
    0.971429       |
     1.28571       |
     1.94286       |
<<< Matrix Elements


[Test 5.14.3] Incompatible Dimensions (Expect Error)
Matrix A (3x3):
Matrix Elements >>>
           1            2            3       |
           4            5            6       |
           7            8            9       |
<<< Matrix Elements

Vector b (2x1, incompatible):
Matrix Elements >>>
          10       |
          11       |
<<< Matrix Elements

[Error] Matrix dimensions are not compatible for solving.
Solution x:
Matrix Elements >>>
           0       |
<<< Matrix Elements


[Test 5.14.4] Singular Matrix (No Unique Solution)
Matrix A (singular, linearly dependent rows):
Matrix Elements >>>
           1            2            3       |
           2            4            6       |
           3            6            9       |
<<< Matrix Elements

Vector b:
Matrix Elements >>>
          10       |
          20       |
          30       |
<<< Matrix Elements

[Error] Zero pivot detected in bandSolve. Cannot proceed.
Solution x:
Matrix Elements >>>
           0       |
           0       |
           0       |
<<< Matrix Elements


[Group 5.15: Roots Tests]

[Test 5.15.1] Solving a Simple 2x2 System Ax = b
Matrix A:
Matrix Elements >>>
           2            1       |
           1            3       |
<<< Matrix Elements

Vector b:
Matrix Elements >>>
           5       |
           6       |
<<< Matrix Elements

Solution x:
Matrix Elements >>>
         1.8       |
         1.4       |
<<< Matrix Elements


[Test 5.15.2] Solving a 3x3 System Ax = b
Matrix A:
Matrix Elements >>>
           1            2            1       |
           2            0            3       |
           3            2            1       |
<<< Matrix Elements

Vector b:
Matrix Elements >>>
           9       |
           8       |
           7       |
<<< Matrix Elements

Solution x:
Matrix Elements >>>
          -1       |
     3.33333       |
     3.33333       |
<<< Matrix Elements


[Test 5.15.3] Singular Matrix (No Unique Solution)
Matrix A (singular, linearly dependent rows):
Matrix Elements >>>
           1            2       |
           2            4       |
<<< Matrix Elements

Vector b:
Matrix Elements >>>
           5       |
           6       |
<<< Matrix Elements

[Error] Pivot is zero, system may have no solution.
Solution x:
Matrix Elements >>>
           0       |
<<< Matrix Elements


[Test 5.15.4] Incompatible Dimensions (Expect Error)
Matrix A (3x3):
Matrix Elements >>>
           1            2            3       |
           4            5            6       |
           7            8            9       |
<<< Matrix Elements

Vector b (2x1, incompatible):
Matrix Elements >>>
          10       |
          11       |
<<< Matrix Elements

[Error] Cannot augment matrices: Row counts do not match (3 vs 2)
[Error] Pivot is zero, system may have no solution.
Solution x:
Matrix Elements >>>
           0       |
<<< Matrix Elements

============ [tiny_matrix_test end] ============

PHASE V: 高级线性代数 (组 7-8)

目的:高级线性代数运算,用于稳定和高效求解

============ [tiny_matrix_test start] ============

[Test Organization: Application-Oriented Logic]
  Foundation → Basic Ops → Properties → Linear Systems → Decompositions → Applications → Quality


[Group 7: Advanced Linear Algebra - Matrix Decomposition Tests]

[Test 7.1] is_positive_definite() - Basic Functionality

[Test 7.1.1] Positive Definite 3x3 Matrix
Matrix:
Matrix Elements >>>
           4            1            0       |
           1            3            0       |
           0            0            2       |
<<< Matrix Elements

Is positive definite: True (Expected: True) [PASS]

[Test 7.1.2] Non-Positive Definite Matrix
Matrix:
Matrix Elements >>>
           1            2       |
           2            1       |
<<< Matrix Elements

Is positive definite: False (Expected: False) [PASS]

[Test 7.2] LU Decomposition

[Test 7.2.1] 3x3 Matrix - LU Decomposition with Pivoting
Matrix A:
Matrix Elements >>>
           2            1            1       |
           4            3            3       |
           2            1            2       |
<<< Matrix Elements


[Results]
Status: OK
L matrix (lower triangular):
Matrix Elements >>>
           1            0            0       |
         0.5            1            0       |
         0.5            1            1       |
<<< Matrix Elements

U matrix (upper triangular):
Matrix Elements >>>
           4            3            3       |
           0         -0.5         -0.5       |
           0            0            1       |
<<< Matrix Elements

P matrix (permutation):
Matrix Elements >>>
           0            1            0       |
           1            0            0       |
           0            0            1       |
<<< Matrix Elements


[Verification] P * A should equal L * U
Total difference: 0 [PASS]

[Test 7.2.2] Solve Linear System using LU Decomposition
System: A * x = b
A:
Matrix Elements >>>
           2            1            1       |
           4            3            3       |
           2            1            2       |
<<< Matrix Elements

b:
Matrix Elements >>>
           1       |
           2       |
           3       |
<<< Matrix Elements


[Results]
Solution x:
Matrix Elements >>>
         0.5       |
          -2       |
           2       |
<<< Matrix Elements

Verification error: 0 [PASS]

[Test 7.3] Cholesky Decomposition

[Test 7.3.1] SPD Matrix - Cholesky Decomposition
Matrix A (SPD):
Matrix Elements >>>
           4            2            0       |
           2            5            1       |
           0            1            3       |
<<< Matrix Elements


[Results]
Status: OK
L matrix (lower triangular):
Matrix Elements >>>
           2            0            0       |
           1            2            0       |
           0          0.5      1.65831       |
<<< Matrix Elements


[Verification] L * L^T should equal A
Total difference: 2.38419e-07 [PASS]

[Test 7.3.2] Solve Linear System using Cholesky Decomposition
Solution x:
Matrix Elements >>>
    0.272727       |
    0.454545       |
    0.181818       |
<<< Matrix Elements

Verification error: 0 [PASS]

[Test 7.4] QR Decomposition

[Test 7.4.1] General 3x3 Matrix - QR Decomposition
Matrix A:
Matrix Elements >>>
           1            2            3       |
           4            5            6       |
           7            8            9       |
<<< Matrix Elements


[Results]
Status: OK
Q matrix (orthogonal):
Matrix Elements >>>
    0.123091     0.904534     0.408248       |
    0.492366     0.301511    -0.816497       |
     0.86164    -0.301511     0.408248       |
<<< Matrix Elements

R matrix (upper triangular):
Matrix Elements >>>
     8.12404      9.60114      11.0782       |
           0     0.904534      1.80907       |
           0            0            0       |
<<< Matrix Elements


[Verification] Q * R should equal A
Total difference: 1.66893e-06 [PASS]
Q orthogonality error: 2.83733e-07 [PASS]

[Test 7.4.2] Least Squares Solution using QR Decomposition
Overdetermined system: A * x ≈ b
A:
Matrix Elements >>>
           1            1       |
           1            2       |
           1            3       |
<<< Matrix Elements

b:
Matrix Elements >>>
           2       |
           3       |
           4       |
<<< Matrix Elements


[Results]
Least squares solution x:
Matrix Elements >>>
           1       |
           1       |
<<< Matrix Elements

Residual norm ||A*x - b||: 4.12953e-07

[Test 7.5] Singular Value Decomposition (SVD)

[Test 7.5.1] General 3x3 Matrix - SVD Decomposition
Matrix A:
Matrix Elements >>>
           1            2            3       |
           4            5            6       |
           7            8            9       |
<<< Matrix Elements


[Results]
Status: OK
Singular values:
Matrix Elements >>>
     1.06837       |
     16.8481       |
           0       |
<<< Matrix Elements

Numerical rank: 2
Iterations: 7
Reconstruction error: 1.68085e-05 [PASS]

[Test 7.5.2] Pseudo-inverse using SVD
Matrix A (3x2):
Matrix Elements >>>
           1            2       |
           3            4       |
           5            6       |
<<< Matrix Elements


[Results]
Pseudo-inverse A^+ (2x3):
Matrix Elements >>>
    -1.33333    -0.333333     0.666666       |
     1.08333     0.333333    -0.416666       |
<<< Matrix Elements

Verification error (A * A^+ * A ≈ A): 5.72205e-06 [PASS]

[Test 7.6] Matrix Decomposition Performance Tests

[Test 7.6.1] LU Decomposition Performance
[Performance] LU Decomposition (4x4 matrix): 110.00 us

[Test 7.6.2] Cholesky Decomposition Performance
[Performance] Cholesky Decomposition (4x4 SPD matrix): 62.00 us

[Test 7.6.3] QR Decomposition Performance
[Performance] QR Decomposition (4x4 matrix): 157.00 us

[Test 7.6.4] SVD Decomposition Performance
[Performance] SVD Decomposition (4x4 matrix): 288.00 us

[Matrix Decomposition Tests Complete]

[Group 8: Advanced Linear Algebra - Gram-Schmidt Orthogonalization Tests]

[Test 8.1] Basic Orthogonalization - Linearly Independent Vectors
Input vectors (each column is a vector):
Matrix Elements >>>
        1.00         1.00         0.00       |
        0.00         1.00         1.00       |
        1.00         0.00         1.00       |
<<< Matrix Elements


[Results]
Status: OK
Orthogonalized vectors Q (each column is orthogonal):
Matrix Elements >>>
        0.71         0.41        -0.58       |
        0.00         0.82         0.58       |
        0.71        -0.41         0.58       |
<<< Matrix Elements

Coefficients R (upper triangular):
Matrix Elements >>>
        1.41         0.71         0.71       |
        0.00         1.22         0.41       |
        0.00         0.00         1.15       |
<<< Matrix Elements


[Verification] Q^T * Q should be identity
Orthogonality error: 0.00 [PASS]

[Verification] Each column of Q should be normalized
  Column 0 norm: 1.00 (error: 0.00) [PASS]
  Column 1 norm: 1.00 (error: 0.00) [PASS]
  Column 2 norm: 1.00 (error: 0.00) [PASS]

[Verification] Q * R should reconstruct original vectors
Reconstruction error: 0.00 [PASS]

[Test 8.2] Orthogonalization - Near-Linear-Dependent Vectors
Input vectors (third vector is nearly linear dependent):
Matrix Elements >>>
        1.00         0.00         1.00       |
        0.00         1.00         1.00       |
        0.00         0.00         0.00       |
<<< Matrix Elements


[Results]
Status: OK
Orthogonalized vectors Q:
Matrix Elements >>>
        1.00         0.00         0.00       |
        0.00         1.00         0.00       |
        0.00         0.00         1.00       |
<<< Matrix Elements

Coefficients R:
Matrix Elements >>>
        1.00         0.00         1.00       |
        0.00         1.00         1.00       |
        0.00         0.00         0.00       |
<<< Matrix Elements


[Note] Third column norm: 1.00 (should be 0 if linearly dependent, or 1 if orthogonalized)

[Test 8.3] Orthogonalization - 2D Vectors (2x2)
Input vectors:
Matrix Elements >>>
        3.00         1.00       |
        1.00         2.00       |
<<< Matrix Elements


[Results]
Status: OK
Orthogonalized vectors Q:
Matrix Elements >>>
        0.95        -0.32       |
        0.32         0.95       |
<<< Matrix Elements

Coefficients R:
Matrix Elements >>>
        3.16         1.58       |
        0.00         1.58       |
<<< Matrix Elements


[Verification] Dot product of Q columns: 0.00 (should be ~0 for orthogonal) [PASS]

[Test 8.4] Error Handling - Invalid Input
Empty matrix test: FAIL (should return false)
============ [tiny_matrix_test end] ============

PHASE VI: 系统识别应用 (组 9)

目的:特征值分解,用于结构健康监测和模态分析

============ [tiny_matrix_test start] ============

[Test Organization: Application-Oriented Logic]
  Foundation → Basic Ops → Properties → Linear Systems → Decompositions → Applications → Quality


[Group 9: System Identification - Eigenvalue and Eigenvector Decomposition Tests]

[Test 9.1] is_symmetric() - Basic Functionality
[Test 9.1.1] Symmetric 3x3 Matrix
Matrix:
Matrix Elements >>>
           4            1            2       |
           1            3            0       |
           2            0            5       |
<<< Matrix Elements

Is symmetric: True (Expected: True)

[Test 9.1.2] Non-Symmetric 3x3 Matrix
Matrix:
Matrix Elements >>>
           1            2            3       |
           4            5            6       |
           7            8            9       |
<<< Matrix Elements

Is symmetric: False (Expected: False)

[Test 9.1.3] Non-Square Matrix (2x3)
Is symmetric: False (Expected: False)

[Test 9.1.4] Symmetric Matrix with Small Numerical Errors
Matrix with error 1e-05:
Matrix Elements >>>
           1      2.00001       |
           2            3       |
<<< Matrix Elements

Difference: |A(0,1) - A(1,0)| = 1.001358e-05 (Expected: 0.000010)
A(0,1) stored value: 2.00001001 (Expected: 2.00001001)
Is symmetric (tolerance=1e-4): True (Expected: True, tolerance > error) [PASS]
Is symmetric (tolerance=1e-6): False (Expected: False, tolerance < error) [PASS]
Difference accuracy: |actual_diff - expected_diff| = 1.36e-08 [PASS - difference stored correctly]

[Test 9.2] power_iteration() - Dominant Eigenvalue

[Test 9.2.1] Simple 2x2 Matrix
Matrix:
Matrix Elements >>>
        2.00         1.00       |
        1.00         2.00       |
<<< Matrix Elements


[Expected Results]
  Expected eigenvalues: 3.0 (largest), 1.0 (smallest)
  Expected dominant eigenvector (for λ=3): approximately [0.707, 0.707] or [-0.707, -0.707] (normalized)
  Expected dominant eigenvector (for λ=1): approximately [0.707, -0.707] or [-0.707, 0.707] (normalized)

[Actual Results]
  Dominant eigenvalue: 3.00 (Expected: 3.0, largest eigenvalue)
  Iterations: 2
  Status: OK
  Dominant eigenvector:
Matrix Elements >>>
        0.71       |
        0.71       |
<<< Matrix Elements

  Error from expected (3.0): 0.00 [PASS]

[Test 9.2.2] 3x3 Stiffness Matrix (SHM Application)
Stiffness Matrix:
Matrix Elements >>>
        2.00        -1.00         0.00       |
       -1.00         2.00        -1.00       |
        0.00        -1.00         2.00       |
<<< Matrix Elements


[Expected Results]
  Expected eigenvalues (approximate): 3.414 (largest), 2.000, 0.586 (smallest)
  Expected primary frequency: sqrt(3.414) ≈ 1.848 rad/s

[Actual Results]
  Dominant eigenvalue (primary frequency squared): 3.41
  Primary frequency: 1.85 rad/s (Expected: ~1.848 rad/s)
  Iterations: 8
  Status: OK
  Error from expected (3.41): 0.00 [PASS]

[Test 9.2.3] Non-Square Matrix (Expect Error)
[Error] Power iteration requires a square matrix.
Status: Error (Expected)

[Test 9.2.4] inverse_power_iteration() - Smallest Eigenvalue (System Identification)

[Test 9.2.4.1] Simple 2x2 Matrix - Smallest Eigenvalue
Matrix (same as Test 9.2.1):
Matrix Elements >>>
        2.00         1.00       |
        1.00         2.00       |
<<< Matrix Elements


[Expected Results]
  Expected eigenvalues: 3.0 (largest), 1.0 (smallest)
  Expected smallest eigenvalue: 1.0
  Expected smallest eigenvector (for λ=1): approximately [0.707, -0.707] or [-0.707, 0.707] (normalized)
  Note: This is critical for system identification - smallest eigenvalue = fundamental frequency

[Actual Results]
  Smallest eigenvalue: 1.00 (Expected: 1.0, smallest eigenvalue)
  Iterations: 6
  Status: OK
  Smallest eigenvector:
Matrix Elements >>>
        0.71       |
       -0.71       |
<<< Matrix Elements

  Error from expected (1.0): 0.00 [PASS]

[Comparison] Power vs Inverse Power Iteration:
  Power iteration (λ_max): 3.00
  Inverse power iteration (λ_min): 1.00
  Ratio (λ_max/λ_min): 3.00 (Expected: ~3.0) [PASS]

[Test 9.2.4.2] 3x3 Stiffness Matrix - Smallest Eigenvalue (SHM Application)
Stiffness Matrix (same as Test 9.2.2):
Matrix Elements >>>
        2.00        -1.00         0.00       |
       -1.00         2.00        -1.00       |
        0.00        -1.00         2.00       |
<<< Matrix Elements


[Expected Results]
  Expected eigenvalues (approximate): 3.414 (largest), 2.000, 0.586 (smallest)
  Expected smallest eigenvalue: ~0.586 (fundamental frequency squared)
  Expected fundamental frequency: sqrt(0.586) ≈ 0.765 rad/s
  Note: Smallest eigenvalue is critical for system identification - represents fundamental mode

[Actual Results]
  Smallest eigenvalue (fundamental frequency squared): 0.59
  Fundamental frequency: 0.77 rad/s (Expected: ~0.765 rad/s)
  Iterations: 8
  Status: OK
  Smallest eigenvector (fundamental mode shape):
Matrix Elements >>>
        0.50       |
        0.71       |
        0.50       |
<<< Matrix Elements

  Error from expected (0.59): 0.00 [PASS]

[Comparison] Power vs Inverse Power Iteration for SHM:
  Power iteration (primary frequency²): 3.41 → frequency: 1.85 rad/s
  Inverse power iteration (fundamental frequency²): 0.59 → frequency: 0.77 rad/s
  Frequency ratio: 2.41 (Expected: ~2.4, ratio of highest to lowest mode)

[Test 9.2.4.3] Non-Square Matrix (Expect Error)
[Error] Inverse power iteration requires a square matrix.
Status: Error (Expected)
Error handling: [PASS]

[Test 9.2.4.4] Near-Singular Matrix (Edge Case)
Matrix (near-singular but invertible):
Matrix Elements >>>
        1.00         0.00         0.00       |
        0.00         1.00         0.00       |
        0.00         0.00         1.00       |
<<< Matrix Elements


[Results]
  Status: OK
  Smallest eigenvalue: 1.00
  Iterations: 2
  Note: Successfully handled near-singular matrix [PASS]

[Test 9.3] eigendecompose_jacobi() - Symmetric Matrix Decomposition

[Test 9.3.1] 2x2 Symmetric Matrix - Complete Decomposition
[Expected Results]
  Expected eigenvalues: 3.0, 1.0 (in any order)
  Expected eigenvectors (for λ=3): [0.707, 0.707] or [-0.707, -0.707] (normalized)
  Expected eigenvectors (for λ=1): [0.707, -0.707] or [-0.707, 0.707] (normalized)

[Actual Results]
Eigenvalues:
Matrix Elements >>>
        1.00       |
        3.00       |
<<< Matrix Elements

Eigenvectors (each column is an eigenvector):
Matrix Elements >>>
        0.71         0.71       |
       -0.71         0.71       |
<<< Matrix Elements

Iterations: 2
Status: OK
Eigenvalue check (should be 3.0 and 1.0): [PASS]

[Verification] Check A * v = lambda * v for first eigenvector:
A * v:
Matrix Elements >>>
        0.71       |
       -0.71       |
<<< Matrix Elements

lambda * v:
Matrix Elements >>>
        0.71       |
       -0.71       |
<<< Matrix Elements

Verification (A*v = λ*v): [PASS]

[Test 9.3.2] 3x3 Stiffness Matrix (SHM Application)
[Expected Results]
  Expected eigenvalues (approximate): 3.414, 2.000, 0.586
  Expected natural frequencies: 1.848, 1.414, 0.765 rad/s
  Note: Eigenvalues may appear in any order

[Actual Results]
Eigenvalues (natural frequencies squared):
Matrix Elements >>>
        3.41       |
        0.59       |
        2.00       |
<<< Matrix Elements

Natural frequencies (rad/s):
  Mode 0: 1.85 rad/s (Expected: ~1.85 rad/s) [PASS]
  Mode 1: 0.77 rad/s (Expected: ~0.76 rad/s) [PASS]
  Mode 2: 1.41 rad/s (Expected: ~1.41 rad/s) [PASS]
Eigenvectors (mode shapes):
Matrix Elements >>>
        0.50         0.50        -0.71       |
       -0.71         0.71         0.00       |
        0.50         0.50         0.71       |
<<< Matrix Elements

Iterations: 9
Status: OK

[Test 9.3.3] Diagonal Matrix (Eigenvalues on diagonal)
Matrix:
Matrix Elements >>>
        5.00         0.00         0.00       |
        0.00         3.00         0.00       |
        0.00         0.00         1.00       |
<<< Matrix Elements


[Expected Results]
  Expected eigenvalues: 5.0, 3.0, 1.0 (diagonal elements, may be in any order)
  Expected eigenvectors: standard basis vectors [1,0,0], [0,1,0], [0,0,1] (or their negatives)
  Expected iterations: 1 (diagonal matrix should converge immediately)

[Actual Results]
Eigenvalues:
Matrix Elements >>>
        5.00       |
        3.00       |
        1.00       |
<<< Matrix Elements

Eigenvectors:
Matrix Elements >>>
        1.00         0.00         0.00       |
        0.00         1.00         0.00       |
        0.00         0.00         1.00       |
<<< Matrix Elements

Iterations: 1 (Expected: 1)
Eigenvalue check (should be 5.0, 3.0, 1.0): [PASS]

[Test 9.4] eigendecompose_qr() - General Matrix Decomposition

[Test 9.4.1] General 2x2 Matrix
Matrix:
Matrix Elements >>>
        1.00         2.00       |
        3.00         4.00       |
<<< Matrix Elements


[Expected Results]
  Expected eigenvalues: (5+√33)/2 ≈ 5.372, (5-√33)/2 ≈ -0.372
  Note: This is a non-symmetric matrix, eigenvalues are real but may have complex eigenvectors

[Actual Results]
Eigenvalues:
Matrix Elements >>>
        5.37       |
       -0.37       |
<<< Matrix Elements

Eigenvectors:
Matrix Elements >>>
        0.42         0.91       |
        0.91        -0.42       |
<<< Matrix Elements

Iterations: 6
Status: OK
Eigenvalue 1: 5.37 (Expected: 5.37, Error: 0.00, Rel Error: 0.01%) [PASS]
Eigenvalue 2: -0.37 (Expected: -0.37, Error: 0.00, Rel Error: 0.07%) [PASS]
Overall eigenvalue check: [PASS]

[Test 9.4.2] Non-Symmetric 3x3 Matrix
Matrix [1,2,3; 4,5,6; 7,8,9]:
Matrix Elements >>>
        1.00         2.00         3.00       |
        4.00         5.00         6.00       |
        7.00         8.00         9.00       |
<<< Matrix Elements


[Expected Results]
  Expected eigenvalues (theoretical): 16.12, -1.12, 0.00
  Note: This matrix is rank-deficient (determinant = 0), so one eigenvalue is 0
  Note: QR algorithm may have numerical errors, especially for non-symmetric matrices
  Acceptable range: largest eigenvalue ~15-18, smallest eigenvalue near 0

[Actual Results]
Eigenvalues:
Matrix Elements >>>
       16.12       |
       -1.12       |
        0.00       |
<<< Matrix Elements

Eigenvectors:
Matrix Elements >>>
        0.23         0.88         0.41       |
        0.53         0.24        -0.82       |
        0.82        -0.40         0.41       |
<<< Matrix Elements

Iterations: 6
Status: OK
Eigenvalue 0: 16.12 (Expected: 16.12, Error: 0.00, Rel Error: 0.02%) [PASS]
Eigenvalue 1: -1.12 (Expected: -1.12, Error: 0.00, Rel Error: 0.28%) [PASS]
Eigenvalue 2: 0.00 (Expected: 0.00, Error: 0.00, Rel Error: 0.00%) [PASS]
Overall eigenvalue check: [PASS]

[Test 9.5] eigendecompose() - Automatic Method Selection

[Test 9.5.1] Symmetric Matrix (Auto-select: Jacobi)
Matrix:
Matrix Elements >>>
        4.00         1.00         2.00       |
        1.00         3.00         0.00       |
        2.00         0.00         5.00       |
<<< Matrix Elements


[Expected Results]
  Method: Should automatically use Jacobi (symmetric matrix detected)
  Expected eigenvalues (approximate): 6.67, 3.48, 1.85
  Note: Eigenvalues may appear in any order

[Actual Results]
Eigenvalues:
Matrix Elements >>>
        1.85       |
        3.48       |
        6.67       |
<<< Matrix Elements

Iterations: 8
Status: OK
Method used: Jacobi (auto-selected for symmetric matrix)

[Test 9.5.2] Non-Symmetric Matrix (Auto-select: QR)
[Expected Results]
  Method: Should automatically use QR (non-symmetric matrix detected)
  Expected eigenvalues (theoretical): 16.12, -1.12, 0.00
  Note: One eigenvalue should be near 0 (rank-deficient matrix)
  Note: QR algorithm may have numerical errors for non-symmetric matrices
  Acceptable: largest ~15-18, smallest near 0, one near -1 to -3

[Actual Results]
Eigenvalues:
Matrix Elements >>>
       16.12       |
       -1.12       |
        0.00       |
<<< Matrix Elements

Iterations: 6
Status: OK
Method used: QR (auto-selected for non-symmetric matrix)
Eigenvalue 0: 16.12 (Expected: 16.12, Error: 0.00, Rel Error: 0.02%) [PASS]
Eigenvalue 1: -1.12 (Expected: -1.12, Error: 0.00, Rel Error: 0.28%) [PASS]
Eigenvalue 2: 0.00 (Expected: 0.00, Error: 0.00, Rel Error: 0.00%) [PASS]
Overall eigenvalue check: [PASS]

[Test 9.6] SHM Application - Structural Dynamics Analysis

[Test 9.6.1] 4-DOF Mass-Spring System
Stiffness Matrix K:
Matrix Elements >>>
        2.00        -1.00         0.00         0.00       |
       -1.00         2.00        -1.00         0.00       |
        0.00        -1.00         2.00        -1.00       |
        0.00         0.00        -1.00         1.00       |
<<< Matrix Elements

Is symmetric: Yes

[Quick Analysis] Primary frequency using power_iteration():
[Expected Results]
  Expected primary eigenvalue: ~3.53 (largest eigenvalue)
  Expected primary frequency: sqrt(3.53) ≈ 1.88 rad/s

[Actual Results]
  Primary eigenvalue: 3.53 (Expected: ~3.53)
  Primary frequency: 1.88 rad/s (Expected: ~1.88 rad/s)
  Iterations: 13
  Error from expected: 0.00 [PASS]

[Complete Analysis] Full modal analysis using eigendecompose_jacobi():
[Expected Results]
  Expected eigenvalues (approximate): 3.53, 2.35, 1.00, 0.12
  Expected natural frequencies: 1.88, 1.53, 1.00, 0.35 rad/s
  Note: These are approximate values for the 4-DOF system

[Actual Results]
All eigenvalues (natural frequencies squared):
Matrix Elements >>>
        3.53       |
        1.00       |
        2.35       |
        0.12       |
<<< Matrix Elements

Natural frequencies (rad/s):
  Mode 0: 1.88 rad/s (Expected: ~1.88 rad/s) [PASS]
  Mode 1: 1.00 rad/s (Expected: ~1.00 rad/s) [PASS]
  Mode 2: 1.53 rad/s (Expected: ~1.53 rad/s) [PASS]
  Mode 3: 0.35 rad/s (Expected: ~0.35 rad/s) [PASS]
Mode shapes (eigenvectors):
Matrix Elements >>>
        0.43         0.58        -0.66         0.23       |
       -0.66         0.58         0.23         0.43       |
        0.58        -0.00         0.58         0.58       |
       -0.23        -0.58        -0.43         0.66       |
<<< Matrix Elements

Total iterations: 17

[Test 9.7] Edge Cases and Error Handling

[Test 9.7.1] 1x1 Matrix
Matrix: [5.0]
[Expected Results]
  Expected eigenvalue: 5.0 (the matrix element itself)
  Expected eigenvector: [1.0] (normalized)

[Actual Results]
Eigenvalue: 5.00 (Expected: 5.0)
Eigenvector:
Matrix Elements >>>
        1.00       |
<<< Matrix Elements

Error from expected: 0.00 [PASS]

[Test 9.7.2] Zero Matrix
[Error] Power iteration: computed vector norm too small.
Status: Error (Expected)

[Test 9.7.3] Identity Matrix
Matrix (3x3 Identity):
Matrix Elements >>>
        1.00         0.00         0.00       |
        0.00         1.00         0.00       |
        0.00         0.00         1.00       |
<<< Matrix Elements


[Expected Results]
  Expected eigenvalues: 1.0, 1.0, 1.0 (all eigenvalues are 1)
  Expected eigenvectors: Any orthonormal basis (e.g., standard basis vectors)
  Expected iterations: 1 (should converge immediately)

[Actual Results]
Eigenvalues (should all be 1.0):
Matrix Elements >>>
        1.00       |
        1.00       |
        1.00       |
<<< Matrix Elements

Eigenvectors:
Matrix Elements >>>
        1.00         0.00         0.00       |
        0.00         1.00         0.00       |
        0.00         0.00         1.00       |
<<< Matrix Elements

Iterations: 1 (Expected: 1)
All eigenvalues = 1.0: [PASS]

[Test 9.8] Performance Test for SHM Applications

[Test 9.8.1] Power Iteration Performance (Real-time SHM - Dominant Eigenvalue)
[Performance] Power Iteration (3x3 matrix): 101.00 us

[Test 9.8.2] Inverse Power Iteration Performance (System Identification - Smallest Eigenvalue)
[Performance] Inverse Power Iteration (3x3 matrix): 495.00 us

[Test 9.8.3] Jacobi Method Performance (Complete Eigendecomposition - Symmetric Matrices)
[Performance] Jacobi Decomposition (3x3 symmetric matrix): 129.00 us

[Test 9.8.4] QR Method Performance (Complete Eigendecomposition - General Matrices)
[Performance] QR Decomposition (3x3 general matrix): 760.00 us

[Eigenvalue Decomposition Tests Complete]
============ [tiny_matrix_test end] ============

PHASE VII: 辅助函数 (组 10-11)

目的:便利函数和 I/O 操作

============ [tiny_matrix_test start] ============

[Test Organization: Application-Oriented Logic]
  Foundation → Basic Ops → Properties → Linear Systems → Decompositions → Applications → Quality


[Group 10: Auxiliary Functions - Stream Operators Tests]

[Test 10.1] Stream Insertion Operator (<<) for Mat
Matrix mat1:
1 2 3
4 5 6
7 8 9


[Test 10.2] Stream Insertion Operator (<<) for Mat::ROI
ROI created: ROI(pos_x=1, pos_y=2, width=3, height=4)
Expected output:
  row start: 2 (pos_y)
  col start: 1 (pos_x)
  row count: 4 (height)
  col count: 3 (width)

Actual output:
row start 2
col start 1
row count 4
col count 3


[Test 10.3] Stream Extraction Operator (>>) for Mat
Simulated input: "10 20 30 40"
Matrix mat2 after input:
10 20
30 40

Expected: [10, 20; 30, 40]

[Test 10.4] Stream Extraction Operator (>>) for Mat (2x3 matrix)
Simulated input: "1.5 2.5 3.5 4.5 5.5 6.5"
Matrix mat3 after input:
1.5 2.5 3.5
4.5 5.5 6.5

Expected: [1.5, 2.5, 3.5; 4.5, 5.5, 6.5]

[Group 11: Auxiliary Functions - Global Arithmetic Operators Tests]

[Test 11.1] Matrix Addition (operator+)
Matrix A:
Matrix Elements >>>
           1            2       |
           3            4       |
<<< Matrix Elements

Matrix B:
Matrix Elements >>>
           5            6       |
           7            8       |
<<< Matrix Elements

matA + matB:
6 8
10 12


[Test 11.2] Matrix Addition with Constant (operator+)
Matrix A:
Matrix Elements >>>
           1            2       |
           3            4       |
<<< Matrix Elements

Constant: 5.0
matA + 5.0f:
6 7
8 9


[Test 11.3] Matrix Subtraction (operator-)
Matrix A:
Matrix Elements >>>
           1            2       |
           3            4       |
<<< Matrix Elements

Matrix B:
Matrix Elements >>>
           5            6       |
           7            8       |
<<< Matrix Elements

matA - matB:
-4 -4
-4 -4


[Test 11.4] Matrix Subtraction with Constant (operator-)
Matrix A:
Matrix Elements >>>
           1            2       |
           3            4       |
<<< Matrix Elements

Constant: 2.0
matA - 2.0f:
-1 0
1 2


[Test 11.5] Matrix Multiplication (operator*)
Matrix C (2x3):
Matrix Elements >>>
           1            2            3       |
           4            5            6       |
<<< Matrix Elements

Matrix D (3x2):
Matrix Elements >>>
           7            8       |
           9           10       |
          11           12       |
<<< Matrix Elements

matC * matD:
58 64
139 154


[Test 11.6] Matrix Multiplication with Constant (operator*)
Matrix A:
Matrix Elements >>>
           1            2       |
           3            4       |
<<< Matrix Elements

Constant: 2.0
matA * 2.0f:
2 4
6 8


[Test 11.7] Matrix Division (operator/)
Matrix A:
Matrix Elements >>>
           1            2       |
           3            4       |
<<< Matrix Elements

Constant: 2.0
matA / 2.0f:
0.5 1
1.5 2


[Test 11.8] Matrix Division Element-wise (operator/)
Matrix A:
Matrix Elements >>>
           1            2       |
           3            4       |
<<< Matrix Elements

Matrix B:
Matrix Elements >>>
           5            6       |
           7            8       |
<<< Matrix Elements

matA / matB:
0.2 0.333333
0.428571 0.5


[Test 11.9] Matrix Comparison (operator==)
Matrix E:
Matrix Elements >>>
           1            2       |
           3            4       |
<<< Matrix Elements

Matrix F:
Matrix Elements >>>
           1            2       |
           3            4       |
<<< Matrix Elements

matE == matF: True

After modifying matF(0,0) = 5:
Matrix E:
Matrix Elements >>>
           1            2       |
           3            4       |
<<< Matrix Elements

Matrix F:
Matrix Elements >>>
           5            2       |
           3            4       |
<<< Matrix Elements

operator == Error: 0 0, m1.data=1, m2.data=5, diff=4
matE == matF after modification: False
============ [tiny_matrix_test end] ============

PHASE VIII: 质量保证 (组 12-14)

目的:确保鲁棒性、性能和正确性

============ [tiny_matrix_test start] ============

[Test Organization: Application-Oriented Logic]
  Foundation → Basic Ops → Properties → Linear Systems → Decompositions → Applications → Quality


[Group 12: Quality Assurance - Boundary Conditions and Error Handling Tests]

[Test 12.1] Null Pointer Handling in print_matrix
[Error] Cannot print matrix: data pointer is null.

[Test 12.2] Null Pointer Handling in operator<<
[Error] Cannot print matrix: data pointer is null.


[Test 12.3] Invalid Block Parameters
[Error] Invalid block parameters: negative start position or non-positive block size.
block(-1, 0, 2, 2): Error
[Error] Block exceeds matrix boundaries.
block(2, 2, 2, 2) on 3x3 matrix: Error
[Error] Invalid block parameters: negative start position or non-positive block size.
block(0, 0, 0, 2): Error

[Test 12.4] Invalid swap_rows Parameters
Before invalid swap_rows:
Matrix Elements >>>
           1            2            3       |
           4            5            6       |
           7            8            9       |
<<< Matrix Elements

Error: row index out of range
After swap_rows(-1, 1):
Matrix Elements >>>
           1            2            3       |
           4            5            6       |
           7            8            9       |
<<< Matrix Elements

Error: row index out of range
After swap_rows(0, 5):
Matrix Elements >>>
           1            2            3       |
           4            5            6       |
           7            8            9       |
<<< Matrix Elements


[Test 12.5] Invalid swap_cols Parameters
Before invalid swap_cols:
Matrix Elements >>>
           1            2            3       |
           4            5            6       |
           7            8            9       |
<<< Matrix Elements

Error: column index out of range
After swap_cols(-1, 1):
Matrix Elements >>>
           1            2            3       |
           4            5            6       |
           7            8            9       |
<<< Matrix Elements

Error: column index out of range
After swap_cols(0, 5):
Matrix Elements >>>
           1            2            3       |
           4            5            6       |
           7            8            9       |
<<< Matrix Elements


[Test 12.6] Division by Zero
[Error] Division by zero in operator/.
mat3 / 0.0f: Error

[Test 12.7] Matrix Division with Zero Elements
[Error] Matrix division failed: Division by zero detected.
mat4 /= divisor (with zero):
Matrix Elements >>>
           1            2       |
           3            4       |
<<< Matrix Elements


[Test 12.8] Empty Matrix Operations
Empty matrix addition: Error

[Group 13: Quality Assurance - Performance Benchmarks Tests]

[Test 13.1] Matrix Addition Performance
[Performance] 50x50 Matrix Addition (100 iterations): 15962.00 us total, 159.62 us avg

[Test 13.2] Matrix Multiplication Performance
[Performance] 30x30 Matrix Multiplication (100 iterations): 66056.00 us total, 660.56 us avg

[Test 13.3] Matrix Transpose Performance
[Performance] 50x30 Matrix Transpose (100 iterations): 17898.00 us total, 178.98 us avg

[Test 13.4] Determinant Calculation Performance Comparison

[Test 13.4.1] Small Matrix (4x4) - Laplace Expansion
[Performance] 4x4 Determinant (Laplace, 10 iterations): 2883.00 us total, 288.30 us avg

[Test 13.4.2] Large Matrix (8x8) - LU Decomposition
[Error] LU decomposition: Matrix is singular or near-singular.
[Error] LU decomposition: Matrix is singular or near-singular.
[Error] LU decomposition: Matrix is singular or near-singular.
[Error] LU decomposition: Matrix is singular or near-singular.
[Error] LU decomposition: Matrix is singular or near-singular.
[Error] LU decomposition: Matrix is singular or near-singular.
[Error] LU decomposition: Matrix is singular or near-singular.
[Error] LU decomposition: Matrix is singular or near-singular.
[Error] LU decomposition: Matrix is singular or near-singular.
[Error] LU decomposition: Matrix is singular or near-singular.
[Performance] 8x8 Determinant (LU, 10 iterations): 55564.00 us total, 5556.40 us avg

[Test 13.4.3] Large Matrix (8x8) - Gaussian Elimination
[Performance] 8x8 Determinant (Gaussian, 10 iterations): 349.00 us total, 34.90 us avg

[Test 13.4.4] Large Matrix (8x8) - Auto-select Method
[Error] LU decomposition: Matrix is singular or near-singular.
[Error] LU decomposition: Matrix is singular or near-singular.
[Error] LU decomposition: Matrix is singular or near-singular.
[Error] LU decomposition: Matrix is singular or near-singular.
[Error] LU decomposition: Matrix is singular or near-singular.
[Error] LU decomposition: Matrix is singular or near-singular.
[Error] LU decomposition: Matrix is singular or near-singular.
[Error] LU decomposition: Matrix is singular or near-singular.
[Error] LU decomposition: Matrix is singular or near-singular.
[Error] LU decomposition: Matrix is singular or near-singular.
[Performance] 8x8 Determinant (auto-select, 10 iterations): 55582.00 us total, 5558.20 us avg

[Note] Performance Summary:
  - Laplace expansion (O(n!)): Suitable only for small matrices (n <= 4)
  - LU decomposition (O(n³)): Efficient for large matrices, auto-selected for n > 4
  - Gaussian elimination (O(n³)): Alternative efficient method for large matrices
  - Auto-select: Automatically chooses the best method based on matrix size

[Test 13.5] Matrix Copy with Padding Performance
[Performance] 8x8 Copy ROI (with padding) (100 iterations): 2342.00 us total, 23.42 us avg

[Test 13.6] Element Access Performance
[Performance] Computing element access (warmup)...
[Performance] 50x50 Element Access (all elements) (100 iterations): 9706.00 us total, 97.06 us avg

[Group 14: Quality Assurance - Memory Layout Tests (Padding and Stride)]

[Test 14.1] Contiguous Memory (no padding)
Matrix 3x4 (stride=4, pad=0):
Matrix Info >>>
rows            3
cols            4
elements        12
paddings        0
stride          4
memory          12
data pointer    0x3fce9af0
temp pointer    0
ext_buff        0
sub_matrix      0
<<< Matrix Info
Matrix Elements >>>
        0.00         1.00         2.00         3.00       |
        4.00         5.00         6.00         7.00       |
        8.00         9.00        10.00        11.00       |
<<< Matrix Elements


[Test 14.2] Padded Memory (stride > col)
Matrix 3x4 (stride=5, pad=1):
Matrix Info >>>
rows            3
cols            4
elements        12
paddings        1
stride          5
memory          15
data pointer    0x3fc991e4
temp pointer    0
ext_buff        1   (External buffer or View)
sub_matrix      0
<<< Matrix Info
Matrix Elements >>>
        0.00         1.00         2.00         3.00       |   0.00 
        4.00         5.00         6.00         7.00       |   0.00 
        8.00         9.00        10.00        11.00       |   0.00 
<<< Matrix Elements


[Test 14.3] Addition with Padded Matrices
Result of padded matrix addition:
Matrix Info >>>
rows            3
cols            4
elements        12
paddings        1
stride          5
memory          15
data pointer    0x3fce9c64
temp pointer    0
ext_buff        0
sub_matrix      0
<<< Matrix Info
Matrix Elements >>>
       11.00        22.00        33.00        44.00       |   0.00 
       55.00        66.00        77.00        88.00       |   0.00 
       99.00       110.00       121.00       132.00       |   0.00 
<<< Matrix Elements


[Test 14.4] ROI Operations with Padded Matrices
ROI (1,1,2,2) from padded matrix:
Matrix Info >>>
rows            2
cols            2
elements        4
paddings        3
stride          5
memory          10
data pointer    0x3fc991fc
temp pointer    0
ext_buff        1   (External buffer or View)
sub_matrix      1   (This is a Sub-Matrix View)
<<< Matrix Info
Matrix Elements >>>
        5.00         6.00       |   7.00         0.00         8.00 
        9.00        10.00       |  11.00         0.00         0.00 
<<< Matrix Elements


[Test 14.5] Copy Operations Preserve Stride
Copied matrix (should have stride=4, no padding):
Matrix Info >>>
rows            3
cols            4
elements        12
paddings        0
stride          4
memory          12
data pointer    0x3fce9d98
temp pointer    0
ext_buff        0
sub_matrix      0
<<< Matrix Info
Matrix Elements >>>
        0.00         1.00         2.00         3.00       |
        4.00         5.00         6.00         7.00       |
        8.00         9.00        10.00        11.00       |
<<< Matrix Elements

============ [tiny_matrix_test end] ============