Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 167 additions & 0 deletions lib/node_modules/@stdlib/blas/ext/base/ndarray/dcusumkbn/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,173 @@ console.log( ndarray2array( v ) );

<!-- /.references -->

<!-- C interface documentation. -->

* * *

<section class="c">

## C APIs

<section class="intro">

</section>

<!-- /.intro -->

<section class="usage">

### Usage

```c
#include "stdlib/blas/ext/base/ndarray/dcusumkbn.h"
```

#### stdlib_blas_ext_dcusumkbn( arrays )

Computes the cumulative sum of a one-dimensional double-precision floating-point ndarray using an improved Kahan–Babuška algorithm.

```c
#include "stdlib/ndarray/ctor.h"
#include "stdlib/ndarray/dtypes.h"
#include "stdlib/ndarray/index_modes.h"
#include "stdlib/ndarray/orders.h"
#include "stdlib/ndarray/base/bytes_per_element.h"
#include <stdint.h>

// Create one-dimensional input and output ndarrays:
const double dataX[] = { 1.0e16, 1.0, -1.0e16 };
double dataY[] = { 0.0, 0.0, 0.0 };
int64_t shape[] = { 3 };
int64_t strides[] = { STDLIB_NDARRAY_FLOAT64_BYTES_PER_ELEMENT };
int8_t submodes[] = { STDLIB_NDARRAY_INDEX_ERROR };

struct ndarray *x = stdlib_ndarray_allocate( STDLIB_NDARRAY_FLOAT64, (uint8_t *)dataX, 1, shape, strides, 0, STDLIB_NDARRAY_ROW_MAJOR, STDLIB_NDARRAY_INDEX_ERROR, 1, submodes );
struct ndarray *y = stdlib_ndarray_allocate( STDLIB_NDARRAY_FLOAT64, (uint8_t *)dataY, 1, shape, strides, 0, STDLIB_NDARRAY_ROW_MAJOR, STDLIB_NDARRAY_INDEX_ERROR, 1, submodes );

// Create a zero-dimensional ndarray containing the initial sum:
const double dataInitial[] = { 0.0 };
int64_t scalarStrides[] = { 0 };
struct ndarray *initial = stdlib_ndarray_allocate( STDLIB_NDARRAY_FLOAT64, (uint8_t *)dataInitial, 0, NULL, scalarStrides, 0, STDLIB_NDARRAY_ROW_MAJOR, STDLIB_NDARRAY_INDEX_ERROR, 1, submodes );

// Perform computation:
const struct ndarray *arrays[] = { x, y, initial };
stdlib_blas_ext_dcusumkbn( arrays );
// dataY => { 1.0e16, 1.0e16, 1.0 }

// Free allocated memory:
stdlib_ndarray_free( x );
stdlib_ndarray_free( y );
stdlib_ndarray_free( initial );
```

The function accepts the following arguments:

- **arrays**: `[in] const struct ndarray**` list containing the following ndarrays:

- `[in] const struct ndarray*` a one-dimensional double-precision floating-point input ndarray.
- `[out] const struct ndarray*` a one-dimensional double-precision floating-point output ndarray.
- `[in] const struct ndarray*` a zero-dimensional double-precision floating-point ndarray containing the initial sum.

```c
void stdlib_blas_ext_dcusumkbn( const struct ndarray *arrays[] );
```

</section>

<!-- /.usage -->

<section class="notes">

### Notes

- The function writes cumulative sums to the output ndarray and returns no value.
- The input ndarray's length determines the number of elements to process. The caller must provide valid data buffers and an output ndarray containing at least that many elements.
- The function reads the initial sum at the zero-dimensional ndarray's own byte offset before writing output elements.
- If provided an empty input ndarray, the function leaves the output ndarray unchanged.
- The function supports positive, negative, and zero strides. Input and output buffers may overlap; each input element is read before the corresponding output element is written, following the existing strided cumulative-sum implementation's sequential semantics.
- Byte strides and byte offsets must be aligned for double-precision floating-point elements. Element strides, offsets, and all indexed and post-increment positions must be representable using the configured `CBLAS_INT` type. Invalid or unrepresentable ndarray metadata leaves the output ndarray unchanged.
- The implementation reuses the improved Kahan–Babuška algorithm described by Neumaier (1974).

</section>

<!-- /.notes -->

<section class="examples">

### Examples

