PeriodArray#

class numpy::PeriodArray#

numpy C++ class.

Example#

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

// Use PeriodArray
PeriodArray obj;
// ... operations ...

Constructors#

Signature

Location

Example

PeriodArray(const numpy::NDArray<numpy::int64>& data, const numpy::NDArray<numpy::bool\_>& mask, const std::string& freq, bool copy = false)

df_period_array.h:583

PeriodArray(const numpy::NDArray<numpy::int64>& data, const std::string& freq)

df_period_array.h:599

PeriodArray(const std::vector<std::optional<numpy::int64>>& values, const std::string& freq)

df_period_array.h:641

PeriodArray(const std::vector<std::string>& period_strings, const std::string& freq)

df_period_array.h:661

Construction#

Signature

Return Type

Location

Example

static PeriodArray from_sequence(const std::vector<std::optional<numpy::int64>>& scalars, const std::string& freq)

static PeriodArray

df_period_array.h:1536

Array Creation#

Signature

Return Type

Location

Example

bool empty() const

bool

df_period_array.h:721

View

Indexing / Selection#

Signature

Return Type

Location

Example

numpy::int64 at(size_t index) const

numpy::int64

df_period_array.h:780

View

Statistics#

Signature

Return Type

Location

Example

std::optional<numpy::int64> max() const

std::optional<numpy::int64>

df_period_array.h:1461

View

std::optional<numpy::int64> min() const

std::optional<numpy::int64>

df_period_array.h:1452

View

IntegerArray<numpy::int32> minute() const

IntegerArray<numpy::int32>

df_period_array.h:1040

View

Sorting#

Signature

Return Type

Location

Example

numpy::NDArray<size_t> argsort(bool ascending = true, const std::string& na_position = "last") const

numpy::NDArray<size_t>

df_period_array.h:1382

View

Set Operations#

Signature

Return Type

Location

Example

PeriodArray unique() const

PeriodArray

df_period_array.h:1474

View

I/O#

Signature

Return Type

Location

Example

std::string to_string() const

std::string

df_period_array.h:1581

View

DatetimeArray to_timestamp(const std::string& how = "start") const

DatetimeArray

df_period_array.h:1119

Type Handling#

Signature

Return Type

Location

Example

PeriodArray copy() const

PeriodArray

df_period_array.h:827

View

Type Checking#

Signature

Return Type

Location

Example

BooleanArray is_leap_year() const

BooleanArray

df_period_array.h:1096

View

bool is_na(size_t index) const

bool

df_period_array.h:791

Other Methods#

Signature

Return Type

Location

Example

std::optional<size_t> argmax() const

std::optional<size_t>

df_period_array.h:1433

View

std::optional<size_t> argmin() const

std::optional<size_t>

df_period_array.h:1414

View

PeriodArray asfreq(const std::string& new_freq, const std::string& how = "end") const

PeriodArray

df_period_array.h:1152

static PeriodArray concat(const std::vector<PeriodArray>& arrays)

static PeriodArray

df_period_array.h:1544

size_t count() const

size_t

df_period_array.h:834

View

const numpy::NDArray<numpy::int64>& data() const

const numpy::NDArray<numpy::int64>&

df_period_array.h:753

View

IntegerArray<numpy::int32> day() const

IntegerArray<numpy::int32>

df_period_array.h:965

View

IntegerArray<numpy::int32> dayofweek() const

IntegerArray<numpy::int32>

df_period_array.h:982

View

IntegerArray<numpy::int32> dayofyear() const

IntegerArray<numpy::int32>

df_period_array.h:1006

View

IntegerArray<numpy::int32> days_in_month() const

IntegerArray<numpy::int32>

df_period_array.h:1074

View

days_since_epoch_to_date(days, year, month, day)

df_period_array.h:1174

PeriodArray dropna() const

PeriodArray

df_period_array.h:873

dtype_type dtype() const

dtype_type

df_period_array.h:686

View

DatetimeArray end_time() const

DatetimeArray

df_period_array.h:1143

std::pair<numpy::NDArray<numpy::int64>, PeriodArray> factorize() const

