MaskedArray#

class numpy::MaskedArray#

numpy C++ class.

Example#

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

// Use MaskedArray
MaskedArray obj;
// ... operations ...

Constructors#

Signature

Location

Example

MaskedArray(const NDArray<T>&data, Tfill_value = get_default_fill_value<T>())

NP_MASKED_ARRAY.H:54

MaskedArray(const NDArray<T>&data, const NDArray<bool\_>&mask, Tfill_value = get_default_fill_value<T>())

NP_MASKED_ARRAY.H:60

MaskedArray(const MaskedArray<T>&other)

NP_MASKED_ARRAY.H:69

Operators#

Signature

Return Type

Location

Example

MaskedArray<T>& operator=(const MaskedArray<T>&other)

MaskedArray<T>&

NP_MASKED_ARRAY.H:73

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

MaskedArray<T>

NP_MASKED_ARRAY.H:315

MaskedArray<T> operator+(Tscalar)

MaskedArray<T>

NP_MASKED_ARRAY.H:348

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

MaskedArray<T>

NP_MASKED_ARRAY.H:362

MaskedArray<T> operator-(Tscalar)

MaskedArray<T>

NP_MASKED_ARRAY.H:394

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

MaskedArray<T>

NP_MASKED_ARRAY.H:408

MaskedArray<T> operator\*(Tscalar)

MaskedArray<T>

NP_MASKED_ARRAY.H:440

MaskedArray<T> operator/(const MaskedArray<T>&other)

MaskedArray<T>

NP_MASKED_ARRAY.H:454

MaskedArray<T> operator/(Tscalar)

MaskedArray<T>

NP_MASKED_ARRAY.H:500

MaskedArray<T> operator-()

MaskedArray<T>

NP_MASKED_ARRAY.H:538

MaskedArray<bool\_> operator==(const MaskedArray<T>&other)

MaskedArray<bool_>

NP_MASKED_ARRAY.H:587

MaskedArray<bool\_> operator<(const MaskedArray<T>&other)

MaskedArray<bool_>

NP_MASKED_ARRAY.H:618

MaskedArray<bool\_> operator>(const MaskedArray<T>&other)

MaskedArray<bool_>

NP_MASKED_ARRAY.H:649

MaskedArray<bool\_> operator!=(const MaskedArray<T>&other)

MaskedArray<bool_>

NP_MASKED_ARRAY.H:680

MaskedArray<bool\_> operator<=(const MaskedArray<T>&other)

MaskedArray<bool_>

NP_MASKED_ARRAY.H:711

MaskedArray<bool\_> operator>=(const MaskedArray<T>&other)

MaskedArray<bool_>

NP_MASKED_ARRAY.H:742

Indexing / Selection#

Signature

Return Type

Location

Example

T getElementAt(const std::vector<size_t>&indices)

T

NP_MASKED_ARRAY.H:113

View

size_t getSize()

size_t

NP_MASKED_ARRAY.H:106

View

U get_default_fill_value()

U

NP_MASKED_ARRAY.H:151

Statistics#

Signature

Return Type

Location

Example

T max()

T

NP_MASKED_ARRAY.H:817

View

double mean()

double

NP_MASKED_ARRAY.H:791

View

T min()

T

NP_MASKED_ARRAY.H:800

View

double std()

double

NP_MASKED_ARRAY.H:834

View

T sum()

T

NP_MASKED_ARRAY.H:777

View

double var()

double

NP_MASKED_ARRAY.H:857

View

Type Checking#

Signature

Return Type

Location

Example

bool is_all_masked()

bool

NP_MASKED_ARRAY.H:174

bool is_masked()

bool

NP_MASKED_ARRAY.H:163

View

bool is_masked_at(const std::vector<size_t>&indices)

bool

NP_MASKED_ARRAY.H:131

View

Other Methods#

Signature

Return Type

Location

Example

size_t count()

size_t

NP_MASKED_ARRAY.H:185

View

const NDArray<T>& data()

const NDArray<T>&

NP_MASKED_ARRAY.H:88

View

NDArray<T>& data()

NDArray<T>&

NP_MASKED_ARRAY.H:89

View

T fill_value()

T

NP_MASKED_ARRAY.H:96

View

bool hard_mask()

bool