```c
#include "stdlib/blas/ext/base/ndarray/dcusumkbn.h"
#include "stdlib/ndarray/ctor.h"
#include "stdlib/ndarray/dtypes.h"
#include "stdlib/ndarray/index_modes.h"
#include "stdlib/ndarray/orders.h"
#include "stdlib/ndarray/base/bytes_per_element.h"
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>

int main( void ) {
// Create data buffers:
const double dataX[] = { 1.0e16, 1.0, -1.0e16 };
double dataY[] = { 0.0, 0.0, 0.0 };
const double dataInitial[] = { 123.0, 0.0 };

// Specify the ndarray metadata:
int64_t shape[] = { 3 };
int64_t strides[] = { STDLIB_NDARRAY_FLOAT64_BYTES_PER_ELEMENT };
int64_t scalarStrides[] = { 0 };
int8_t submodes[] = { STDLIB_NDARRAY_INDEX_ERROR };
const enum STDLIB_NDARRAY_ORDER order = STDLIB_NDARRAY_ROW_MAJOR;
const enum STDLIB_NDARRAY_INDEX_MODE imode = STDLIB_NDARRAY_INDEX_ERROR;

// Create one-dimensional input and output ndarrays:
struct ndarray *x = stdlib_ndarray_allocate( STDLIB_NDARRAY_FLOAT64, (uint8_t *)dataX, 1, shape, strides, 0, order, imode, 1, submodes );
struct ndarray *y = stdlib_ndarray_allocate( STDLIB_NDARRAY_FLOAT64, (uint8_t *)dataY, 1, shape, strides, 0, order, imode, 1, submodes );

// Select an initial sum of zero at the scalar's own byte offset:
struct ndarray *initial = stdlib_ndarray_allocate( STDLIB_NDARRAY_FLOAT64, (uint8_t *)dataInitial, 0, NULL, scalarStrides, STDLIB_NDARRAY_FLOAT64_BYTES_PER_ELEMENT, order, imode, 1, submodes );
int status = EXIT_SUCCESS;
if ( x == NULL || y == NULL || initial == NULL ) {
fprintf( stderr, "Error allocating ndarray descriptors.\n" );
status = EXIT_FAILURE;
} else {
const struct ndarray *arrays[] = { x, y, initial };
stdlib_blas_ext_dcusumkbn( arrays );

// Compensated summation retains the unit term after cancellation:
if ( dataY[ 0 ] != 1.0e16 || dataY[ 1 ] != 1.0e16 || dataY[ 2 ] != 1.0 ) {
fprintf( stderr, "Unexpected cumulative sum.\n" );
status = EXIT_FAILURE;
}
for ( int i = 0; i < 3; i++ ) {
printf( "y[ %i ] = %.17g\n", i, dataY[ i ] );
}
}

// Free any successfully allocated descriptors:
if ( x != NULL ) {
stdlib_ndarray_free( x );
}
if ( y != NULL ) {
stdlib_ndarray_free( y );
}
if ( initial != NULL ) {
stdlib_ndarray_free( initial );
}
return status;
}
```

</section>

<!-- /.examples -->

</section>

<!-- /.c -->

<!-- Section for related `stdlib` packages. Do not manually edit this section, as it is automatically populated. -->

<section class="related">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/**
* @license Apache-2.0
*
* Copyright (c) 2025 The Stdlib Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

// MODULES //

var resolve = require( 'path' ).resolve;
var bench = require( '@stdlib/bench' );
var tryRequire = require( '@stdlib/utils/try-require' );
var uniform = require( '@stdlib/random/uniform' );
var Float64Vector = require( '@stdlib/ndarray/vector/float64' );
var isnan = require( '@stdlib/math/base/assert/is-nan' );
var pow = require( '@stdlib/math/base/special/pow' );
var scalar2ndarray = require( '@stdlib/ndarray/from-scalar' );
var format = require( '@stdlib/string/format' );
var pkg = require( './../package.json' ).name;
var dcusumkbn = tryRequire( resolve( __dirname, './../lib/native.js' ) );


// VARIABLES //

var options = {
'dtype': 'float64'
};


// FUNCTIONS //

/**
* Creates a benchmark function.
*
* @private
* @param {PositiveInteger} len - array length
* @returns {Function} benchmark function
*/
function createBenchmark( len ) {
var initial = scalar2ndarray( 0.0, options );
var x = uniform( [ len ], -10.0, 10.0, options );
var y = new Float64Vector( len );
return benchmark;

/**
* Benchmark function.
*
* @private
* @param {Benchmark} b - benchmark instance
*/
function benchmark( b ) {
var v;
var i;

b.tic();
for ( i = 0; i < b.iterations; i++ ) {
v = dcusumkbn( [ x, y, initial ] );
if ( typeof v !== 'object' ) {
b.fail( 'should return an ndarray' );
}
}
b.toc();
if ( isnan( v.get( i%len ) ) ) {
b.fail( 'should not return NaN' );
}
b.pass( 'benchmark finished' );
b.end();
}
}


// MAIN //

/**
* Main execution sequence.
*
* @private
*/
function main() {
var len;
var min;
var max;
var f;
var i;

min = 1; // 10^min
max = 6; // 10^max

for ( i = min; i <= max; i++ ) {
len = pow( 10, i );
f = createBenchmark( len );
bench( format( '%s:len=%d,native', pkg, len ), {
'skip': dcusumkbn instanceof Error
}, f );
}
}

main();
Loading
Loading