CategoricalArray ================ .. cpp:class:: numpy::CategoricalArray numpy C++ class. Example ------- .. code-block:: cpp #include using namespace numpy; // Use CategoricalArray CategoricalArray obj; // ... operations ... Constructors ------------ .. list-table:: :widths: 55 25 20 :header-rows: 1 * - Signature - Location - Example * - ``CategoricalArray(const numpy::NDArray& codes, const std::vector& categories, bool ordered = false)`` - df_categorical_array.h:91 - * - ``explicit CategoricalArray(const std::vector>& values, bool ordered = false)`` - df_categorical_array.h:106 - * - ``CategoricalArray(const std::vector>& values, const std::vector& categories, bool ordered = false)`` - df_categorical_array.h:137 - Construction ------------ .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``static CategoricalArray from_codes( const std::vector& codes, const std::vector& categories, bool ordered = false)`` - static CategoricalArray - df_categorical_array.h:176 - * - ``static CategoricalArray from_sequence( const std::vector>& values, bool ordered = false)`` - static CategoricalArray - df_categorical_array.h:199 - Array Creation -------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``bool empty() const`` - bool - df_categorical_array.h:286 - :ref:`View ` Indexing / Selection -------------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``numpy::int32 get_code(size_t index) const`` - numpy::int32 - df_categorical_array.h:351 - * - ``size_t searchsorted(const std::string& value, const std::string& side = "left") const`` - size_t - df_categorical_array.h:1612 - :ref:`View ` * - ``CategoricalArray take(const std::vector& indices, bool allow_fill = false, const std::string& fill_value = "") const`` - CategoricalArray - df_categorical_array.h:1051 - :ref:`View ` Shape Manipulation ------------------ .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``CategoricalArray T() const`` - CategoricalArray - df_categorical_array.h:1793 - :ref:`View ` * - ``CategoricalArray ravel() const`` - CategoricalArray - df_categorical_array.h:1535 - :ref:`View ` * - ``CategoricalArray reshape(const std::vector& new_shape) const`` - CategoricalArray - df_categorical_array.h:1592 - :ref:`View ` * - ``CategoricalArray swapaxes(int axis1, int axis2) const`` - CategoricalArray - df_categorical_array.h:1731 - :ref:`View ` * - ``CategoricalArray transpose() const`` - CategoricalArray - df_categorical_array.h:1786 - :ref:`View ` Statistics ---------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``std::optional max() const`` - std::optional - df_categorical_array.h:703 - :ref:`View ` * - ``std::optional min() const`` - std::optional - df_categorical_array.h:679 - :ref:`View ` Sorting ------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``numpy::NDArray argsort(bool ascending = true, const std::string& na_position = "last") const`` - numpy::NDArray - df_categorical_array.h:956 - :ref:`View ` * - ``CategoricalArray sort_values(bool ascending = true, const std::string& na_position = "last") const`` - CategoricalArray - df_categorical_array.h:1706 - Math Operations --------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``CategoricalArray add_categories(const std::vector& new_cats) const`` - CategoricalArray - df_categorical_array.h:463 - Comparison ---------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``bool equals(const CategoricalArray& other) const`` - bool - df_categorical_array.h:1317 - Set Operations -------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``numpy::NDArray isin(const std::vector& values) const`` - numpy::NDArray - df_categorical_array.h:1417 - :ref:`View ` * - ``CategoricalArray unique() const`` - CategoricalArray - df_categorical_array.h:727 - :ref:`View ` I/O --- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``std::vector> to_list() const`` - std::vector> - df_categorical_array.h:1742 - * - ``numpy::NDArray to_numpy(const std::string& dtype = "int", bool copy_data = true) const`` - numpy::NDArray - df_categorical_array.h:1771 - :ref:`View ` * - ``std::string to_string() const`` - std::string - df_categorical_array.h:1816 - :ref:`View ` * - ``std::vector> tolist() const`` - std::vector> - df_categorical_array.h:1761 - :ref:`View ` Joining / Splitting ------------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``CategoricalArray delete\_(size_t loc) const`` - CategoricalArray - df_categorical_array.h:1181 - :ref:`View ` * - ``CategoricalArray delete\_(const std::vector& locs) const`` - CategoricalArray - df_categorical_array.h:1203 - :ref:`View ` * - ``CategoricalArray insert(size_t index, const std::optional& value) const`` - CategoricalArray - df_categorical_array.h:1336 - :ref:`View ` * - ``CategoricalArray repeat(size_t repeats) const`` - CategoricalArray - df_categorical_array.h:1544 - :ref:`View ` * - ``CategoricalArray repeat(const std::vector& repeats) const`` - CategoricalArray - df_categorical_array.h:1563 - :ref:`View ` Type Handling ------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``std::vector> astype(const std::string& dtype) const`` - std::vector> - df_categorical_array.h:1109 - :ref:`View ` * - ``numpy::NDArray astype_codes() const`` - numpy::NDArray - df_categorical_array.h:1161 - * - ``CategoricalArray copy() const`` - CategoricalArray - df_categorical_array.h:1044 - :ref:`View ` * - ``CategoricalArray view() const`` - CategoricalArray - df_categorical_array.h:1805 - :ref:`View ` Type Checking ------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``bool is_na(size_t index) const`` - bool - df_categorical_array.h:361 - Other Methods ------------- .. list-table:: :widths: 40 20 15 25 :header-rows: 1 * - Signature - Return Type - Location - Example * - ``std::optional argmax() const`` - std::optional - df_categorical_array.h:1016 - :ref:`View ` * - ``std::optional argmin() const`` - std::optional - df_categorical_array.h:992 - :ref:`View ` * - ``CategoricalArray as_ordered() const`` - CategoricalArray - df_categorical_array.h:661 - * - ``CategoricalArray as_unordered() const`` - CategoricalArray - df_categorical_array.h:668 - * - ``std::unordered_map build_category_map() const`` - std::unordered_map - df_categorical_array.h:48 - * - ``const std::vector& categories() const`` - const std::vector& - df_categorical_array.h:319 - * - ``void check_for_ordered(const std::string& op) const`` - void - df_categorical_array.h:1170 - * - ``check_for_ordered("searchsorted")`` - - df_categorical_array.h:1613 - * - ``check_for_ordered("sort_values")`` - - df_categorical_array.h:1708 - * - ``const numpy::NDArray& codes() const`` - const numpy::NDArray& - df_categorical_array.h:300 - * - ``numpy::NDArray codes_arr(std::vector`` - numpy::NDArray - df_categorical_array.h:188 - * - ``std::vector codes_vector() const`` - std::vector - df_categorical_array.h:307 - * - ``static CategoricalArray concat(const std::vector& arrays)`` - static CategoricalArray - df_categorical_array.h:209 - * - ``size_t count() const`` - size_t - df_categorical_array.h:434 - :ref:`View ` * - ``std::map describe() const`` - std::map - df_categorical_array.h:1222 - :ref:`View ` * - ``CategoricalArray dropna() const`` - CategoricalArray - df_categorical_array.h:420 - * - ``CategoricalDtype dtype() const`` - CategoricalDtype - df_categorical_array.h:247 - :ref:`View ` * - ``numpy::NDArray duplicated(const std::string& keep = "first") const`` - numpy::NDArray - df_categorical_array.h:1259 - * - ``std::pair, CategoricalArray> factorize() const`` - std::pair, CategoricalArray> - df_categorical_array.h:745 - * - ``CategoricalArray fillna(const std::string& value) const`` - CategoricalArray - df_categorical_array.h:397 - * - ``bool has_na() const`` - bool - df_categorical_array.h:447 - * - ``CategoricalArray interpolate(const std::string& method = "pad") const`` - CategoricalArray - df_categorical_array.h:1375 - * - ``numpy::NDArray isna() const`` - numpy::NDArray - df_categorical_array.h:375 - * - ``numpy::NDArray isnull() const`` - numpy::NDArray - df_categorical_array.h:1445 - * - ``size_t len() const`` - size_t - df_categorical_array.h:293 - * - ``CategoricalArray map(const std::unordered_map& mapping) const`` - CategoricalArray - df_categorical_array.h:1454 - * - ``CategoricalArray map(Func func) const`` - CategoricalArray - df_categorical_array.h:1495 - * - ``size_t memory_usage(bool deep = false) const`` - size_t - df_categorical_array.h:1508 - * - ``size_t nbytes() const`` - size_t - df_categorical_array.h:261 - :ref:`View ` * - ``constexpr int ndim() const`` - constexpr int - df_categorical_array.h:272 - :ref:`View ` * - ``numpy::NDArray notna() const`` - numpy::NDArray - df_categorical_array.h:386 - * - ``numpy::NDArray notnull() const`` - numpy::NDArray - df_categorical_array.h:1527 - * - ``bool ordered() const`` - bool - df_categorical_array.h:326 - :ref:`View ` * - ``CategoricalArray remove_categories(const std::vector& removals) const`` - CategoricalArray - df_categorical_array.h:480 - * - ``CategoricalArray remove_unused_categories() const`` - CategoricalArray - df_categorical_array.h:619 - * - ``CategoricalArray rename_categories(const std::vector& new_names) const`` - CategoricalArray - df_categorical_array.h:559 - * - ``CategoricalArray rename_categories(const std::unordered_map& mapping) const`` - CategoricalArray - df_categorical_array.h:569 - * - ``CategoricalArray reorder_categories(const std::vector& new_order) const`` - CategoricalArray - df_categorical_array.h:583 - * - ``std::string repr() const`` - std::string - df_categorical_array.h:1842 - * - ``CategoricalArray set_categories(const std::vector& new_cats, bool rename = false) const`` - CategoricalArray - df_categorical_array.h:522 - * - ``CategoricalArray set_ordered(bool value) const`` - CategoricalArray - df_categorical_array.h:1660 - * - ``std::vector shape() const`` - std::vector - df_categorical_array.h:279 - :ref:`View ` * - ``CategoricalArray shift(int64_t periods = 1, const std::optional& fill_value = std::nullopt) const`` - CategoricalArray - df_categorical_array.h:1670 - :ref:`View ` * - ``size_t size() const`` - size_t - df_categorical_array.h:254 - :ref:`View ` * - ``CategoricalArray slice(size_t start, size_t stop, size_t step = 1) const`` - CategoricalArray - df_categorical_array.h:1086 - :ref:`View ` * - ``void validate_codes() const`` - void - df_categorical_array.h:59 - * - ``std::pair, std::vector> value_counts() const`` - std::pair, std::vector> - df_categorical_array.h:775 - Code Examples ------------- The following examples are extracted from the test suite. .. _example-categoricalarray-empty-0: .. dropdown:: empty (np_test_1_all.cpp:6316) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 6306 :emphasize-lines: 11 } void test_data_generator_emptyBenchmarkSorting() { std::cout << "========= test_data_generator_empty ======================="; DataGenerator gen(42); // Test empty data generation std::vector data = gen.generate(0, DataPattern::RANDOM); if (!(data.empty())) { std::string description = std::string("test_data_generator_emptyBenchmarkSorting():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(data.empty())"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } // std::cout << "Empty data generation test passed" << std::endl; std::cout << " -> tests passed" << std::endl; } .. _example-categoricalarray-searchsorted-1: .. dropdown:: searchsorted (np_test_2_all.cpp:8204) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 8194 :emphasize-lines: 11 // Test missing NumPy functions void test_numpy_functions() { std::cout << "========= NumPy Functions Test =========================="; // Test searchsorted { std::vector sorted_arr = { 1, 3, 5, 7, 9 }; std::vector values = { 2, 6, 8 }; auto result = numpy::searchsorted(sorted_arr, values, "left"); std::vector expected = { 1, 3, 4 }; if (result != expected) { std::cout << " searchsorted (left): -> [FAIL]"; throw std::runtime_error("searchsorted (left): FAILED - incorrect result indices"); } // std::cout << "[OK] searchsorted (left): PASSED" << std::endl; auto result_right = numpy::searchsorted(sorted_arr, values, "right"); std::vector expected_right = { 1, 3, 4 }; .. _example-categoricalarray-take-2: .. dropdown:: take (np_test_5_all.cpp:4313) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 4303 :emphasize-lines: 11 for (size_t i = 0; i < 6; ++i) { arr.setElementAt({ i }, static_cast(i * 10)); // [0, 10, 20, 30, 40, 50] } // Take specific indices numpy::NDArray indices({ 3 }); indices.setElementAt({ 0 }, 5); // 50 indices.setElementAt({ 1 }, 2); // 20 indices.setElementAt({ 2 }, 0); // 0 auto result = numpy::take(arr, indices); if (result.getSize() != 3) { std::cout << " [FAIL] : in np_test_take_basic() : Wrong result size"; throw std::runtime_error("Test failed"); } if (result.getElementAt({ 0 }) != 50 || result.getElementAt({ 1 }) != 20 || result.getElementAt({ 2 }) != 0) { std::cout << " [FAIL] : in np_test_take_basic() : Wrong values extracted"; throw std::runtime_error("Test failed"); } .. _example-categoricalarray-t-3: .. dropdown:: T (np_test_1_all.cpp:20062) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 20052 :emphasize-lines: 11 std::mt19937 gen; public: MatrixGenerator(unsigned seed = 12345) : gen(seed) {} // Generate real matrix with known real eigenvalues NDArray real_matrix_real_eigenvalues(size_t n) { // Create diagonal matrix with known eigenvalues NDArray D = NDArray::createZeros({ n, n }); for (size_t i = 0; i < n; ++i) { D.setElementAt({ i, i }, T(i + 1)); // Eigenvalues 1, 2, 3, ... } // Create random orthogonal transformation auto Q = random_orthogonal_matrix(n); auto QT = Q.transposeArray(); // A = Q * D * Q^T return matmul(matmul(Q, D), QT); } .. _example-categoricalarray-ravel-4: .. dropdown:: ravel (np_test_1_all.cpp:4082) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 4072 :emphasize-lines: 11 std::cout << "Testing ravel function...\n"; // Test with 2-D array auto arr_2d = createFloat64Array({ 2, 3 }); for (size_t i = 0; i < 2; ++i) { for (size_t j = 0; j < 3; ++j) { arr_2d.setElementAt({ i, j }, static_cast(i * 3 + j)); } } auto raveled = ravel(arr_2d); if (!(raveled.getShape() == std::vector({ 6 }))) { std::string description = std::string("testRavelFunction():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(raveled.getShape() == std::vector({ 6 }))"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } for (size_t i = 0; i < 6; ++i) { if (!(isApproxEqualExt(raveled.getElementAt({ i }), static_cast(i)))) { std::string description = std::string("testRavelFunction():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(isApproxEqualExt(raveled.getElementAt({ i }), static_cast(i)))"; std::cout << std::string("[FAIL] ") + description << std::endl; .. _example-categoricalarray-reshape-5: .. dropdown:: reshape (np_test_1_all.cpp:5391) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 5381 :emphasize-lines: 11 std::cout << "========= testInvalidReshapeExtended ======================="; auto array = createInt32Array({2, 3}, 42); // Size = 6 // std::cout << "Original array (2x3, size=6):" << std::endl; //array.printArray(); // Valid reshape try { auto reshaped = array.reshapeArray({3, 2}); // Size = 6, OK // std::cout << "[OK] Valid reshape (3x2) works"; } catch (const std::exception& e) { std::cout << " [FAIL] : in testInvalidReshapeExtended(): Unexpected error in valid reshape: " << e.what(); throw std::runtime_error("testInvalidReshapeExtended(): Unexpected error in valid reshape: " + std::string(e.what())); } // Invalid reshape - wrong total size try { auto reshaped = array.reshapeArray({2, 2}); // Size = 4, should fail std::cout << "[FAIL] Invalid reshape should have thrown"; } catch (const std::invalid_argument& e) { .. _example-categoricalarray-swapaxes-6: .. dropdown:: swapaxes (np_test_2_all.cpp:3707) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 3697 :emphasize-lines: 11 std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } if (!(isApproxEqualMCO(rolled.getElementAt({ 0, 0 }), arr.getElementAt({ 0, 3 })))) { std::string description = std::string("testRotationFlipOperations():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(isApproxEqualMCO(rolled.getElementAt({ 0, 0 }), arr.getElementAt({ 0, 3 })))"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } // Test swapaxes auto swapped = swapaxes(arr, 0, 1); if (!(swapped.getShape() == std::vector({ 4, 3 }))) { std::string description = std::string("testRotationFlipOperations():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(swapped.getShape() == std::vector({ 4, 3 }))"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } if (!(isApproxEqualMCO(swapped.getElementAt({ 0, 0 }), arr.getElementAt({ 0, 0 })))) { std::string description = std::string("testRotationFlipOperations():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(isApproxEqualMCO(swapped.getElementAt({ 0, 0 }), arr.getElementAt({ 0, 0 })))"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } .. _example-categoricalarray-transpose-7: .. dropdown:: transpose (np_test_2_all.cpp:4973) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 4963 :emphasize-lines: 11 } /** * Test matrix properties and methods */ void testMatrixProperties() { std::cout << "========= testMatrixProperties ======================="; // Test transpose numpy::Matrix m("1 2 3; 4 5 6"); auto mt = m.transpose(); assert_test(mt.rows() == 3, "Transpose rows"); assert_test(mt.cols() == 2, "Transpose cols"); assert_test(std::abs(mt(0, 1) - 4.0) < 1e-10, "Transpose element"); assert_test(std::abs(mt(2, 0) - 3.0) < 1e-10, "Transpose element"); // Test trace for square matrix numpy::Matrix square("1 2; 3 4"); double tr = square.trace(); assert_test(std::abs(tr - 5.0) < 1e-10, "Matrix trace"); .. _example-categoricalarray-max-8: .. dropdown:: max (np_test_1_all.cpp:7274) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 7264 :emphasize-lines: 11 if (sizeof(uintp) == sizeof(void*)) { // std::cout << " -> uintp size matches pointer size"; } else { // std::cout << " ✗ uintp size doesn't match pointer size" << std::endl; } // Test range limits // std::cout << "Range Information:" << std::endl; // std::cout << " intp min: " << std::numeric_limits::min() << std::endl; // std::cout << " intp max: " << std::numeric_limits::max() << std::endl; // std::cout << " uintp max: " << std::numeric_limits::max() << std::endl; // std::cout << " longdouble digits: " << std::numeric_limits::digits << std::endl; std::cout << " -> tests passed" << std::endl; } void testComplexArithmeticExtendedTypes() { std::cout << "========= testComplexArithmeticExtendedTypes ======================="; clongdouble c1(3.0L, 4.0L); // 3 + 4i .. _example-categoricalarray-min-9: .. dropdown:: min (np_test_1_all.cpp:2350) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 2340 :emphasize-lines: 11 if (i % 3 == 0) { large_array.setElementAt({i}, object_(static_cast(i))); } else if (i % 3 == 1) { large_array.setElementAt({i}, object_(static_cast(i) * 0.5)); } else { large_array.setElementAt({i}, object_(std::string("str") + std::to_string(i))); } } // Verify pattern for (size_t i = 0; i < std::min(large_size, size_t(100)); ++i) { // Check first 100 object_ obj = large_array.getElementAt({i}); if (i % 3 == 0) { if (!(obj.is_type())) { std::string description = std::string("testArrayEdgeCases():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(obj.is_type())"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } } else if (i % 3 == 1) { if (!(obj.is_type())) { std::string description = std::string("unknown_function():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(obj.is_type())"; .. _example-categoricalarray-argsort-10: .. dropdown:: argsort (np_test_1_all.cpp:16841) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 16831 :emphasize-lines: 11 std::cout << "========= test_argsort ======================="; // Test 1D array argsort NDArray arr1d({ 5 }); arr1d.setElementAt({ 0 }, 30); // index 0 arr1d.setElementAt({ 1 }, 10); // index 1 arr1d.setElementAt({ 2 }, 40); // index 2 arr1d.setElementAt({ 3 }, 20); // index 3 arr1d.setElementAt({ 4 }, 50); // index 4 auto indices = argsort(arr1d); // Expected order: 10(idx1), 20(idx3), 30(idx0), 40(idx2), 50(idx4) if (!(indices.getElementAt({ 0 }) == 1)) { std::string description = std::string("test_argsort():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(indices.getElementAt({ 0 }) == 1)"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } if (!(indices.getElementAt({ 1 }) == 3)) { std::string description = std::string("test_argsort():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(indices.getElementAt({ 1 }) == 3)"; std::cout << std::string("[FAIL] ") + description << std::endl; .. _example-categoricalarray-isin-11: .. dropdown:: isin (np_test_1_all.cpp:19434) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 19424 :emphasize-lines: 11 std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } if (!(membership.getElementAt({ 5 }) == false)) { std::string description = std::string("testMembershipOperations():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(membership.getElementAt({ 5 }) == false)"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } // std::cout << "[OK] Membership testing (in1d) works correctly\n"; // Test isin (alias for in1d) auto isin_result = isin(test_array, test_values); // Should be identical to in1d result for (size_t i = 0; i < membership.getSize(); ++i) { if (!(isin_result.getElementAt({ i }) == membership.getElementAt({ i }))) { std::string description = std::string("testMembershipOperations():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(isin_result.getElementAt({ i }) == membership.getElementAt({ i }))"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } } .. _example-categoricalarray-unique-12: .. dropdown:: unique (np_test_1_all.cpp:6259) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 6249 :emphasize-lines: 11 if (!(data.size() == 100)) { std::string description = std::string("test_data_generator_few_uniqueBenchmarkSorting():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(data.size() == 100)"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } // Count unique values std::vector sorted_copy = data; std::sort(sorted_copy.begin(), sorted_copy.end()); auto unique_end = std::unique(sorted_copy.begin(), sorted_copy.end()); size_t unique_count = std::distance(sorted_copy.begin(), unique_end); // Should have significantly fewer unique values than total elements if (!(unique_count < data.size() / 2)) { std::string description = std::string("test_data_generator_few_uniqueBenchmarkSorting():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(unique_count < data.size() / 2)"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } // std::cout << "Few unique data generation test passed. Unique values: " << unique_count << std::endl; .. _example-categoricalarray-to_numpy-13: .. dropdown:: to_numpy (np_test_5_all.cpp:21373) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 21363 :emphasize-lines: 11 if (errors == 0) { std::cout << "np_test_timedelta_components -> tests passed" << std::endl; } return errors; } // ============================================================================= // Test 4: Total Conversion Properties // ============================================================================= int np_test_timedelta_total_conversions() { int errors = 0; numpy::Timedelta td(1, 12, 0); // 1 day 12 hours = 1.5 days = 36 hours // total_seconds { double secs = td.total_seconds(); double expected = (24 + 12) * 3600.0; if (std::abs(secs - expected) > 0.0001) { std::cout << "[FAIL] np_test_timedelta_total_conversions: total_seconds expected " << expected << ", got " << secs << std::endl; .. _example-categoricalarray-to_string-14: .. dropdown:: to_string (np_test_1_all.cpp:454) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 444 :emphasize-lines: 11 // Modify through different views view1.setElementAt({0, 0}, 100); view2.setElementAt({2, 1}, 200); // This is (1, 2) in original view3.setElementAt({0, 0}, 300); // This is (1, 1) in original // std::cout << "After modifications through multiple views:" << std::endl; //original.printArray(); // Verify all changes are reflected if (!(original.getElementAt({0, 0}) == 100)) { std::string description = std::string("testAdvancedViewLifecycle():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(original.getElementAt({0, 0}) == 100)"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } if (!(original.getElementAt({1, 2}) == 200)) { std::string description = std::string("testAdvancedViewLifecycle():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(original.getElementAt({1, 2}) == 200)"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } if (!(original.getElementAt({1, 1}) == 300)) { std::string description = std::string("testAdvancedViewLifecycle():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(original.getElementAt({1, 1}) == 300)"; .. _example-categoricalarray-tolist-15: .. dropdown:: tolist (np_test_4_all.cpp:20046) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 20036 :emphasize-lines: 11 } // namespace numpy_tests /** * @file np_test_phase6.cpp * @brief Test suite for Phase 6A - HIGH PRIORITY NDArray methods and masked array utilities * * Tests: * - ndarray.nonzero() - Return indices of non-zero elements * - ndarray.tobytes() - Convert to bytes representation * - ndarray.tolist() - Convert to nested list string * - ndarray.fill() - Fill with scalar value (in-place) * - ndarray.item() - Get single element as scalar * - ndarray.itemset() - Set single element value * - ma.masked_all_like() - Create masked array with all elements masked * * Created: 2025-10-28 * Status: Phase 6A Implementation - HIGH PRIORITY functions */ #include "../numpy/np_ndarray.h" .. _example-categoricalarray-delete_-16: .. dropdown:: delete_ (np_test_4_all.cpp:18411) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 18401 :emphasize-lines: 11 } // ============================================================================ // SPRINT 1.2: ESSENTIAL OPERATIONS TESTS // ============================================================================ void np_test_phase1_delete() { std::cout << "========= delete_: element deletion ===="; auto arr = numpy::array({10, 20, 30, 40, 50}); auto result = numpy::delete_(arr, 2); // Delete index 2 (value 30) // Verify size reduced if (result.getSize() != 4) { std::cout << " [FAIL] : delete_ result size is " << result.getSize() << ", expected 4\n"; throw std::runtime_error("delete_ failed: wrong size"); } // Verify correct element was removed if (result.getElementAt({0}) != 10 || result.getElementAt({1}) != 20 || result.getElementAt({2}) != 40 || result.getElementAt({3}) != 50) { .. _example-categoricalarray-delete_-17: .. dropdown:: delete_ (np_test_4_all.cpp:18411) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 18401 :emphasize-lines: 11 } // ============================================================================ // SPRINT 1.2: ESSENTIAL OPERATIONS TESTS // ============================================================================ void np_test_phase1_delete() { std::cout << "========= delete_: element deletion ===="; auto arr = numpy::array({10, 20, 30, 40, 50}); auto result = numpy::delete_(arr, 2); // Delete index 2 (value 30) // Verify size reduced if (result.getSize() != 4) { std::cout << " [FAIL] : delete_ result size is " << result.getSize() << ", expected 4\n"; throw std::runtime_error("delete_ failed: wrong size"); } // Verify correct element was removed if (result.getElementAt({0}) != 10 || result.getElementAt({1}) != 20 || result.getElementAt({2}) != 40 || result.getElementAt({3}) != 50) { .. _example-categoricalarray-insert-18: .. dropdown:: insert (np_test_1_all.cpp:6990) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 6980 :emphasize-lines: 11 } void testBusinessDateRangeDateTime() { std::cout << "========= testBusinessDateRangeDateTime ======================="; datetime64 start("2024-03-11"); // Monday datetime64 end("2024-03-22"); // Friday (2 weeks later) // Create holidays set std::set holidays; holidays.insert(datetime64("2024-03-15")); // Friday holiday auto business_dates = createBusinessDateRange(start, end, holidays); // std::cout << "Business dates from " << start.toString() // << " to " << end.toString() << " (excluding 2024-03-15):" << std::endl; //business_dates.printArray(); std::cout << " -> tests passed" << std::endl; } void testMonthRangeDateTime() { .. _example-categoricalarray-repeat-19: .. dropdown:: repeat (np_test_1_all.cpp:18268) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 18258 :emphasize-lines: 11 // Create test array auto array = createInt32Array({ 2, 3 }, 0); for (size_t i = 0; i < 2; ++i) { for (size_t j = 0; j < 3; ++j) { array.setElementAt({ i, j }, static_cast(i * 3 + j + 1)); } } // Test repeat without axis (flattened) auto repeated_flat = repeat(array, 2); if (!(repeated_flat.getShape()[0] == 12)) { std::string description = std::string("testRepeat():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(repeated_flat.getShape()[0] == 12)"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } if (!(repeated_flat.getElementAt({ 0 }) == 1)) { std::string description = std::string("testRepeat():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(repeated_flat.getElementAt({ 0 }) == 1)"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } .. _example-categoricalarray-repeat-20: .. dropdown:: repeat (np_test_1_all.cpp:18268) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 18258 :emphasize-lines: 11 // Create test array auto array = createInt32Array({ 2, 3 }, 0); for (size_t i = 0; i < 2; ++i) { for (size_t j = 0; j < 3; ++j) { array.setElementAt({ i, j }, static_cast(i * 3 + j + 1)); } } // Test repeat without axis (flattened) auto repeated_flat = repeat(array, 2); if (!(repeated_flat.getShape()[0] == 12)) { std::string description = std::string("testRepeat():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(repeated_flat.getShape()[0] == 12)"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } if (!(repeated_flat.getElementAt({ 0 }) == 1)) { std::string description = std::string("testRepeat():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(repeated_flat.getElementAt({ 0 }) == 1)"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } .. _example-categoricalarray-astype-21: .. dropdown:: astype (np_test_3_all.cpp:796) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 786 :emphasize-lines: 11 auto ufunc_square = numpy::frompyfunc(square, 1, 1); numpy::NDArray arr({ 3 }); arr.setElementAt({ 0 }, 2.0); arr.setElementAt({ 1 }, 3.0); arr.setElementAt({ 2 }, 4.0); auto result = ufunc_square(arr); // Convert back to double to check values auto typed_result = numpy::astype(result); if (std::abs(typed_result.getElementAt({ 0 }) - 4.0) > 1e-10 || std::abs(typed_result.getElementAt({ 1 }) - 9.0) > 1e-10 || std::abs(typed_result.getElementAt({ 2 }) - 16.0) > 1e-10) { std::cout << "[FAIL] Basic frompyfunc creation failed"; return 1; } // std::cout << "[OK] Basic frompyfunc creation works correctly" << std::endl; std::cout << " -> tests passed" << std::endl; return 0; .. _example-categoricalarray-copy-22: .. dropdown:: copy (np_test_1_all.cpp:9812) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 9802 :emphasize-lines: 11 //original.printArray(); // The modification should be at position (1,1) in original if (!(original.getElementAt({1, 1}) == 9999)) { std::string description = std::string("testSliceCopyVsViewMemoryOwnership():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(original.getElementAt({1, 1}) == 9999)"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } // std::cout << "[OK] Slice view shares memory with original"; // Test slice copy (should be independent) auto slice_copy = original.sliceArray({{2, 4}, {2, 4}}); // std::cout << "Slice copy [2:4, 2:4]:"; //slice_copy.printArray(); slice_copy.setElementAt({0, 0}, 7777); // std::cout << "After modifying slice copy at (0,0):" << std::endl; // std::cout << "Original array:" << std::endl; //original.printArray(); // std::cout << "Slice copy:" << std::endl; .. _example-categoricalarray-view-23: .. dropdown:: view (np_test_1_all.cpp:440) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 430 :emphasize-lines: 11 for (size_t i = 0; i < 3; ++i) { for (size_t j = 0; j < 3; ++j) { original.setElementAt({i, j}, static_cast(i * 3 + j)); } } // std::cout << "Original array:" << std::endl; //original.printArray(); // Create multiple views auto view1 = original.view(); auto view2 = original.transposeView(); auto view3 = original.sliceView({{1, 3}, {1, 3}}); // Modify through different views view1.setElementAt({0, 0}, 100); view2.setElementAt({2, 1}, 200); // This is (1, 2) in original view3.setElementAt({0, 0}, 300); // This is (1, 1) in original // std::cout << "After modifications through multiple views:" << std::endl; //original.printArray(); .. _example-categoricalarray-argmax-24: .. dropdown:: argmax (np_test_3_all.cpp:20521) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 20511 :emphasize-lines: 11 auto result = numpy::argmin(arr); // Should return 1 (index of (1,5)) if (result.getElementAt({0}) != 1) { throw std::runtime_error("argmin() failed: expected index 1"); } std::cout << "PASSED\n"; } void test_argmax_complex128() { std::cout << " Testing argmax() with complex128... "; numpy::NDArray arr({3}); arr.setElementAt({0}, complex128(3.0, 1.0)); // index 0 - largest arr.setElementAt({1}, complex128(1.0, 5.0)); // index 1 arr.setElementAt({2}, complex128(2.0, 2.0)); // index 2 auto result = numpy::argmax(arr); // Should return 0 (index of (3,1)) if (result.getElementAt({0}) != 0) { throw std::runtime_error("argmax() failed: expected index 0"); } .. _example-categoricalarray-argmin-25: .. dropdown:: argmin (np_test_3_all.cpp:20506) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 20496 :emphasize-lines: 11 if (min_result.getElementAt({0}).real() != 2.0 || min_result.getElementAt({0}).imag() != 1.0) { throw std::runtime_error("min() tie-breaking failed: expected (2,1)"); } if (max_result.getElementAt({0}).real() != 2.0 || max_result.getElementAt({0}).imag() != 5.0) { throw std::runtime_error("max() tie-breaking failed: expected (2,5)"); } std::cout << "PASSED\n"; } void test_argmin_complex128() { std::cout << " Testing argmin() with complex128... "; numpy::NDArray arr({3}); arr.setElementAt({0}, complex128(3.0, 1.0)); // index 0 arr.setElementAt({1}, complex128(1.0, 5.0)); // index 1 - smallest arr.setElementAt({2}, complex128(2.0, 2.0)); // index 2 auto result = numpy::argmin(arr); // Should return 1 (index of (1,5)) if (result.getElementAt({0}) != 1) { throw std::runtime_error("argmin() failed: expected index 1"); } .. _example-categoricalarray-count-26: .. dropdown:: count (np_test_1_all.cpp:3616) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 3606 :emphasize-lines: 11 // Create larger arrays for performance testing auto large_arr = NDArray::createOnes({100, 100}); auto broadcast_arr = NDArray::createOnes({1, 100}); // Time the operation (basic timing) auto start = std::chrono::high_resolution_clock::now(); auto result = large_arr.addArrays(broadcast_arr); auto end = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast(end - start); // std::cout << "Large array broadcasting took " << duration.count() << " microseconds" << std::endl; // Verify result shape if (!((result.getShape() == std::vector{100, 100}))) { std::string description = std::string("test_broadcasting_performance():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !((result.getShape() == std::vector{100, 100}))"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } if (!(result.getElementAt({50, 50}) == 2.0)) { std::string description = std::string("test_broadcasting_performance():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(result.getElementAt({50, 50}) == 2.0)"; std::cout << std::string("[FAIL] ") + description << std::endl; .. _example-categoricalarray-describe-27: .. dropdown:: describe (np_test_1_all.cpp:11448) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 11438 :emphasize-lines: 11 auto moment2_result = moment(normal_data, 2); // std::cout << "2nd moment: " << moment2_result.getElementAt({ 0 }) << std::endl; if (!(moment2_result.getElementAt({ 0 }) > 0)) { std::string description = std::string("testDistributionShapeMeasures():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(moment2_result.getElementAt({ 0 }) > 0)"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } // std::cout << "[OK] Moment calculation\n"; // Test describe auto desc_result = describe(normal_data); // std::cout << "Describe result:" << std::endl; // std::cout << " nobs: " << desc_result.nobs << std::endl; // std::cout << " min: " << desc_result.minmax.first << ", max: " << desc_result.minmax.second << std::endl; // std::cout << " mean: " << desc_result.mean << std::endl; // std::cout << " variance: " << desc_result.variance << std::endl; if (!(desc_result.nobs == 5)) { std::string description = std::string("testDistributionShapeMeasures():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(desc_result.nobs == 5)"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } .. _example-categoricalarray-dtype-28: .. dropdown:: dtype (np_test_3_all.cpp:7942) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 7932 :emphasize-lines: 11 if (info.max != expected_max) { std::cerr << "[FAIL] IInfo::max mismatch"; throw std::runtime_error("IInfo uint64 max test failed"); } // std::cout << "[OK] IInfo::max = " << info.max << std::endl; std::cout << " -> tests passed" << std::endl; } // ============================================================================ // dtype() Tests - DType descriptor creation // ============================================================================ void np_test_dtype_from_string_integers() { std::cout << "========= np_test_dtype_from_string_integers ======================="; // Test integer type strings if (dtype("int8") != DType::INT8) { std::cerr << "[FAIL] dtype(\"int8\") should return INT8"; throw std::runtime_error("dtype string test failed"); } .. _example-categoricalarray-nbytes-29: .. dropdown:: nbytes (np_test_2_all.cpp:3547) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 3537 :emphasize-lines: 11 } // Test itemsize if (!(itemsize(arr) == sizeof(double))) { std::string description = std::string("testArrayInfo():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(itemsize(arr) == sizeof(double))"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } // Test nbytes if (!(nbytes(arr) == 24 * sizeof(double))) { std::string description = std::string("testArrayInfo():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(nbytes(arr) == 24 * sizeof(double))"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } // Test flags auto flags_info = flags(arr); if (!(flags_info.owndata == true)) { std::string description = std::string("testArrayInfo():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(flags_info.owndata == true)"; std::cout << std::string("[FAIL] ") + description << std::endl; .. _example-categoricalarray-ndim-30: .. dropdown:: ndim (np_test_2_all.cpp:3526) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 3516 :emphasize-lines: 11 void testArrayInfo() { std::cout << "Testing array information functions...\n"; // Test basic info functions auto arr = createFloat64Array({ 2, 3, 4 }); for (size_t i = 0; i < arr.getSize(); ++i) { arr.setElementAt({ i / 12, (i / 4) % 3, i % 4 }, static_cast(i)); } // Test ndim if (!(ndim(arr) == 3)) { std::string description = std::string("testArrayInfo():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(ndim(arr) == 3)"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } // Test size if (!(size(arr) == 24)) { std::string description = std::string("testArrayInfo():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(size(arr) == 24)"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); .. _example-categoricalarray-ordered-31: .. dropdown:: ordered (np_test_2_all.cpp:8640) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 8630 :emphasize-lines: 11 if (indices.size() != n) { std::cout << " IPP large lexsort: -> [FAIL]"; throw std::runtime_error("IPP large lexsort: FAILED - incorrect result size"); } // Verify sorting correctness for (size_t i = 1; i < indices.size(); ++i) { size_t prev_idx = indices[i - 1]; size_t curr_idx = indices[i]; // Check if correctly ordered (second key primary) if (keys[1][curr_idx] < keys[1][prev_idx] || (keys[1][curr_idx] == keys[1][prev_idx] && keys[0][curr_idx] < keys[0][prev_idx])) { std::cout << " IPP large lexsort order: -> [FAIL]"; throw std::runtime_error("IPP large lexsort: FAILED - incorrect ordering"); } } auto duration_us = std::chrono::duration_cast(end - start).count(); // std::cout << "[OK] IPP large lexsort (" << n << " elements): PASSED in " << duration_us << " μs" << std::endl; } .. _example-categoricalarray-shape-32: .. dropdown:: shape (np_test_1_all.cpp:3751) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 3741 :emphasize-lines: 11 } for (size_t j = 0; j < 3; ++j) { arr3.setElementAt({0, j}, static_cast((j + 1) * 100)); // [100, 200, 300] } // Broadcast all arrays together std::vector> arrays = {arr1, arr2, arr3}; auto broadcasted = broadcast_arrays(arrays); // All should have shape (2, 3) for (const auto& arr : broadcasted) { if (!((arr.getShape() == std::vector{2, 3}))) { std::string description = std::string("test_broadcast_arrays():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !((arr.getShape() == std::vector{2, 3}))"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } } // Check values if (!(broadcasted[0].getElementAt({0, 1}) == 2.0)) { .. _example-categoricalarray-shift-33: .. dropdown:: shift (np_test_1_all.cpp:2761) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 2751 :emphasize-lines: 11 throw std::runtime_error(description); } if (!(left_array.getElementAt({3}) == 16384)) { std::string description = std::string("testBitShifts():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(left_array.getElementAt({3}) == 16384)"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } // std::cout << "[OK] Left shift by array\n"; // Test excessive shift (should result in 0) auto excessive_left = left_shift(arr, 20); // More than 16 bits if (!(excessive_left.getElementAt({0}) == 0)) { std::string description = std::string("testBitShifts():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(excessive_left.getElementAt({0}) == 0)"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } if (!(excessive_left.getElementAt({1}) == 0)) { std::string description = std::string("testBitShifts():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(excessive_left.getElementAt({1}) == 0)"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); .. _example-categoricalarray-size-34: .. dropdown:: size (np_test_1_all.cpp:47) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 37 :emphasize-lines: 11 using namespace numpy; using namespace numpy::benchmark; using namespace numpy::char_; // Helper functions for array comparison tests namespace { const double TOLERANCE = 1e-10; bool allTrue(const NDArray& arr) { std::vector indices(arr.getShape().size(), 0); do { if (!arr.getElementAt(indices)) { return false; } } while (incrementIndices(indices, arr.getShape())); return true; } bool allFalse(const NDArray& arr) { std::vector indices(arr.getShape().size(), 0); .. _example-categoricalarray-slice-35: .. dropdown:: slice (np_test_1_all.cpp:13009) :class-title: example-dropdown .. code-block:: cpp :linenos: :lineno-start: 12999 :emphasize-lines: 11 // Test substr valid start but excessive length auto result3 = str1.substr(2, 10); // start=2, len=10 on string of length 5 if (!(result3.to_string() == "llo")) { std::string description = std::string("test_variable_string_out_of_bounds():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(result3.to_string() == \"llo\")"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } // std::cout << "[OK] vstring_ substr(2, 10) on 'hello' returns 'llo'\n"; // Test slice method with out-of-bounds auto result4 = str1.slice(10, 15); // slice[10:15] on string of length 5 if (!(result4.to_string() == "")) { std::string description = std::string("test_variable_string_out_of_bounds():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(result4.to_string() == \"\")"; std::cout << std::string("[FAIL] ") + description << std::endl; throw std::runtime_error(description); } // std::cout << "[OK] vstring_ slice(10, 15) on 'hello' returns empty string\n"; // Test slice with negative indices auto result5 = str1.slice(-2, -1); // slice[-2:-1] should be "l" if (!(result5.to_string() == "l")) {