NP_MASKED_ARRAY.H:100

void harden_mask()

void

NP_MASKED_ARRAY.H:101

View

const NDArray<bool\_>& mask()

const NDArray<bool_>&

NP_MASKED_ARRAY.H:92

View

NDArray<bool\_>& mask()

NDArray<bool_>&

NP_MASKED_ARRAY.H:93

View

void mask_at(const std::vector<size_t>&indices)

void

NP_MASKED_ARRAY.H:136

View

void mask_equal(Tvalue)

void

NP_MASKED_ARRAY.H:289

void mask_greater(Tvalue)

void

NP_MASKED_ARRAY.H:294

void mask_invalid()

void

NP_MASKED_ARRAY.H:280

void mask_less(Tvalue)

void

NP_MASKED_ARRAY.H:299

void mask_where(Funccondition)

void

NP_MASKED_ARRAY.H:247

View

void mask_where(const NDArray<bool\_>&condition)

void

NP_MASKED_ARRAY.H:262

View

T prod()

T

NP_MASKED_ARRAY.H:863

View

void setElementAt(const std::vector<size_t>&indices, Tvalue)

void

NP_MASKED_ARRAY.H:121

View

void set_fill_value(Tvalue)

void

NP_MASKED_ARRAY.H:97

View

void soften_mask()

void

NP_MASKED_ARRAY.H:102

View

void unmask_all()

void

NP_MASKED_ARRAY.H:304

void unmask_at(const std::vector<size_t>&indices)

void

NP_MASKED_ARRAY.H:140

View

Code Examples#

The following examples are extracted from the test suite.