std::pair<numpy::NDArray<numpy::int64>, PeriodArray>

df_period_array.h:1500

PeriodArray fillna(numpy::int64 value) const

PeriodArray

df_period_array.h:859

PeriodFrequency freq() const

PeriodFrequency

df_period_array.h:735

std::string freqstr() const

std::string

df_period_array.h:742

bool has_na() const

bool

df_period_array.h:847

IntegerArray<numpy::int32> hour() const

IntegerArray<numpy::int32>

df_period_array.h:1023

View

numpy::NDArray<numpy::bool\_> isna() const

numpy::NDArray<numpy::bool_>

df_period_array.h:809

size_t len() const

size_t

df_period_array.h:728

const numpy::NDArray<numpy::bool\_>& mask() const

const numpy::NDArray<numpy::bool_>&

df_period_array.h:760

View

IntegerArray<numpy::int32> month() const

IntegerArray<numpy::int32>

df_period_array.h:924

View

size_t nbytes() const

size_t

df_period_array.h:700

View

constexpr int ndim() const

constexpr int

df_period_array.h:707

View

numpy::NDArray<numpy::bool\_> notna() const

numpy::NDArray<numpy::bool_>

df_period_array.h:816

numpy::int64 ordinal(size_t index) const

numpy::int64

df_period_array.h:798

