Matrix#

class numpy::Matrix#

numpy C++ class.

Example#

#include <numpy/np_ndarray.h>
using namespace numpy;

// Use Matrix
Matrix obj;
// ... operations ...

Constructors#

Signature

Location

Example

Matrix(size_trows, size_tcols)

NP_MATRIX.H:51

View

Matrix(const std::vector<std::vector<T>>&data)

NP_MATRIX.H:58

View

Matrix(const NDArray<T>&array)

NP_MATRIX.H:84

View

Matrix(const std::string &matlab_string)

NP_MATRIX.H:92

View

Matrix(const Matrix &other)

NP_MATRIX.H:97

View

Operators#

Signature

Return Type

Location

Example

Matrix & operator=(const Matrix &other)

Matrix &

NP_MATRIX.H:100

T operator()(size_trow, size_tcol)

T

NP_MATRIX.H:163

Matrix<T> operator\*(const Matrix<T>&other)

Matrix<T>

NP_MATRIX.H:180

Matrix<T> operator+(const Matrix<T>&other)

Matrix<T>

NP_MATRIX.H:187

Matrix<T> operator-(const Matrix<T>&other)

Matrix<T>

NP_MATRIX.H:194

Matrix<T> operator^(intpower)

Matrix<T>

NP_MATRIX.H:201

Matrix<T> operator\*(const T &scalar)

Matrix<T>

NP_MATRIX.H:224

operator NDArray<T>()

NP_MATRIX.H:354

Array Creation#

Signature

Return Type

Location

Example

Matrix<T> eye(size_tn)

Matrix<T>

NP_MATRIX.H:361

View

Matrix<T> ones(size_trows, size_tcols)

Matrix<T>

NP_MATRIX.H:372

View

Matrix<T> zeros(size_trows, size_tcols)

Matrix<T>

NP_MATRIX.H:385

View

Shape Manipulation#

Signature

Return Type

Location

Example

Matrix<T> transpose()

Matrix<T>

NP_MATRIX.H:112

View

Linear Algebra#

Signature

Return Type

Location

Example

T det()

T

NP_MATRIX.H:246

View

Matrix<T> inv()

Matrix<T>

NP_MATRIX.H:281

View

Matrix<T> matmul(const Matrix<T>&other)

Matrix<T>

NP_MATRIX.H:234

View

Matrix<T> pinv()

Matrix<T>

NP_MATRIX.H:314

View

T trace()

T

NP_MATRIX.H:267

View

Other Methods#

Signature

Return Type

Location

Example

Matrix<T> H()

Matrix<T>

NP_MATRIX.H:121

View

Matrix<T> I()

Matrix<T>

NP_MATRIX.H:140

View

size_t cols()

size_t

NP_MATRIX.H:155

View

void ensureTwoDimensional()

void

NP_MATRIX.H:32

bool isSingular()

bool

NP_MATRIX.H:326

bool isSquare()

bool

NP_MATRIX.H:321

View

void parseMatlabString(const std::string &str)

void

NP_MATRIX.H:393

void print()

void

NP_MATRIX.H:349

View

size_t rows()

size_t

NP_MATRIX.H:154

View

void setElement(size_trow, size_tcol, const T &value)

void

NP_MATRIX.H:170

View

size_t size()

size_t

NP_MATRIX.H:156

View

std::string toString()

std::string

NP_MATRIX.H:339

View

void validateSquare(const std::string &operation)

void

NP_MATRIX.H:38

Code Examples#

The following examples are extracted from the test suite.