getElementAt (np_test_1_all.cpp:49)
39using namespace numpy::benchmark;
40using namespace numpy::char_;
41
42// Helper functions for array comparison tests
43namespace {
44    const double TOLERANCE = 1e-10;
45
46    bool allTrue(const NDArray<bool>& arr) {
47        std::vector<size_t> indices(arr.getShape().size(), 0);
48        do {
49            if (!arr.getElementAt(indices)) {
50                return false;
51            }
52        } while (incrementIndices(indices, arr.getShape()));
53        return true;
54    }
55
56    bool allFalse(const NDArray<bool>& arr) {
57        std::vector<size_t> indices(arr.getShape().size(), 0);
58        do {
59            if (arr.getElementAt(indices)) {
getSize (np_test_1_all.cpp:2172)
2162    }
2163
2164    std::cout << " -> tests passed" << std::endl;
2165}
2166
2167void testArrayEdgeCases() {
2168    std::cout << "========= testArrayEdgeCases =======================";
2169
2170    // Test 1: Empty arrays
2171    NDArray<object_> empty_array = createObjectZeros({0});
2172    if (!(empty_array.getSize() == 0)) {
2173        std::string description = std::string("testArrayEdgeCases():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(empty_array.getSize() == 0)";
2174        std::cout << std::string("[FAIL] ") + description << std::endl;
2175        throw std::runtime_error(description);
2176    }
2177    if (!(empty_array.getShape() == std::vector<size_t>{0})) {
2178        std::string description = std::string("testArrayEdgeCases():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(empty_array.getShape() == std::vector<size_t>{0})";
2179        std::cout << std::string("[FAIL] ") + description << std::endl;
2180        throw std::runtime_error(description);
2181    }
max (np_test_1_all.cpp:7274)
7264    if (sizeof(uintp) == sizeof(void*)) {
7265        // std::cout << "                -> uintp size matches pointer size";
7266    } else {
7267        // std::cout << "  ✗ uintp size doesn't match pointer size" << std::endl;
7268    }
7269
7270    // Test range limits
7271    // std::cout << "Range Information:" << std::endl;
7272    // std::cout << "  intp min: " << std::numeric_limits<intp>::min() << std::endl;
7273    // std::cout << "  intp max: " << std::numeric_limits<intp>::max() << std::endl;
7274    // std::cout << "  uintp max: " << std::numeric_limits<uintp>::max() << std::endl;
7275    // std::cout << "  longdouble digits: " << std::numeric_limits<longdouble>::digits << std::endl;
7276
7277    std::cout << " -> tests passed" << std::endl;
7278}
7279
7280void testComplexArithmeticExtendedTypes() {
7281    std::cout << "========= testComplexArithmeticExtendedTypes =======================";
7282
7283    clongdouble c1(3.0L, 4.0L);  // 3 + 4i
mean (np_test_1_all.cpp:11714)
11704    // Create test array
11705    auto array = createInt32Array({ 2, 3 }, 0);
11706    array.setElementAt({ 0, 0 }, 1);
11707    array.setElementAt({ 0, 1 }, 2);
11708    array.setElementAt({ 0, 2 }, 3);
11709    array.setElementAt({ 1, 0 }, 4);
11710    array.setElementAt({ 1, 1 }, 5);
11711    array.setElementAt({ 1, 2 }, 6);
11712
11713    // Test mean without axis
11714    auto mean_all = mean(array);
11715    if (!(approx_equal(mean_all.getElementAt({ 0 }), 3.5, 1e-10))) {
11716        std::string description = std::string("testBasicStatistics():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(approx_equal(mean_all.getElementAt({ 0 }), 3.5, 1e-10))";
11717        std::cout << std::string("[FAIL] ") + description << std::endl;
11718        throw std::runtime_error(description);
11719    }
11720    // std::cout << "[OK] mean (all elements) works correctly\n";
11721
11722    // Test mean along axis 0
11723    auto mean_axis0 = mean(array, 0);
11724    if (!(mean_axis0.getShape()[0] == 3)) {
min (np_test_1_all.cpp:2350)
2340        if (i % 3 == 0) {
2341            large_array.setElementAt({i}, object_(static_cast<int>(i)));
2342        } else if (i % 3 == 1) {
2343            large_array.setElementAt({i}, object_(static_cast<double>(i) * 0.5));
2344        } else {
2345            large_array.setElementAt({i}, object_(std::string("str") + std::to_string(i)));
2346        }
2347    }
2348
2349    // Verify pattern
2350    for (size_t i = 0; i < std::min(large_size, size_t(100)); ++i) {  // Check first 100
2351        object_ obj = large_array.getElementAt({i});
2352        if (i % 3 == 0) {
2353            if (!(obj.is_type<int>())) {
2354                std::string description = std::string("testArrayEdgeCases():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(obj.is_type<int>())";
2355                std::cout << std::string("[FAIL] ") + description << std::endl;
2356                throw std::runtime_error(description);
2357            }
2358        } else if (i % 3 == 1) {
2359            if (!(obj.is_type<double>())) {
2360                std::string description = std::string("unknown_function():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(obj.is_type<double>())";
std (np_test_1_all.cpp:11836)
11826    auto var_sample = var(array, std::nullopt, 1);  // ddof=1 for sample variance
11827    double expected_sample_var = 1.25 * 4.0 / 3.0;  // Bessel's correction
11828    if (!(approx_equal(var_sample.getElementAt({ 0 }), expected_sample_var, 1e-10))) {
11829        std::string description = std::string("testVarianceAndStandardDeviation():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(approx_equal(var_sample.getElementAt({ 0 }), expected_sample_var, 1e-10))";
11830        std::cout << std::string("[FAIL] ") + description << std::endl;
11831        throw std::runtime_error(description);
11832    }
11833    // std::cout << "[OK] Sample variance works correctly\n";
11834
11835    // Test standard deviation
11836    auto std_result = numpy::std(array, std::nullopt, 0);
11837    if (!(approx_equal(std_result.getElementAt({ 0 }), std::sqrt(expected_var), 1e-10))) {
11838        std::string description = std::string("testVarianceAndStandardDeviation():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(approx_equal(std_result.getElementAt({ 0 }), std::sqrt(expected_var), 1e-10))";
11839        std::cout << std::string("[FAIL] ") + description << std::endl;
11840        throw std::runtime_error(description);
11841    }
11842    // std::cout << "[OK] Standard deviation works correctly\n";
11843
11844    // Test along axis
11845    auto array2d = createFloat64Array({ 2, 2 }, 0);
11846    array2d.setElementAt({ 0, 0 }, 1.0);
sum (np_test_1_all.cpp:11766)
11756        throw std::runtime_error(description);
11757    }
11758    if (!(approx_equal(mean_axis1.getElementAt({ 1 }), 5.0, 1e-10))) {
11759        std::string description = std::string("testBasicStatistics():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(approx_equal(mean_axis1.getElementAt({ 1 }), 5.0, 1e-10))";
11760        std::cout << std::string("[FAIL] ") + description << std::endl;
11761        throw std::runtime_error(description);
11762    }
11763    // std::cout << "[OK] mean along axis 1 works correctly\n";
11764
11765    // Test sum
11766    auto sum_all = sum(array);
11767    if (!(sum_all.getElementAt({ 0 }) == 21)) {
11768        std::string description = std::string("testBasicStatistics():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(sum_all.getElementAt({ 0 }) == 21)";
11769        std::cout << std::string("[FAIL] ") + description << std::endl;
11770        throw std::runtime_error(description);
11771    }
11772    // std::cout << "[OK] sum works correctly\n";
11773
11774    // Test min and max
11775    auto min_all = min(array);
11776    auto max_all = max(array);
var (np_test_1_all.cpp:11816)
11806    std::cout << "========= testVarianceAndStandardDeviation =======================";
11807
11808    // Create test array with known variance
11809    auto array = createFloat64Array({ 4 }, 0);
11810    array.setElementAt({ 0 }, 1.0);
11811    array.setElementAt({ 1 }, 2.0);
11812    array.setElementAt({ 2 }, 3.0);
11813    array.setElementAt({ 3 }, 4.0);
11814
11815    // Test variance (population)
11816    auto var_result = var(array, std::nullopt, 0);  // ddof=0 for population variance
11817    double expected_var = 1.25;  // Known variance for [1,2,3,4]
11818    if (!(approx_equal(var_result.getElementAt({ 0 }), expected_var, 1e-10))) {
11819        std::string description = std::string("testVarianceAndStandardDeviation():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(approx_equal(var_result.getElementAt({ 0 }), expected_var, 1e-10))";
11820        std::cout << std::string("[FAIL] ") + description << std::endl;
11821        throw std::runtime_error(description);
11822    }
11823    // std::cout << "[OK] Population variance works correctly\n";
11824
11825    // Test variance (sample)
11826    auto var_sample = var(array, std::nullopt, 1);  // ddof=1 for sample variance
is_masked (np_test_5_all.cpp:3746)
3736      std::cout << "========= is_masked =======================";
3737
3738      // Test with masked array that has some masked values
3739      numpy::NDArray<double> arr1({ 3 });
3740      arr1.setElementAt({ 0 }, 1.0);
3741      arr1.setElementAt({ 1 }, std::numeric_limits<double>::quiet_NaN());
3742      arr1.setElementAt({ 2 }, 3.0);
3743
3744      auto ma1 = numpy::masked_invalid(arr1);
3745
3746      if (!numpy::is_masked(ma1)) {
3747        std::cout << "  [FAIL] : in np_test_is_masked() : Array with NaN not detected as masked";
3748        throw std::runtime_error("Test failed");
3749      }
3750
3751      // Test with masked array with no masked values
3752      numpy::NDArray<double> arr2({ 3 });
3753      arr2.setElementAt({ 0 }, 1.0);
3754      arr2.setElementAt({ 1 }, 2.0);
3755      arr2.setElementAt({ 2 }, 3.0);
is_masked_at (np_test_2_all.cpp:6004)
5994      data.setElementAt({ 2, 0 }, 7.0);
5995      data.setElementAt({ 2, 1 }, 8.0);
5996      data.setElementAt({ 2, 2 }, 9.0);
5997
5998      auto mask = createBoolArray({ 3, 3 }, false);
5999      mask.setElementAt({ 0, 0 }, true);
6000      mask.setElementAt({ 1, 1 }, true);
6001
6002      MaskedArray<double> ma(data, mask, -999.0);
6003
6004      if (!(ma.is_masked_at({ 0, 0 }))) {
6005          std::string description = std::string("testMaskedArrayCreation():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(ma.is_masked_at({ 0, 0 }))";
6006          std::cout << std::string("[FAIL] ") + description << std::endl;
6007          throw std::runtime_error(description);
6008      }
6009      if (!(ma.is_masked_at({ 1, 1 }))) {
6010          std::string description = std::string("testMaskedArrayCreation():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(ma.is_masked_at({ 1, 1 }))";
6011          std::cout << std::string("[FAIL] ") + description << std::endl;
6012          throw std::runtime_error(description);
6013      }
6014      if (!(!ma.is_masked_at({ 0, 1 }))) {
count (np_test_1_all.cpp:3616)
3606    // Create larger arrays for performance testing
3607    auto large_arr = NDArray<double>::createOnes({100, 100});
3608    auto broadcast_arr = NDArray<double>::createOnes({1, 100});
3609
3610    // Time the operation (basic timing)
3611    auto start = std::chrono::high_resolution_clock::now();
3612    auto result = large_arr.addArrays(broadcast_arr);
3613    auto end = std::chrono::high_resolution_clock::now();
3614
3615    auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
3616    // std::cout << "Large array broadcasting took " << duration.count() << " microseconds" << std::endl;
3617
3618    // Verify result shape
3619    if (!((result.getShape() == std::vector<size_t>{100, 100}))) {
3620        std::string description = std::string("test_broadcasting_performance():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !((result.getShape() == std::vector<size_t>{100, 100}))";
3621        std::cout << std::string("[FAIL] ") + description << std::endl;
3622        throw std::runtime_error(description);
3623    }
3624    if (!(result.getElementAt({50, 50}) == 2.0)) {
3625        std::string description = std::string("test_broadcasting_performance():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(result.getElementAt({50, 50}) == 2.0)";
3626        std::cout << std::string("[FAIL] ") + description << std::endl;
data (np_test_1_all.cpp:2084)
2074    }
2075    if (!(derived_ptr->extra == 2)) {
2076        std::string description = std::string("testObjectHolderEdgeCases():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(derived_ptr->extra == 2)";
2077        std::cout << std::string("[FAIL] ") + description << std::endl;
2078        throw std::runtime_error(description);
2079    }
2080
2081    // Test 6: Large object handling
2082    struct LargeObject {
2083        std::vector<double> data;
2084        LargeObject() : data(10000, 3.14159) {}  // Large object
2085    };
2086
2087    LargeObject large;
2088    object_ large_obj(large);  // Should handle large objects
2089    if (!(!large_obj.is_null())) {
2090        std::string description = std::string("testObjectHolderEdgeCases():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(!large_obj.is_null())";
2091        std::cout << std::string("[FAIL] ") + description << std::endl;
2092        throw std::runtime_error(description);
2093    }
2094    if (!(large_obj.is_type<LargeObject>())) {
data (np_test_1_all.cpp:2084)
2074    }
2075    if (!(derived_ptr->extra == 2)) {
2076        std::string description = std::string("testObjectHolderEdgeCases():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(derived_ptr->extra == 2)";
2077        std::cout << std::string("[FAIL] ") + description << std::endl;
2078        throw std::runtime_error(description);
2079    }
2080
2081    // Test 6: Large object handling
2082    struct LargeObject {
2083        std::vector<double> data;
2084        LargeObject() : data(10000, 3.14159) {}  // Large object
2085    };
2086
2087    LargeObject large;
2088    object_ large_obj(large);  // Should handle large objects
2089    if (!(!large_obj.is_null())) {
2090        std::string description = std::string("testObjectHolderEdgeCases():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(!large_obj.is_null())";
2091        std::cout << std::string("[FAIL] ") + description << std::endl;
2092        throw std::runtime_error(description);
2093    }
2094    if (!(large_obj.is_type<LargeObject>())) {
fill_value (np_test_3_all.cpp:21316)
21306    std::cout << "========= Pad jagged array ====" ;
21307
21308    // Create jagged array
21309    numpy::NDArray<numpy::object_> jagged = numpy::make_jagged_array({
21310        {1, 2, 3},
21311        {4, 5},
21312        {6}
21313    });
21314
21315    // Pad with -1
21316    numpy::object_ fill_value(-1);
21317    numpy::NDArray<numpy::object_> padded = numpy::NestedArray<int>::padJagged(jagged, fill_value);
21318
21319    // Should be 3x3
21320    CHECK(padded.getShape().size() == 2, "np_test_nested_pad", "ndim != 2");
21321    CHECK(padded.getShape()[0] == 3, "np_test_nested_pad", "shape[0] != 3");
21322    CHECK(padded.getShape()[1] == 3, "np_test_nested_pad", "shape[1] != 3");
21323
21324    // Check values - must store object_ to keep pointers valid (avoid dangling)
21325    numpy::object_ obj00 = padded.getElementAt({0, 0});
21326    numpy::object_ obj01 = padded.getElementAt({0, 1});
harden_mask (np_test_2_all.cpp:6446)
6436          std::string description = std::string("testHardSoftMasks():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(!ma_soft.is_masked_at({ 1 }))";
6437          std::cout << std::string("[FAIL] ") + description << std::endl;
6438          throw std::runtime_error(description);
6439      }
6440      // std::cout << "[OK] Soft mask allows unmasking\n";
6441
6442      // Test hard mask - need to set hard mask mode first
6443      MaskedArray<double> ma_hard(data, mask, -999.0);
6444
6445      // std::cout << ma_hard.is_masked_at({ 1 }) << std::endl;
6446      ma_hard.harden_mask();
6447      ma_hard.unmask_at({ 1 });
6448      if (!(ma_hard.is_masked_at({ 1 }))) {
6449          std::string description = std::string("testHardSoftMasks():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(ma_hard.is_masked_at({ 1 }))";
6450          std::cout << std::string("[FAIL] ") + description << std::endl;
6451          throw std::runtime_error(description);
6452      }
6453      // std::cout << "[OK] Hard mask prevents unmasking\n";
6454
6455      std::cout << " -> tests passed\n";
6456    }
mask (np_test_1_all.cpp:27691)
27681    void test_mask_rows_cols() {
27682      std::cout << "========= ma::mask_rows() and ma::mask_cols(): mask operations ===";
27683
27684      auto data = numpy::array({ {1.0, 2.0, 3.0}, {4.0, 5.0, 6.0} });
27685      auto mask = numpy::array({ {false, true, false}, {false, false, false} });
27686      auto ma = numpy::ma::masked_array(data, mask);
27687
27688      auto result_rows = numpy::ma::mask_rows(ma);
27689      auto result_cols = numpy::ma::mask_cols(ma);
27690
27691      // std::cout << "  ma::mask_rows(): row 0 fully masked: " << (result_rows.mask().getElementAt({ 0, 0 }) ? "true" : "false") << std::endl;
27692      // std::cout << "  ma::mask_cols(): column 1 fully masked: " << (result_cols.mask().getElementAt({ 1, 1 }) ? "true" : "false");
27693      std::cout << " -> tests passed";
27694    }
27695
27696    void test_compress_rowcols() {
27697      std::cout << "========= ma::compress_rowcols(): remove masked rows/columns ===";
27698
27699      auto data = numpy::array({ {1.0, 2.0, 3.0}, {4.0, 5.0, 6.0}, {7.0, 8.0, 9.0} });
27700      auto mask = numpy::array({ {false, false, false}, {false, true, false}, {false, false, false} });
27701      auto ma = numpy::ma::masked_array(data, mask);
mask (np_test_1_all.cpp:27691)
27681    void test_mask_rows_cols() {
27682      std::cout << "========= ma::mask_rows() and ma::mask_cols(): mask operations ===";
27683
27684      auto data = numpy::array({ {1.0, 2.0, 3.0}, {4.0, 5.0, 6.0} });
27685      auto mask = numpy::array({ {false, true, false}, {false, false, false} });
27686      auto ma = numpy::ma::masked_array(data, mask);
27687
27688      auto result_rows = numpy::ma::mask_rows(ma);
27689      auto result_cols = numpy::ma::mask_cols(ma);
27690
27691      // std::cout << "  ma::mask_rows(): row 0 fully masked: " << (result_rows.mask().getElementAt({ 0, 0 }) ? "true" : "false") << std::endl;
27692      // std::cout << "  ma::mask_cols(): column 1 fully masked: " << (result_cols.mask().getElementAt({ 1, 1 }) ? "true" : "false");
27693      std::cout << " -> tests passed";
27694    }
27695
27696    void test_compress_rowcols() {
27697      std::cout << "========= ma::compress_rowcols(): remove masked rows/columns ===";
27698
27699      auto data = numpy::array({ {1.0, 2.0, 3.0}, {4.0, 5.0, 6.0}, {7.0, 8.0, 9.0} });
27700      auto mask = numpy::array({ {false, false, false}, {false, true, false}, {false, false, false} });
27701      auto ma = numpy::ma::masked_array(data, mask);
mask_at (np_test_5_all.cpp:4074)
4064      // Create a 2D array
4065      numpy::NDArray<double> arr({ 3, 4 });
4066      for (size_t i = 0; i < 3; ++i) {
4067        for (size_t j = 0; j < 4; ++j) {
4068          arr.setElementAt({ i, j }, static_cast<double>(i * 4 + j));
4069        }
4070      }
4071      numpy::MaskedArray<double> ma(arr);
4072
4073      // Mask one element at (0, 1)
4074      ma.mask_at({ 0, 1 });
4075
4076      // Mask entire row containing masked element (axis=0)
4077      auto ma_rows = numpy::mask_rowcols(ma, 0);
4078
4079      // Check that entire first row is masked
4080      for (size_t j = 0; j < 4; ++j) {
4081        if (!ma_rows.mask().getElementAt({ 0, j })) {
4082          std::cout << "  [FAIL] : in np_test_mask_rowcols() : Row 0 should be fully masked";
4083          throw std::runtime_error("Test failed");
4084        }
mask_where (np_test_2_all.cpp:6308)
6298      data.setElementAt({ 3 }, 40.0);
6299
6300      auto mask = createBoolArray({ 4 }, false);
6301      MaskedArray<double> ma(data, mask, -999.0);
6302
6303      // Test mask_where
6304      auto condition = createBoolArray({ 4 }, false);
6305      condition.setElementAt({ 0 }, true);
6306      condition.setElementAt({ 2 }, true);
6307
6308      ma.mask_where(condition);
6309      if (!(ma.is_masked_at({ 0 }))) {
6310          std::string description = std::string("testMaskOperations():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(ma.is_masked_at({ 0 }))";
6311          std::cout << std::string("[FAIL] ") + description << std::endl;
6312          throw std::runtime_error(description);
6313      }
6314      if (!(!ma.is_masked_at({ 1 }))) {
6315          std::string description = std::string("testMaskOperations():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(!ma.is_masked_at({ 1 }))";
6316          std::cout << std::string("[FAIL] ") + description << std::endl;
6317          throw std::runtime_error(description);
6318      }
mask_where (np_test_2_all.cpp:6308)
6298      data.setElementAt({ 3 }, 40.0);
6299
6300      auto mask = createBoolArray({ 4 }, false);
6301      MaskedArray<double> ma(data, mask, -999.0);
6302
6303      // Test mask_where
6304      auto condition = createBoolArray({ 4 }, false);
6305      condition.setElementAt({ 0 }, true);
6306      condition.setElementAt({ 2 }, true);
6307
6308      ma.mask_where(condition);
6309      if (!(ma.is_masked_at({ 0 }))) {
6310          std::string description = std::string("testMaskOperations():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(ma.is_masked_at({ 0 }))";
6311          std::cout << std::string("[FAIL] ") + description << std::endl;
6312          throw std::runtime_error(description);
6313      }
6314      if (!(!ma.is_masked_at({ 1 }))) {
6315          std::string description = std::string("testMaskOperations():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(!ma.is_masked_at({ 1 }))";
6316          std::cout << std::string("[FAIL] ") + description << std::endl;
6317          throw std::runtime_error(description);
6318      }
prod (np_test_1_all.cpp:11795)
11785        throw std::runtime_error(description);
11786    }
11787    // std::cout << "[OK] min and max work correctly\n";
11788
11789    // Test product
11790    auto small_array = createInt32Array({ 3 }, 0);
11791    small_array.setElementAt({ 0 }, 2);
11792    small_array.setElementAt({ 1 }, 3);
11793    small_array.setElementAt({ 2 }, 4);
11794
11795    auto prod_result = prod(small_array);
11796    if (!(prod_result.getElementAt({ 0 }) == 24)) {
11797        std::string description = std::string("testBasicStatistics():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(prod_result.getElementAt({ 0 }) == 24)";
11798        std::cout << std::string("[FAIL] ") + description << std::endl;
11799        throw std::runtime_error(description);
11800    }
11801    // std::cout << "[OK] prod works correctly\n";
11802    std::cout << " -> tests passed" << std::endl;
11803  }
11804
11805  void testVarianceAndStandardDeviation() {
setElementAt (np_test_1_all.cpp:135)
125    //ones_array.printArray();
126
127    std::cout << " -> tests passed" << std::endl;
128}
129
130void testElementAccess() {
131    std::cout << "========= testElementAccess =======================";
132
133    auto array = createInt32Array({3, 3}, 0);
134
135    array.setElementAt({0, 0}, 1);
136    array.setElementAt({0, 1}, 2);
137    array.setElementAt({0, 2}, 3);
138    array.setElementAt({1, 1}, 5);
139    array.setElementAt({2, 2}, 9);
140
141    // std::cout << "Array after setting elements:" << std::endl;
142    //array.printArray();
143
144    // std::cout << "Element at (1,1): " << array.getElementAt({1, 1}) << std::endl;
145    // std::cout << "Element at (2,2): " << array.getElementAt({2, 2});
set_fill_value (np_test_5_all.cpp:3829)
3819    void np_test_common_fill_value() {
3820      std::cout << "========= common_fill_value =======================";
3821
3822      // Create two masked arrays with the same fill value
3823      numpy::NDArray<double> arr1({ 3 });
3824      arr1.setElementAt({ 0 }, 1.0);
3825      arr1.setElementAt({ 1 }, 2.0);
3826      arr1.setElementAt({ 2 }, 3.0);
3827      numpy::MaskedArray<double> ma1(arr1);
3828      ma1.set_fill_value(999.0);
3829
3830      numpy::NDArray<double> arr2({ 3 });
3831      arr2.setElementAt({ 0 }, 4.0);
3832      arr2.setElementAt({ 1 }, 5.0);
3833      arr2.setElementAt({ 2 }, 6.0);
3834      numpy::MaskedArray<double> ma2(arr2);
3835      ma2.set_fill_value(999.0);
3836
3837      auto fill = numpy::common_fill_value(ma1, ma2);
soften_mask (np_test_5_all.cpp:4116)
4106      for (size_t i = 0; i < 5; ++i) {
4107        arr.setElementAt({ i }, static_cast<double>(i + 1));
4108      }
4109      numpy::MaskedArray<double> ma(arr);
4110
4111      // Mask some elements
4112      ma.mask_at({ 1 });
4113      ma.mask_at({ 3 });
4114
4115      // Soften the mask (allows modification)
4116      ma.soften_mask();
4117
4118      // After softening, we should still have the masked elements
4119      if (!ma.mask().getElementAt({ 1 }) || !ma.mask().getElementAt({ 3 })) {
4120        std::cout << "  [FAIL] : in np_test_soften_mask() : Masked elements lost after soften";
4121        throw std::runtime_error("Test failed");
4122      }
4123
4124      // Verify unmasked elements are still unmasked
4125      if (ma.mask().getElementAt({ 0 }) || ma.mask().getElementAt({ 2 }) || ma.mask().getElementAt({ 4 })) {
4126        std::cout << "  [FAIL] : in np_test_soften_mask() : Unmasked elements incorrectly masked";
unmask_at (np_test_2_all.cpp:6335)
6325          std::string description = std::string("testMaskOperations():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(!ma.is_masked_at({ 3 }))";
6326          std::cout << std::string("[FAIL] ") + description << std::endl;
6327          throw std::runtime_error(description);
6328      }
6329      // std::cout << "[OK] mask_where() applies conditional masking\n";
6330
6331      // Test unmask (for soft masks)
6332      auto unmask_condition = createBoolArray({ 4 }, false);
6333      unmask_condition.setElementAt({ 0 }, true);
6334
6335      ma.unmask_at({ 0 });
6336      if (!(!ma.is_masked_at({ 0 }))) {
6337          std::string description = std::string("testMaskOperations():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(!ma.is_masked_at({ 0 }))";
6338          std::cout << std::string("[FAIL] ") + description << std::endl;
6339          throw std::runtime_error(description);
6340      }
6341      if (!(ma.is_masked_at({ 2 }))) {
6342          std::string description = std::string("testMaskOperations():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(ma.is_masked_at({ 2 }))";
6343          std::cout << std::string("[FAIL] ") + description << std::endl;
6344          throw std::runtime_error(description);
6345      }