ordinal_to_day(data\_.getElementAt(

df_period_array.h:973

ordinal_to_dayofweek(data\_.getElementAt(

df_period_array.h:990

ordinal_to_dayofyear(data\_.getElementAt(

df_period_array.h:1014

ordinal_to_hour(data\_.getElementAt(

df_period_array.h:1031

ordinal_to_minute(data\_.getElementAt(

df_period_array.h:1048

ordinal_to_month(data\_.getElementAt(

df_period_array.h:932

ordinal_to_quarter(data\_.getElementAt(

df_period_array.h:915

ordinal_to_second(data\_.getElementAt(

df_period_array.h:1065

ordinal_to_week(data\_.getElementAt(

df_period_array.h:949

ordinal_to_year(data\_.getElementAt(

df_period_array.h:898

IntegerArray<numpy::int32> quarter() const

IntegerArray<numpy::int32>

df_period_array.h:907

View

std::string repr() const

std::string

df_period_array.h:1603

IntegerArray<numpy::int32> second() const

IntegerArray<numpy::int32>

df_period_array.h:1057

View

std::vector<size_t> shape() const

std::vector<size_t>

df_period_array.h:714

View

size_t size() const

size_t

df_period_array.h:693

View

DatetimeArray start_time() const

DatetimeArray

df_period_array.h:1136

void validate_arrays()

void

df_period_array.h:543

IntegerArray<numpy::int32> week() const

IntegerArray<numpy::int32>

df_period_array.h:941

View

IntegerArray<numpy::int32> weekday() const

IntegerArray<numpy::int32>

df_period_array.h:999

View

IntegerArray<numpy::int32> weekofyear() const

IntegerArray<numpy::int32>

df_period_array.h:958

IntegerArray<numpy::int32> year() const

IntegerArray<numpy::int32>

df_period_array.h:890

View

Code Examples#

The following examples are extracted from the test suite.

empty (np_test_1_all.cpp:6316)
6306}
6307
6308void test_data_generator_emptyBenchmarkSorting() {
6309    std::cout << "========= test_data_generator_empty =======================";
6310
6311    DataGenerator<int> gen(42);
6312
6313    // Test empty data generation
6314    std::vector<int> data = gen.generate(0, DataPattern::RANDOM);
6315
6316    if (!(data.empty())) {
6317        std::string description = std::string("test_data_generator_emptyBenchmarkSorting():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(data.empty())";
6318        std::cout << std::string("[FAIL] ") + description << std::endl;
6319        throw std::runtime_error(description);
6320    }
6321
6322    // std::cout << "Empty data generation test passed" << std::endl;
6323
6324    std::cout << " -> tests passed" << std::endl;
6325}
at (np_test_1_all.cpp:144)
134    array.setElementAt({0, 0}, 1);
135    array.setElementAt({0, 1}, 2);
136    array.setElementAt({0, 2}, 3);
137    array.setElementAt({1, 1}, 5);
138    array.setElementAt({2, 2}, 9);
139
140    // std::cout << "Array after setting elements:" << std::endl;
141    //array.printArray();
142
143    // std::cout << "Element at (1,1): " << array.getElementAt({1, 1}) << std::endl;
144    // std::cout << "Element at (2,2): " << array.getElementAt({2, 2});
145
146    std::cout << " -> tests passed" << std::endl;
147}
148
149void testArithmetic() {
150    std::cout << "========= testArithmeticOperations =======================";
151
152    auto array1 = createFloat32Array({2, 2}, 5.0f);
153    auto array2 = createFloat32Array({2, 2}, 3.0f);
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
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>())";
minute (np_test_5_all.cpp:22186)
22176            errors++;
22177        }
22178
22179        numpy::Timedelta td3("45s");
22180        if (std::abs(td3.total_seconds() - 45.0) > 0.0001) {
22181            std::cout << "[FAIL] np_test_timedelta_edge_cases: '45s' expected 45 sec"
22182                      << std::endl;
22183            errors++;
22184        }
22185
22186        numpy::Timedelta td4("NaT");
22187        if (!td4.isNaT()) {
22188            std::cout << "[FAIL] np_test_timedelta_edge_cases: 'NaT' should parse to NaT"
22189                      << std::endl;
22190            errors++;
22191        }
22192    }
22193
22194    // Stream operator
22195    {
22196        numpy::Timedelta td(1, 2, 30);
argsort (np_test_1_all.cpp:16841)
16831    std::cout << "========= test_argsort =======================";
16832
16833    // Test 1D array argsort
16834    NDArray<int> arr1d({ 5 });
16835    arr1d.setElementAt({ 0 }, 30);  // index 0
16836    arr1d.setElementAt({ 1 }, 10);  // index 1
16837    arr1d.setElementAt({ 2 }, 40);  // index 2
16838    arr1d.setElementAt({ 3 }, 20);  // index 3
16839    arr1d.setElementAt({ 4 }, 50);  // index 4
16840
16841    auto indices = argsort(arr1d);
16842
16843    // Expected order: 10(idx1), 20(idx3), 30(idx0), 40(idx2), 50(idx4)
16844    if (!(indices.getElementAt({ 0 }) == 1)) {
16845        std::string description = std::string("test_argsort():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(indices.getElementAt({ 0 }) == 1)";
16846        std::cout << std::string("[FAIL] ") + description << std::endl;
16847        throw std::runtime_error(description);
16848    }
16849    if (!(indices.getElementAt({ 1 }) == 3)) {
16850        std::string description = std::string("test_argsort():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(indices.getElementAt({ 1 }) == 3)";
16851        std::cout << std::string("[FAIL] ") + description << std::endl;
unique (np_test_1_all.cpp:6259)
6249    if (!(data.size() == 100)) {
6250        std::string description = std::string("test_data_generator_few_uniqueBenchmarkSorting():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(data.size() == 100)";
6251        std::cout << std::string("[FAIL] ") + description << std::endl;
6252        throw std::runtime_error(description);
6253    }
6254
6255    // Count unique values
6256    std::vector<int> sorted_copy = data;
6257    std::sort(sorted_copy.begin(), sorted_copy.end());
6258    auto unique_end = std::unique(sorted_copy.begin(), sorted_copy.end());
6259    size_t unique_count = std::distance(sorted_copy.begin(), unique_end);
6260
6261    // Should have significantly fewer unique values than total elements
6262    if (!(unique_count < data.size() / 2)) {
6263        std::string description = std::string("test_data_generator_few_uniqueBenchmarkSorting():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(unique_count < data.size() / 2)";
6264        std::cout << std::string("[FAIL] ") + description << std::endl;
6265        throw std::runtime_error(description);
6266    }
6267
6268    // std::cout << "Few unique data generation test passed. Unique values: " << unique_count << std::endl;
to_string (np_test_1_all.cpp:454)
444    // Modify through different views
445    view1.setElementAt({0, 0}, 100);
446    view2.setElementAt({2, 1}, 200);  // This is (1, 2) in original
447    view3.setElementAt({0, 0}, 300);  // This is (1, 1) in original
448
449    // std::cout << "After modifications through multiple views:" << std::endl;
450    //original.printArray();
451
452    // Verify all changes are reflected
453    if (!(original.getElementAt({0, 0}) == 100)) {
454        std::string description = std::string("testAdvancedViewLifecycle():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(original.getElementAt({0, 0}) == 100)";
455        std::cout << std::string("[FAIL] ") + description << std::endl;
456        throw std::runtime_error(description);
457    }
458    if (!(original.getElementAt({1, 2}) == 200)) {
459        std::string description = std::string("testAdvancedViewLifecycle():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(original.getElementAt({1, 2}) == 200)";
460        std::cout << std::string("[FAIL] ") + description << std::endl;
461        throw std::runtime_error(description);
462    }
463    if (!(original.getElementAt({1, 1}) == 300)) {
464        std::string description = std::string("testAdvancedViewLifecycle():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(original.getElementAt({1, 1}) == 300)";
copy (np_test_1_all.cpp:9812)
9802    //original.printArray();
9803
9804    // The modification should be at position (1,1) in original
9805    if (!(original.getElementAt({1, 1}) == 9999)) {
9806        std::string description = std::string("testSliceCopyVsViewMemoryOwnership():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(original.getElementAt({1, 1}) == 9999)";
9807        std::cout << std::string("[FAIL] ") + description << std::endl;
9808        throw std::runtime_error(description);
9809    }
9810    // std::cout << "[OK] Slice view shares memory with original";
9811
9812    // Test slice copy (should be independent)
9813    auto slice_copy = original.sliceArray({{2, 4}, {2, 4}});
9814    // std::cout << "Slice copy [2:4, 2:4]:";
9815    //slice_copy.printArray();
9816
9817    slice_copy.setElementAt({0, 0}, 7777);
9818
9819    // std::cout << "After modifying slice copy at (0,0):" << std::endl;
9820    // std::cout << "Original array:" << std::endl;
9821    //original.printArray();
9822    // std::cout << "Slice copy:" << std::endl;
is_leap_year (np_test_5_all.cpp:22577)
22567        numpy::Timestamp::strptime("", "%Y-%m-%d");
22568      } catch (const std::invalid_argument&) {
22569        threw = true;
22570      }
22571      if (!threw) {
22572        throw std::runtime_error("strptime failed: should throw for empty string");
22573      }
22574
22575      // Test 9: Empty format should throw
22576      threw = false;
22577      try {
22578        numpy::Timestamp::strptime("2024-03-15", "");
22579      } catch (const std::invalid_argument&) {
22580        threw = true;
22581      }
22582      if (!threw) {
22583        throw std::runtime_error("strptime failed: should throw for empty format");
22584      }
22585
22586      // Test 10: Literal percent
22587      numpy::Timestamp ts10 = numpy::Timestamp::strptime("100%2024-03-15", "100%%%Y-%m-%d");
argmax (np_test_3_all.cpp:20521)
20511    auto result = numpy::argmin(arr);
20512    // Should return 1 (index of (1,5))
20513    if (result.getElementAt({0}) != 1) {
20514        throw std::runtime_error("argmin() failed: expected index 1");
20515    }
20516    std::cout << "PASSED\n";
20517}
20518
20519void test_argmax_complex128() {
20520    std::cout << "  Testing argmax() with complex128... ";
20521    numpy::NDArray<complex128> arr({3});
20522    arr.setElementAt({0}, complex128(3.0, 1.0));  // index 0 - largest
20523    arr.setElementAt({1}, complex128(1.0, 5.0));  // index 1
20524    arr.setElementAt({2}, complex128(2.0, 2.0));  // index 2
20525
20526    auto result = numpy::argmax(arr);
20527    // Should return 0 (index of (3,1))
20528    if (result.getElementAt({0}) != 0) {
20529        throw std::runtime_error("argmax() failed: expected index 0");
20530    }
argmin (np_test_3_all.cpp:20506)
20496    if (min_result.getElementAt({0}).real() != 2.0 || min_result.getElementAt({0}).imag() != 1.0) {
20497        throw std::runtime_error("min() tie-breaking failed: expected (2,1)");
20498    }
20499    if (max_result.getElementAt({0}).real() != 2.0 || max_result.getElementAt({0}).imag() != 5.0) {
20500        throw std::runtime_error("max() tie-breaking failed: expected (2,5)");
20501    }
20502    std::cout << "PASSED\n";
20503}
20504
20505void test_argmin_complex128() {
20506    std::cout << "  Testing argmin() with complex128... ";
20507    numpy::NDArray<complex128> arr({3});
20508    arr.setElementAt({0}, complex128(3.0, 1.0));  // index 0
20509    arr.setElementAt({1}, complex128(1.0, 5.0));  // index 1 - smallest
20510    arr.setElementAt({2}, complex128(2.0, 2.0));  // index 2
20511
20512    auto result = numpy::argmin(arr);
20513    // Should return 1 (index of (1,5))
20514    if (result.getElementAt({0}) != 1) {
20515        throw std::runtime_error("argmin() failed: expected index 1");
20516    }
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>())) {
day (np_test_5_all.cpp:22185)
22175                      << std::endl;
22176            errors++;
22177        }
22178
22179        numpy::Timedelta td3("45s");
22180        if (std::abs(td3.total_seconds() - 45.0) > 0.0001) {
22181            std::cout << "[FAIL] np_test_timedelta_edge_cases: '45s' expected 45 sec"
22182                      << std::endl;
22183            errors++;
22184        }
22185
22186        numpy::Timedelta td4("NaT");
22187        if (!td4.isNaT()) {
22188            std::cout << "[FAIL] np_test_timedelta_edge_cases: 'NaT' should parse to NaT"
22189                      << std::endl;
22190            errors++;
22191        }
22192    }
22193
22194    // Stream operator
22195    {
dayofweek (np_test_5_all.cpp:22547)
22537        throw std::runtime_error("strptime failed: American format parsing");
22538      }
22539
22540      // Test 4: 2-digit year
22541      numpy::Timestamp ts4 = numpy::Timestamp::strptime("03/15/24", "%m/%d/%y");
22542      if (ts4.year() != 2024) {
22543        throw std::runtime_error("strptime failed: 2-digit year parsing");
22544      }
22545
22546      // Test 5: With microseconds
22547      numpy::Timestamp ts5 = numpy::Timestamp::strptime("2024-03-15 14:30:45.123456", "%Y-%m-%d %H:%M:%S.%f");
22548      if (ts5.microsecond() != 123456) {
22549        throw std::runtime_error("strptime failed: microseconds parsing");
22550      }
22551
22552      // Test 6: 12-hour format with AM/PM
22553      numpy::Timestamp ts6 = numpy::Timestamp::strptime("03/15/2024 02:30:00 PM", "%m/%d/%Y %I:%M:%S %p");
22554      if (ts6.hour() != 14) {
22555        throw std::runtime_error("strptime failed: 12-hour format parsing");
22556      }
dayofyear (np_test_5_all.cpp:22549)
22539      // Test 4: 2-digit year
22540      numpy::Timestamp ts4 = numpy::Timestamp::strptime("03/15/24", "%m/%d/%y");
22541      if (ts4.year() != 2024) {
22542        throw std::runtime_error("strptime failed: 2-digit year parsing");
22543      }
22544
22545      // Test 5: With microseconds
22546      numpy::Timestamp ts5 = numpy::Timestamp::strptime("2024-03-15 14:30:45.123456", "%Y-%m-%d %H:%M:%S.%f");
22547      if (ts5.microsecond() != 123456) {
22548        throw std::runtime_error("strptime failed: microseconds parsing");
22549      }
22550
22551      // Test 6: 12-hour format with AM/PM
22552      numpy::Timestamp ts6 = numpy::Timestamp::strptime("03/15/2024 02:30:00 PM", "%m/%d/%Y %I:%M:%S %p");
22553      if (ts6.hour() != 14) {
22554        throw std::runtime_error("strptime failed: 12-hour format parsing");
22555      }
22556
22557      // Test 7: Day of year format
22558      numpy::Timestamp ts7 = numpy::Timestamp::strptime("2024-075", "%Y-%j");
days_in_month (np_test_5_all.cpp:22552)
22542      if (ts4.year() != 2024) {
22543        throw std::runtime_error("strptime failed: 2-digit year parsing");
22544      }
22545
22546      // Test 5: With microseconds
22547      numpy::Timestamp ts5 = numpy::Timestamp::strptime("2024-03-15 14:30:45.123456", "%Y-%m-%d %H:%M:%S.%f");
22548      if (ts5.microsecond() != 123456) {
22549        throw std::runtime_error("strptime failed: microseconds parsing");
22550      }
22551
22552      // Test 6: 12-hour format with AM/PM
22553      numpy::Timestamp ts6 = numpy::Timestamp::strptime("03/15/2024 02:30:00 PM", "%m/%d/%Y %I:%M:%S %p");
22554      if (ts6.hour() != 14) {
22555        throw std::runtime_error("strptime failed: 12-hour format parsing");
22556      }
22557
22558      // Test 7: Day of year format
22559      numpy::Timestamp ts7 = numpy::Timestamp::strptime("2024-075", "%Y-%j");
22560      if (ts7.month() != 3 || ts7.day() != 15) {  // Day 75 of 2024 is March 15
22561        throw std::runtime_error("strptime failed: day of year parsing");
22562      }
dtype (np_test_3_all.cpp:7942)
7932  if (info.max != expected_max) {
7933    std::cerr << "[FAIL] IInfo<uint64_t>::max mismatch";
7934    throw std::runtime_error("IInfo uint64 max test failed");
7935  }
7936  // std::cout << "[OK] IInfo<uint64_t>::max = " << info.max << std::endl;
7937
7938  std::cout << " -> tests passed" << std::endl;
7939}
7940
7941// ============================================================================
7942// dtype() Tests - DType descriptor creation
7943// ============================================================================
7944
7945void np_test_dtype_from_string_integers() {
7946  std::cout << "========= np_test_dtype_from_string_integers =======================";
7947
7948  // Test integer type strings
7949  if (dtype("int8") != DType::INT8) {
7950    std::cerr << "[FAIL] dtype(\"int8\") should return INT8";
7951    throw std::runtime_error("dtype string test failed");
7952  }
hour (np_test_5_all.cpp:22186)
22176            errors++;
22177        }
22178
22179        numpy::Timedelta td3("45s");
22180        if (std::abs(td3.total_seconds() - 45.0) > 0.0001) {
22181            std::cout << "[FAIL] np_test_timedelta_edge_cases: '45s' expected 45 sec"
22182                      << std::endl;
22183            errors++;
22184        }
22185
22186        numpy::Timedelta td4("NaT");
22187        if (!td4.isNaT()) {
22188            std::cout << "[FAIL] np_test_timedelta_edge_cases: 'NaT' should parse to NaT"
22189                      << std::endl;
22190            errors++;
22191        }
22192    }
22193
22194    // Stream operator
22195    {
22196        numpy::Timedelta td(1, 2, 30);
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);
month (np_test_5_all.cpp:22185)
22175                      << std::endl;
22176            errors++;
22177        }
22178
22179        numpy::Timedelta td3("45s");
22180        if (std::abs(td3.total_seconds() - 45.0) > 0.0001) {
22181            std::cout << "[FAIL] np_test_timedelta_edge_cases: '45s' expected 45 sec"
22182                      << std::endl;
22183            errors++;
22184        }
22185
22186        numpy::Timedelta td4("NaT");
22187        if (!td4.isNaT()) {
22188            std::cout << "[FAIL] np_test_timedelta_edge_cases: 'NaT' should parse to NaT"
22189                      << std::endl;
22190            errors++;
22191        }
22192    }
22193
22194    // Stream operator
22195    {
nbytes (np_test_2_all.cpp:3547)
3537      }
3538
3539      // Test itemsize
3540      if (!(itemsize(arr) == sizeof(double))) {
3541          std::string description = std::string("testArrayInfo():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(itemsize(arr) == sizeof(double))";
3542          std::cout << std::string("[FAIL] ") + description << std::endl;
3543          throw std::runtime_error(description);
3544      }
3545
3546      // Test nbytes
3547      if (!(nbytes(arr) == 24 * sizeof(double))) {
3548          std::string description = std::string("testArrayInfo():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(nbytes(arr) == 24 * sizeof(double))";
3549          std::cout << std::string("[FAIL] ") + description << std::endl;
3550          throw std::runtime_error(description);
3551      }
3552
3553      // Test flags
3554      auto flags_info = flags(arr);
3555      if (!(flags_info.owndata == true)) {
3556          std::string description = std::string("testArrayInfo():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(flags_info.owndata == true)";
3557          std::cout << std::string("[FAIL] ") + description << std::endl;
ndim (np_test_2_all.cpp:3526)
3516    void testArrayInfo() {
3517      std::cout << "Testing array information functions...\n";
3518
3519      // Test basic info functions
3520      auto arr = createFloat64Array({ 2, 3, 4 });
3521      for (size_t i = 0; i < arr.getSize(); ++i) {
3522        arr.setElementAt({ i / 12, (i / 4) % 3, i % 4 }, static_cast<double>(i));
3523      }
3524
3525      // Test ndim
3526      if (!(ndim(arr) == 3)) {
3527          std::string description = std::string("testArrayInfo():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(ndim(arr) == 3)";
3528          std::cout << std::string("[FAIL] ") + description << std::endl;
3529          throw std::runtime_error(description);
3530      }
3531
3532      // Test size
3533      if (!(size(arr) == 24)) {
3534          std::string description = std::string("testArrayInfo():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !(size(arr) == 24)";
3535          std::cout << std::string("[FAIL] ") + description << std::endl;
3536          throw std::runtime_error(description);
quarter (np_test_5_all.cpp:22551)
22541      numpy::Timestamp ts4 = numpy::Timestamp::strptime("03/15/24", "%m/%d/%y");
22542      if (ts4.year() != 2024) {
22543        throw std::runtime_error("strptime failed: 2-digit year parsing");
22544      }
22545
22546      // Test 5: With microseconds
22547      numpy::Timestamp ts5 = numpy::Timestamp::strptime("2024-03-15 14:30:45.123456", "%Y-%m-%d %H:%M:%S.%f");
22548      if (ts5.microsecond() != 123456) {
22549        throw std::runtime_error("strptime failed: microseconds parsing");
22550      }
22551
22552      // Test 6: 12-hour format with AM/PM
22553      numpy::Timestamp ts6 = numpy::Timestamp::strptime("03/15/2024 02:30:00 PM", "%m/%d/%Y %I:%M:%S %p");
22554      if (ts6.hour() != 14) {
22555        throw std::runtime_error("strptime failed: 12-hour format parsing");
22556      }
22557
22558      // Test 7: Day of year format
22559      numpy::Timestamp ts7 = numpy::Timestamp::strptime("2024-075", "%Y-%j");
22560      if (ts7.month() != 3 || ts7.day() != 15) {  // Day 75 of 2024 is March 15
22561        throw std::runtime_error("strptime failed: day of year parsing");
second (np_test_5_all.cpp:22186)
22176            errors++;
22177        }
22178
22179        numpy::Timedelta td3("45s");
22180        if (std::abs(td3.total_seconds() - 45.0) > 0.0001) {
22181            std::cout << "[FAIL] np_test_timedelta_edge_cases: '45s' expected 45 sec"
22182                      << std::endl;
22183            errors++;
22184        }
22185
22186        numpy::Timedelta td4("NaT");
22187        if (!td4.isNaT()) {
22188            std::cout << "[FAIL] np_test_timedelta_edge_cases: 'NaT' should parse to NaT"
22189                      << std::endl;
22190            errors++;
22191        }
22192    }
22193
22194    // Stream operator
22195    {
22196        numpy::Timedelta td(1, 2, 30);
shape (np_test_1_all.cpp:3751)
3741    }
3742
3743    for (size_t j = 0; j < 3; ++j) {
3744        arr3.setElementAt({0, j}, static_cast<double>((j + 1) * 100));  // [100, 200, 300]
3745    }
3746
3747    // Broadcast all arrays together
3748    std::vector<NDArray<double>> arrays = {arr1, arr2, arr3};
3749    auto broadcasted = broadcast_arrays(arrays);
3750
3751    // All should have shape (2, 3)
3752    for (const auto& arr : broadcasted) {
3753        if (!((arr.getShape() == std::vector<size_t>{2, 3}))) {
3754            std::string description = std::string("test_broadcast_arrays():") + __FILE__ + ":" + std::to_string(__LINE__) + ": !((arr.getShape() == std::vector<size_t>{2, 3}))";
3755            std::cout << std::string("[FAIL] ") + description << std::endl;
3756            throw std::runtime_error(description);
3757        }
3758    }
3759
3760    // Check values
3761    if (!(broadcasted[0].getElementAt({0, 1}) == 2.0)) {
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);
week (np_test_1_all.cpp:27347)
27337      std::cout << "========= busday_offset: forward offset =======================";
27338
27339      // Start on Monday, offset by 5 business days -> should be next Monday
27340      NDArray<datetime64> dates({ 1 });
27341      NDArray<int64_t> offsets({ 1 });
27342      dates.setElementAt({ 0 }, datetime64(19723, DateTimeUnit::Day)); // 2024-01-01 (Monday)
27343      offsets.setElementAt({ 0 }, int64_t(5));
27344
27345      auto result = busday_offset(dates, offsets);
27346
27347      // Expected: Monday + 5 business days = Monday next week (skipping weekend)
27348      datetime64 expected(19730, DateTimeUnit::Day); // 2024-01-08 (Monday)
27349
27350      if (result.getElementAt({ 0 }) != expected) {
27351        std::cout << "  [FAIL] : in test_busday_offset_forward() : incorrect offset result";
27352        throw std::runtime_error("busday_offset forward test failed");
27353      }
27354
27355      std::cout << " -> tests passed" << std::endl;
27356    }
weekday (np_test_5_all.cpp:22772)
22762      // timestamp
22763      double posix = ts.timestamp();
22764      if (posix <= 0) { pass = false; fail_msg = "POSIX timestamp should be positive"; }
22765
22766      // timetuple
22767      auto [y, mo, d, h, mi, s] = ts.timetuple();
22768      if (y != 2024 || mo != 6) { pass = false; fail_msg = "timetuple values incorrect"; }
22769
22770      // date/time tuples
22771      auto [dy, dm, dd] = ts.date();
22772      if (dy != 2024) { pass = false; fail_msg = "date tuple year"; }
22773
22774      auto [th, tmi, ts2, tus] = ts.time();
22775      if (th != 12) { pass = false; fail_msg = "time tuple hour"; }
22776
22777      // Julian date
22778      double jd = ts.to_julian_date();
22779      if (jd < 2400000) { pass = false; fail_msg = "Julian date should be reasonable"; }
22780
22781      // Ordinal
22782      int ord = ts.toordinal();
year (np_test_5_all.cpp:22185)
22175                      << std::endl;
22176            errors++;
22177        }
22178
22179        numpy::Timedelta td3("45s");
22180        if (std::abs(td3.total_seconds() - 45.0) > 0.0001) {
22181            std::cout << "[FAIL] np_test_timedelta_edge_cases: '45s' expected 45 sec"
22182                      << std::endl;
22183            errors++;
22184        }
22185
22186        numpy::Timedelta td4("NaT");
22187        if (!td4.isNaT()) {
22188            std::cout << "[FAIL] np_test_timedelta_edge_cases: 'NaT' should parse to NaT"
22189                      << std::endl;
22190            errors++;
22191        }
22192    }
22193
22194    // Stream operator
22195    {