Matrix (np_test_5_all.cpp:8563)
8553        mat.setElement(i, j, static_cast<double>(i * 3 + j));
8554      }
8555    }
8556
8557    std::string result = mat.toString();
8558
8559    // std::cout << "Result:\n" << result << std::endl;
8560
8561    verify_not_empty(result, "Matrix toString()");
8562
8563    if (!verify_contains(result, "Matrix(3x3)", "Matrix")) {
8564      throw std::runtime_error("Missing matrix dimensions in toString()");
8565    }
8566
8567    std::cout << " -> tests passed" << std::endl;
8568  }
8569
8570  void np_test_toString_matrix_identity() {
8571    std::cout << "========= Matrix::toString() identity matrix =======================";
8572
8573    numpy::Matrix<int> mat = numpy::Matrix<int>::eye(4);
Matrix (np_test_5_all.cpp:8563)
8553        mat.setElement(i, j, static_cast<double>(i * 3 + j));
8554      }
8555    }
8556
8557    std::string result = mat.toString();
8558
8559    // std::cout << "Result:\n" << result << std::endl;
8560
8561    verify_not_empty(result, "Matrix toString()");
8562
8563    if (!verify_contains(result, "Matrix(3x3)", "Matrix")) {
8564      throw std::runtime_error("Missing matrix dimensions in toString()");
8565    }
8566
8567    std::cout << " -> tests passed" << std::endl;
8568  }
8569
8570  void np_test_toString_matrix_identity() {
8571    std::cout << "========= Matrix::toString() identity matrix =======================";
8572
8573    numpy::Matrix<int> mat = numpy::Matrix<int>::eye(4);
Matrix (np_test_5_all.cpp:8563)
8553        mat.setElement(i, j, static_cast<double>(i * 3 + j));
8554      }
8555    }
8556
8557    std::string result = mat.toString();
8558
8559    // std::cout << "Result:\n" << result << std::endl;
8560
8561    verify_not_empty(result, "Matrix toString()");
8562
8563    if (!verify_contains(result, "Matrix(3x3)", "Matrix")) {
8564      throw std::runtime_error("Missing matrix dimensions in toString()");
8565    }
8566
8567    std::cout << " -> tests passed" << std::endl;
8568  }
8569
8570  void np_test_toString_matrix_identity() {
8571    std::cout << "========= Matrix::toString() identity matrix =======================";
8572
8573    numpy::Matrix<int> mat = numpy::Matrix<int>::eye(4);
Matrix (np_test_5_all.cpp:8563)
8553        mat.setElement(i, j, static_cast<double>(i * 3 + j));
8554      }
8555    }
8556
8557    std::string result = mat.toString();
8558
8559    // std::cout << "Result:\n" << result << std::endl;
8560
8561    verify_not_empty(result, "Matrix toString()");
8562
8563    if (!verify_contains(result, "Matrix(3x3)", "Matrix")) {
8564      throw std::runtime_error("Missing matrix dimensions in toString()");
8565    }
8566
8567    std::cout << " -> tests passed" << std::endl;
8568  }
8569
8570  void np_test_toString_matrix_identity() {
8571    std::cout << "========= Matrix::toString() identity matrix =======================";
8572
8573    numpy::Matrix<int> mat = numpy::Matrix<int>::eye(4);
Matrix (np_test_5_all.cpp:8563)
8553        mat.setElement(i, j, static_cast<double>(i * 3 + j));
8554      }
8555    }
8556
8557    std::string result = mat.toString();
8558
8559    // std::cout << "Result:\n" << result << std::endl;
8560
8561    verify_not_empty(result, "Matrix toString()");
8562
8563    if (!verify_contains(result, "Matrix(3x3)", "Matrix")) {
8564      throw std::runtime_error("Missing matrix dimensions in toString()");
8565    }
8566
8567    std::cout << " -> tests passed" << std::endl;
8568  }
8569
8570  void np_test_toString_matrix_identity() {
8571    std::cout << "========= Matrix::toString() identity matrix =======================";
8572
8573    numpy::Matrix<int> mat = numpy::Matrix<int>::eye(4);
eye (np_test_1_all.cpp:23980)
23970      // Test geomspace
23971      auto geomspace_result = geomspace<double>(1.0, 16.0, 5);
23972      if (!(geomspace_result.getShape()[0] == 5)) {
23973          std::string description = std::string("testArrayCreationSignatures():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(geomspace_result.getShape()[0] == 5)";
23974          std::cout << std::string("[FAIL] ") + description << std::endl;
23975          throw std::runtime_error(description);
23976      }
23977      // std::cout << "[OK] geomspace function has correct signature\n";
23978
23979      // Test eye with optional parameters
23980      auto eye_square = eye<double>(3);
23981      auto eye_rect = eye<double>(3, 4);
23982      auto eye_offset = eye<double>(3, 4, 1);
23983
23984      if (!((eye_square.getShape() == std::vector<size_t>{3, 3}))) {
23985          std::string description = std::string("testArrayCreationSignatures():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !((eye_square.getShape() == std::vector<size_t>{3, 3}))";
23986          std::cout << std::string("[FAIL] ") + description << std::endl;
23987          throw std::runtime_error(description);
23988      }
23989      if (!((eye_rect.getShape() == std::vector<size_t>{3, 4}))) {
23990          std::string description = std::string("testArrayCreationSignatures():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !((eye_rect.getShape() == std::vector<size_t>{3, 4}))";
ones (np_test_1_all.cpp:319)
309  //int_range.printArray();
310
311  auto reshaped = int_range.reshapeArray({ 3, 2 });
312  // std::cout << "Reshaped to 2x2 matrix:";
313  //reshaped.printArray();
314
315  auto zeros = createInt32Zeros({ 2, 3 });
316  // std::cout << "zeros (2,3):";
317  //zeros.printArray();
318  auto ones = createInt32Ones({ 2, 3 });
319  // std::cout << "ones (2,3):";
320  //ones.printArray();
321
322  // std::cout << "Addition of zeros and ones:" << std::endl;
323  auto sum = zeros.addArrays(ones);
324  //sum.printArray();
325
326  // std::cout << "Sum of all elements: " << sum.sumArray() << std::endl;
327  // std::cout << "Mean: " << sum.meanArray() << std::endl;
328
329  // std::cout << std::endl << "Type introspection with get_typename():" << std::endl;
zeros (np_test_1_all.cpp:316)
306  auto int_range = NDArray<int32>::createRange(1, 12, 2);
307  // std::cout << "Int32 range array (1 to 10, step 2):" << std::endl;
308  //int_range.printArray();
309
310  auto reshaped = int_range.reshapeArray({ 3, 2 });
311  // std::cout << "Reshaped to 2x2 matrix:";
312  //reshaped.printArray();
313
314  auto zeros = createInt32Zeros({ 2, 3 });
315  // std::cout << "zeros (2,3):";
316  //zeros.printArray();
317  auto ones = createInt32Ones({ 2, 3 });
318  // std::cout << "ones (2,3):";
319  //ones.printArray();
320
321  // std::cout << "Addition of zeros and ones:" << std::endl;
322  auto sum = zeros.addArrays(ones);
323  //sum.printArray();
324
325  // std::cout << "Sum of all elements: " << sum.sumArray() << std::endl;
transpose (np_test_2_all.cpp:4973)
4963    }
4964
4965    /**
4966     * Test matrix properties and methods
4967     */
4968    void testMatrixProperties() {
4969      std::cout << "========= testMatrixProperties =======================";
4970
4971      // Test transpose
4972      numpy::Matrix<double> m("1 2 3; 4 5 6");
4973      auto mt = m.transpose();
4974      assert_test(mt.rows() == 3, "Transpose rows");
4975      assert_test(mt.cols() == 2, "Transpose cols");
4976      assert_test(std::abs(mt(0, 1) - 4.0) < 1e-10, "Transpose element");
4977      assert_test(std::abs(mt(2, 0) - 3.0) < 1e-10, "Transpose element");
4978
4979      // Test trace for square matrix
4980      numpy::Matrix<double> square("1 2; 3 4");
4981      double tr = square.trace();
4982      assert_test(std::abs(tr - 5.0) < 1e-10, "Matrix trace");
det (np_test_2_all.cpp:4985)
4975      assert_test(mt.cols() == 2, "Transpose cols");
4976      assert_test(std::abs(mt(0, 1) - 4.0) < 1e-10, "Transpose element");
4977      assert_test(std::abs(mt(2, 0) - 3.0) < 1e-10, "Transpose element");
4978
4979      // Test trace for square matrix
4980      numpy::Matrix<double> square("1 2; 3 4");
4981      double tr = square.trace();
4982      assert_test(std::abs(tr - 5.0) < 1e-10, "Matrix trace");
4983
4984      // Test determinant for 2x2 matrix
4985      double det = square.det();
4986      assert_test(std::abs(det - (-2.0)) < 1e-10, "Matrix determinant 2x2");
4987
4988      // Test matrix inverse for 2x2
4989      auto inv = square.inv();
4990      assert_test(std::abs(inv(0, 0) - (-2.0)) < 1e-10, "Matrix inverse 0,0");
4991      assert_test(std::abs(inv(0, 1) - 1.0) < 1e-10, "Matrix inverse 0,1");
4992      assert_test(std::abs(inv(1, 0) - 1.5) < 1e-10, "Matrix inverse 1,0");
4993      assert_test(std::abs(inv(1, 1) - (-0.5)) < 1e-10, "Matrix inverse 1,1");
4994
4995      // Verify A * A^-1 = I
inv (np_test_2_all.cpp:4989)
4979      // Test trace for square matrix
4980      numpy::Matrix<double> square("1 2; 3 4");
4981      double tr = square.trace();
4982      assert_test(std::abs(tr - 5.0) < 1e-10, "Matrix trace");
4983
4984      // Test determinant for 2x2 matrix
4985      double det = square.det();
4986      assert_test(std::abs(det - (-2.0)) < 1e-10, "Matrix determinant 2x2");
4987
4988      // Test matrix inverse for 2x2
4989      auto inv = square.inv();
4990      assert_test(std::abs(inv(0, 0) - (-2.0)) < 1e-10, "Matrix inverse 0,0");
4991      assert_test(std::abs(inv(0, 1) - 1.0) < 1e-10, "Matrix inverse 0,1");
4992      assert_test(std::abs(inv(1, 0) - 1.5) < 1e-10, "Matrix inverse 1,0");
4993      assert_test(std::abs(inv(1, 1) - (-0.5)) < 1e-10, "Matrix inverse 1,1");
4994
4995      // Verify A * A^-1 = I
4996      auto identity_check = square * inv;
4997      assert_test(std::abs(identity_check(0, 0) - 1.0) < 1e-10, "Inverse verification diagonal");
4998      assert_test(std::abs(identity_check(1, 1) - 1.0) < 1e-10, "Inverse verification diagonal");
4999      assert_test(std::abs(identity_check(0, 1)) < 1e-10, "Inverse verification off-diagonal");
matmul (np_test_1_all.cpp:15423)
15413    // Verify reconstruction: A = U * S * Vt
15414    // First create diagonal matrix from S
15415    NDArray<double> S_diag({ 2, 2 });
15416    for (size_t i = 0; i < 2; ++i) {
15417      for (size_t j = 0; j < 2; ++j) {
15418        S_diag.setElementAt({ i, j }, (i == j) ? svd_result.S.getElementAt({ i }) : 0.0);
15419      }
15420    }
15421
15422    auto US = matmul(svd_result.U, S_diag);
15423    auto reconstructed = matmul(US, svd_result.Vt);
15424
15425    // std::cout << "Reconstructed matrix (U * S * Vt):" << std::endl;
15426    //reconstructed.printArray();
15427
15428    // Check reconstruction error
15429    double max_error = 0.0;
15430    for (size_t i = 0; i < 3; ++i) {
15431      for (size_t j = 0; j < 2; ++j) {
15432        double error = std::abs(matrix.getElementAt({ i, j }) - reconstructed.getElementAt({ i, j }));
pinv (np_test_1_all.cpp:15553)
15543    matrix.setElementAt({ 0, 0 }, 1.0);
15544    matrix.setElementAt({ 0, 1 }, 2.0);
15545    matrix.setElementAt({ 1, 0 }, 2.0);
15546    matrix.setElementAt({ 1, 1 }, 4.0);
15547    matrix.setElementAt({ 2, 0 }, 3.0);
15548    matrix.setElementAt({ 2, 1 }, 6.0);
15549
15550    // std::cout << "Original matrix (rank-deficient):" << std::endl;
15551    //matrix.printArray();
15552
15553    auto pseudoinv = pinv(matrix);
15554
15555    // std::cout << "Pseudoinverse:" << std::endl;
15556    //pseudoinv.printArray();
15557
15558    // Test Moore-Penrose conditions
15559    // 1. A * A^+ * A = A
15560    auto AApA = matmul(matmul(matrix, pseudoinv), matrix);
15561
15562    // std::cout << "A * A^+ * A (should equal A):" << std::endl;
15563    //AApA.printArray();
trace (np_test_2_all.cpp:4981)
4971      // Test transpose
4972      numpy::Matrix<double> m("1 2 3; 4 5 6");
4973      auto mt = m.transpose();
4974      assert_test(mt.rows() == 3, "Transpose rows");
4975      assert_test(mt.cols() == 2, "Transpose cols");
4976      assert_test(std::abs(mt(0, 1) - 4.0) < 1e-10, "Transpose element");
4977      assert_test(std::abs(mt(2, 0) - 3.0) < 1e-10, "Transpose element");
4978
4979      // Test trace for square matrix
4980      numpy::Matrix<double> square("1 2; 3 4");
4981      double tr = square.trace();
4982      assert_test(std::abs(tr - 5.0) < 1e-10, "Matrix trace");
4983
4984      // Test determinant for 2x2 matrix
4985      double det = square.det();
4986      assert_test(std::abs(det - (-2.0)) < 1e-10, "Matrix determinant 2x2");
4987
4988      // Test matrix inverse for 2x2
4989      auto inv = square.inv();
4990      assert_test(std::abs(inv(0, 0) - (-2.0)) < 1e-10, "Matrix inverse 0,0");
4991      assert_test(std::abs(inv(0, 1) - 1.0) < 1e-10, "Matrix inverse 0,1");
H (np_test_1_all.cpp:20194)
20184      const SchurDecomposition<T>& schur) {
20185      ValidationResult result;
20186      result.passed = false;
20187      result.max_error = 0.0;
20188      result.avg_error = 0.0;
20189
20190      try {
20191        // Compute Q * T
20192        auto QT = matmul(schur.Q, schur.T_matrix);
20193
20194        // Compute Q^H (conjugate transpose)
20195        NDArray<T> QH = schur.Q.transposeArray();  // Start with transpose
20196        if constexpr (utils::is_complex_v<T>) {
20197          QH = utils::conjugate_transpose(schur.Q);  // Override with conjugate transpose if complex
20198        }
20199
20200        // Compute reconstructed matrix: Q * T * Q^H
20201        auto reconstructed = matmul(QT, QH);
20202
20203        // Calculate error
20204        double total_error = 0.0;
I (np_test_1_all.cpp:24644)
24634        throw std::runtime_error("np_test_eigh_3x3_diagonal failed");
24635      }
24636
24637      std::cout << " -> tests passed" << std::endl;
24638    }
24639
24640    void np_test_eigh_identity() {
24641      std::cout << "========= eigh: identity matrix =======================";
24642
24643      // Create 3x3 identity matrix
24644      numpy::NDArray<double> I({ 3, 3 });
24645      for (size_t i = 0; i < 3; ++i) {
24646        for (size_t j = 0; j < 3; ++j) {
24647          I.setElementAt({ i, j }, (i == j) ? 1.0 : 0.0);
24648        }
24649      }
24650
24651      auto result = numpy::linalg::eigh(I, true);
24652
24653      print_vector(result.eigenvalues, "Eigenvalues");
cols (np_test_2_all.cpp:4911)
4901    /**
4902     * Test basic matrix construction and properties
4903     */
4904    void testMatrixBasics() {
4905      std::cout << "========= testMatrixBasics =======================";
4906
4907      // Test construction from dimensions
4908      numpy::Matrix<double> m1(3, 3);
4909      assert_test(m1.rows() == 3, "Matrix rows");
4910      assert_test(m1.cols() == 3, "Matrix cols");
4911      assert_test(m1.isSquare(), "Matrix is square");
4912
4913      // Test construction from 2D vector
4914      std::vector<std::vector<int>> data = { {1, 2, 3}, {4, 5, 6} };
4915      numpy::Matrix<int> m2(data);
4916      assert_test(m2.rows() == 2, "Matrix from vector rows");
4917      assert_test(m2.cols() == 3, "Matrix from vector cols");
4918      assert_test(m2(0, 0) == 1, "Matrix element access");
4919      assert_test(m2(1, 2) == 6, "Matrix element access");
isSquare (np_test_2_all.cpp:4912)
4902    /**
4903     * Test basic matrix construction and properties
4904     */
4905    void testMatrixBasics() {
4906      std::cout << "========= testMatrixBasics =======================";
4907
4908      // Test construction from dimensions
4909      numpy::Matrix<double> m1(3, 3);
4910      assert_test(m1.rows() == 3, "Matrix rows");
4911      assert_test(m1.cols() == 3, "Matrix cols");
4912      assert_test(m1.isSquare(), "Matrix is square");
4913
4914      // Test construction from 2D vector
4915      std::vector<std::vector<int>> data = { {1, 2, 3}, {4, 5, 6} };
4916      numpy::Matrix<int> m2(data);
4917      assert_test(m2.rows() == 2, "Matrix from vector rows");
4918      assert_test(m2.cols() == 3, "Matrix from vector cols");
4919      assert_test(m2(0, 0) == 1, "Matrix element access");
4920      assert_test(m2(1, 2) == 6, "Matrix element access");
4921
4922      // Test MATLAB-style string construction
print (np_test_1_all.cpp:6395)
6385    std::vector<std::string> strings = {"Alice", "Bob", "Charlie"};
6386    auto arr2 = array<32>(strings);
6387    // std::cout << "Created from strings vector:" << std::endl;
6388    for (size_t i = 0; i < arr2.size(); ++i) {
6389        // std::cout << "arr2[" << i << "] = '" << arr2[i] << "'";
6390    }
6391
6392    // Test 2D array creation
6393    chararray16 arr_2d({2, 3}, "test");
6394    // std::cout << "Created 2D chararray16 with shape {2, 3}:";
6395    // arr_2d.print();
6396
6397    std::cout << " -> tests passed" << std::endl;
6398}
6399
6400void testCharArrayStringOperationsCharArray() {
6401    std::cout << "========= testStringOperations =======================";
6402
6403    // Test string concatenation
6404    std::vector<std::string> words1 = {"Hello", "Good", "Nice"};
6405    std::vector<std::string> words2 = {" World", " Day", " Work"};
rows (np_test_2_all.cpp:4910)
4900  namespace test_matrix {
4901
4902    /**
4903     * Test basic matrix construction and properties
4904     */
4905    void testMatrixBasics() {
4906      std::cout << "========= testMatrixBasics =======================";
4907
4908      // Test construction from dimensions
4909      numpy::Matrix<double> m1(3, 3);
4910      assert_test(m1.rows() == 3, "Matrix rows");
4911      assert_test(m1.cols() == 3, "Matrix cols");
4912      assert_test(m1.isSquare(), "Matrix is square");
4913
4914      // Test construction from 2D vector
4915      std::vector<std::vector<int>> data = { {1, 2, 3}, {4, 5, 6} };
4916      numpy::Matrix<int> m2(data);
4917      assert_test(m2.rows() == 2, "Matrix from vector rows");
4918      assert_test(m2.cols() == 3, "Matrix from vector cols");
4919      assert_test(m2(0, 0) == 1, "Matrix element access");
4920      assert_test(m2(1, 2) == 6, "Matrix element access");
setElement (np_test_5_all.cpp:8553)
8543  // ===========================
8544
8545#endif  // End of RecordArray tests
8546
8547  void np_test_toString_matrix_basic() {
8548    std::cout << "========= Matrix::toString() basic =======================";
8549
8550    numpy::Matrix<double> mat(3, 3);
8551    for (size_t i = 0; i < 3; ++i) {
8552      for (size_t j = 0; j < 3; ++j) {
8553        mat.setElement(i, j, static_cast<double>(i * 3 + j));
8554      }
8555    }
8556
8557    std::string result = mat.toString();
8558
8559    // std::cout << "Result:\n" << result << std::endl;
8560
8561    verify_not_empty(result, "Matrix toString()");
8562
8563    if (!verify_contains(result, "Matrix(3x3)", "Matrix")) {
size (np_test_1_all.cpp:47)
37using namespace numpy;
38using namespace numpy::benchmark;
39using namespace numpy::char_;
40
41// Helper functions for array comparison tests
42namespace {
43    const double TOLERANCE = 1e-10;
44
45    bool allTrue(const NDArray<bool>& arr) {
46        std::vector<size_t> indices(arr.getShape().size(), 0);
47        do {
48            if (!arr.getElementAt(indices)) {
49                return false;
50            }
51        } while (incrementIndices(indices, arr.getShape()));
52        return true;
53    }
54
55    bool allFalse(const NDArray<bool>& arr) {
56        std::vector<size_t> indices(arr.getShape().size(), 0);
toString (np_test_1_all.cpp:6826)
6816void testDatetime64CreationDateTime() {
6817    std::cout << "========= testDatetime64CreationDateTime =======================";
6818
6819    // Test default constructor
6820    datetime64 default_dt;
6821    if (!(default_dt.isNaT())) {
6822        std::string description = std::string("testDatetime64CreationDateTime():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(default_dt.isNaT())";
6823        std::cout << std::string("[FAIL] ") + description << std::endl;
6824        throw std::runtime_error(description);
6825    }
6826    // std::cout << "Default datetime64 is NaT: " << default_dt.toString() << std::endl;
6827
6828    // Test value constructor
6829    datetime64 epoch_day(0, DateTimeUnit::Day);
6830    // std::cout << "Epoch day: " << epoch_day.toString() << std::endl;
6831
6832    // Test string constructor
6833    datetime64 date_from_string("2024-01-15");
6834    // std::cout << "Date from string '2024-01-15': " << date_from_string.toString() << std::endl;
6835
6836    datetime64 datetime_from_string("2024-01-15T10:30:45");