Skip to content

Commit 8acd137

Browse files
steff456kgryte
andauthored
feat!: refactor API and add C API to math/base/special/cfloor
BREAKING CHANGE: refactor API by removing `out` argument To migrate, users should provide a `Complex128` value to `cfloor`. PR-URL: stdlib-js#973 Co-authored-by: Athan Reines <kgryte@gmail.com> Reviewed-by: Athan Reines <kgryte@gmail.com> Private-ref: stdlib-js/todo#1454
1 parent e041f72 commit 8acd137

23 files changed

Lines changed: 1268 additions & 345 deletions

File tree

lib/node_modules/@stdlib/math/base/special/cfloor/README.md

Lines changed: 146 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ limitations under the License.
2020

2121
# Floor
2222

23-
> Round a complex number toward negative infinity.
23+
> Round a double-precision complex floating-point number toward negative infinity.
2424
2525
<section class="usage">
2626

@@ -30,36 +30,50 @@ limitations under the License.
3030
var cfloor = require( '@stdlib/math/base/special/cfloor' );
3131
```
3232

33-
#### cfloor( \[out,] re, im )
33+
#### cfloor( z )
3434

35-
Rounds a `complex` number comprised of a **real** component `re` and an **imaginary** component `im` toward negative infinity.
35+
Rounds a double-precision complex floating-point number toward negative infinity.
3636

3737
```javascript
38-
var v = cfloor( -4.2, 5.5 );
39-
// returns [ -5.0, 5.0 ]
38+
var Complex128 = require( '@stdlib/complex/float64' );
39+
var real = require( '@stdlib/complex/real' );
40+
var imag = require( '@stdlib/complex/imag' );
4041

41-
v = cfloor( 9.99999, 0.1 );
42-
// returns [ 9.0, 0.0 ]
42+
var v = cfloor( new Complex128( -4.2, 5.5 ) );
43+
// returns <Complex128>
4344

44-
v = cfloor( 0.0, 0.0 );
45-
// returns [ 0.0, 0.0 ]
45+
var re = real( v );
46+
// returns -5.0
4647

47-
v = cfloor( NaN, NaN );
48-
// returns [ NaN, NaN ]
49-
```
48+
var im = imag( v );
49+
// returns 5.0
5050

51-
By default, the function returns real and imaginary components as a two-element `array`. To avoid unnecessary memory allocation, the function supports providing an output (destination) object.
51+
v = cfloor( new Complex128( 9.99999, 0.1 ) );
52+
// returns <Complex128>
5253

53-
```javascript
54-
var Float32Array = require( '@stdlib/array/float32' );
54+
re = real( v );
55+
// returns 9.0
56+
57+
im = imag( v );
58+
// returns 0.0
59+
60+
v = cfloor( new Complex128( 0.0, 0.0 ) );
61+
// returns <Complex128>
62+
63+
re = real( v );
64+
// returns 0.0
5565

56-
var out = new Float32Array( 2 );
66+
im = imag( v );
67+
// returns 0.0
5768

58-
var v = cfloor( out, -4.2, 5.5 );
59-
// returns <Float32Array>[ -5.0, 5.0 ]
69+
v = cfloor( new Complex128( NaN, NaN ) );
70+
// returns <Complex128>
6071

61-
var bool = ( v === out );
62-
// returns true
72+
re = real( v );
73+
// returns NaN
74+
75+
im = imag( v );
76+
// returns NaN
6377
```
6478

6579
</section>
@@ -75,23 +89,19 @@ var bool = ( v === out );
7589
```javascript
7690
var Complex128 = require( '@stdlib/complex/float64' );
7791
var randu = require( '@stdlib/random/base/randu' );
78-
var real = require( '@stdlib/complex/real' );
79-
var imag = require( '@stdlib/complex/imag' );
8092
var cfloor = require( '@stdlib/math/base/special/cfloor' );
8193

8294
var re;
8395
var im;
8496
var z;
85-
var o;
8697
var w;
8798
var i;
8899

89100
for ( i = 0; i < 100; i++ ) {
90101
re = ( randu()*100.0 ) - 50.0;
91102
im = ( randu()*100.0 ) - 50.0;
92103
z = new Complex128( re, im );
93-
o = cfloor( real(z), imag(z) );
94-
w = new Complex128( o[ 0 ], o[ 1 ] );
104+
w = cfloor( z );
95105
console.log( 'floor(%s) = %s', z.toString(), w.toString() );
96106
}
97107
```
@@ -100,6 +110,117 @@ for ( i = 0; i < 100; i++ ) {
100110

101111
<!-- /.examples -->
102112

113+
<!-- C interface documentation. -->
114+
115+
* * *
116+
117+
<section class="c">
118+
119+
## C APIs
120+
121+
<!-- Section to include introductory text. Make sure to keep an empty line after the intro `section` element and another before the `/section` close. -->
122+
123+
<section class="intro">
124+
125+
</section>
126+
127+
<!-- /.intro -->
128+
129+
<!-- C usage documentation. -->
130+
131+
<section class="usage">
132+
133+
### Usage
134+
135+
```c
136+
#include "stdlib/math/base/special/cfloor.h"
137+
```
138+
139+
#### stdlib_base_cfloor( z )
140+
141+
Rounds a double-precision complex floating-point number toward negative infinity.
142+
143+
```c
144+
#include "stdlib/complex/float64.h"
145+
#include "stdlib/complex/real.h"
146+
#include "stdlib/complex/imag.h"
147+
148+
stdlib_complex128_t z = stdlib_complex128( 2.5, -1.5 );
149+
150+
stdlib_complex128_t out = stdlib_base_cfloor( z );
151+
152+
double re = stdlib_real( out );
153+
// returns 2.0
154+
155+
double im = stdlib_imag( out );
156+
// returns -2.0
157+
```
158+
159+
The function accepts the following arguments:
160+
161+
- **z**: `[in] stdlib_complex128_t` input value.
162+
163+
```c
164+
stdlib_complex128_t stdlib_base_cfloor( const stdlib_complex128_t z );
165+
```
166+
167+
</section>
168+
169+
<!-- /.usage -->
170+
171+
<!-- C API usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
172+
173+
<section class="notes">
174+
175+
</section>
176+
177+
<!-- /.notes -->
178+
179+
<!-- C API usage examples. -->
180+
181+
<section class="examples">
182+
183+
### Examples
184+
185+
```c
186+
#include "stdlib/math/base/special/cfloor.h"
187+
#include "stdlib/complex/float64.h"
188+
#include "stdlib/complex/reim.h"
189+
#include <stdio.h>
190+
191+
int main() {
192+
const stdlib_complex128_t x[] = {
193+
stdlib_complex128( 3.14, 1.5 ),
194+
stdlib_complex128( -3.14, -1.5 ),
195+
stdlib_complex128( 0.0, 0.0 ),
196+
stdlib_complex128( 0.0/0.0, 0.0/0.0 )
197+
};
198+
199+
stdlib_complex128_t v;
200+
stdlib_complex128_t y;
201+
double re1;
202+
double im1;
203+
double re2;
204+
double im2;
205+
int i;
206+
for ( i = 0; i < 4; i++ ) {
207+
v = x[ i ];
208+
y = stdlib_base_cfloor( v );
209+
stdlib_reim( v, &re1, &im1 );
210+
stdlib_reim( y, &re2, &im2 );
211+
printf( "cfloor(%lf + %lfi) = %lf + %lfi\n", re1, im1, re2, im2 );
212+
}
213+
}
214+
```
215+
216+
</section>
217+
218+
<!-- /.examples -->
219+
220+
</section>
221+
222+
<!-- /.c -->
223+
103224
<!-- Section for related `stdlib` packages. Do not manually edit this section, as it is automatically populated. -->
104225

105226
<section class="related">

lib/node_modules/@stdlib/math/base/special/cfloor/benchmark/benchmark.js

Lines changed: 15 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@
2222

2323
var bench = require( '@stdlib/bench' );
2424
var randu = require( '@stdlib/random/base/randu' );
25+
var isnan = require( '@stdlib/math/base/assert/is-nan' );
26+
var Complex128 = require( '@stdlib/complex/float64' );
27+
var real = require( '@stdlib/complex/real' );
28+
var imag = require( '@stdlib/complex/imag' );
29+
var uniform = require( '@stdlib/random/base/uniform' );
2530
var isArray = require( '@stdlib/assert/is-array' );
2631
var floor = require( '@stdlib/math/base/special/floor' );
2732
var pkg = require( './../package.json' ).name;
@@ -31,49 +36,25 @@ var cfloor = require( './../lib' );
3136
// MAIN //
3237

3338
bench( pkg, function benchmark( b ) {
34-
var re;
35-
var im;
36-
var y;
37-
var i;
38-
39-
b.tic();
40-
for ( i = 0; i < b.iterations; i++ ) {
41-
re = ( randu()*1000.0 ) - 500.0;
42-
im = ( randu()*1000.0 ) - 500.0;
43-
y = cfloor( re, im );
44-
if ( y.length === 0 ) {
45-
b.fail( 'should not be empty' );
46-
}
47-
}
48-
b.toc();
49-
if ( !isArray( y ) ) {
50-
b.fail( 'should return an array' );
51-
}
52-
b.pass( 'benchmark finished' );
53-
b.end();
54-
});
55-
56-
bench( pkg+'::memory_reuse', function benchmark( b ) {
57-
var out;
58-
var re;
59-
var im;
39+
var values;
6040
var y;
6141
var i;
6242

63-
out = new Array( 2 );
43+
values = [
44+
new Complex128( uniform( -500.0, 500.0 ), uniform( -500.0, 500.0 ) ),
45+
new Complex128( uniform( -500.0, 500.0 ), uniform( -500.0, 500.0 ) )
46+
];
6447

6548
b.tic();
6649
for ( i = 0; i < b.iterations; i++ ) {
67-
re = ( randu()*1000.0 ) - 500.0;
68-
im = ( randu()*1000.0 ) - 500.0;
69-
y = cfloor( out, re, im );
70-
if ( y.length === 0 ) {
71-
b.fail( 'should not be empty' );
50+
y = cfloor( ( values[ i%values.length ] ) );
51+
if ( isnan( real( y ) ) ) {
52+
b.fail( 'should not return NaN' );
7253
}
7354
}
7455
b.toc();
75-
if ( !isArray( y ) ) {
76-
b.fail( 'should return an array' );
56+
if ( isnan( imag( y ) ) ) {
57+
b.fail( 'should not return NaN' );
7758
}
7859
b.pass( 'benchmark finished' );
7960
b.end();
@@ -101,29 +82,3 @@ bench( pkg+'::manual', function benchmark( b ) {
10182
b.pass( 'benchmark finished' );
10283
b.end();
10384
});
104-
105-
bench( pkg+'::manual,memory_reuse', function benchmark( b ) {
106-
var re;
107-
var im;
108-
var y;
109-
var i;
110-
111-
y = new Array( 2 );
112-
113-
b.tic();
114-
for ( i = 0; i < b.iterations; i++ ) {
115-
re = ( randu()*1000.0 ) - 500.0;
116-
im = ( randu()*1000.0 ) - 500.0;
117-
y[ 0 ] = floor( re );
118-
y[ 1 ] = floor( im );
119-
if ( y.length === 0 ) {
120-
b.fail( 'should not be empty' );
121-
}
122-
}
123-
b.toc();
124-
if ( !isArray( y ) ) {
125-
b.fail( 'should return an array' );
126-
}
127-
b.pass( 'benchmark finished' );
128-
b.end();
129-
});
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2023 The Stdlib Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
'use strict';
20+
21+
// MODULES //
22+
23+
var resolve = require( 'path' ).resolve;
24+
var bench = require( '@stdlib/bench' );
25+
var uniform = require( '@stdlib/random/base/uniform' );
26+
var isnan = require( '@stdlib/math/base/assert/is-nan' );
27+
var Complex128 = require( '@stdlib/complex/float64' );
28+
var real = require( '@stdlib/complex/real' );
29+
var tryRequire = require( '@stdlib/utils/try-require' );
30+
var pkg = require( './../package.json' ).name;
31+
32+
33+
// VARIABLES //
34+
35+
var cfloor = tryRequire( resolve( __dirname, './../lib/native.js' ) );
36+
var opts = {
37+
'skip': ( cfloor instanceof Error )
38+
};
39+
40+
41+
// MAIN //
42+
43+
bench( pkg+'::native', opts, function benchmark( b ) {
44+
var values;
45+
var y;
46+
var i;
47+
48+
values = [
49+
new Complex128( uniform( -500.0, 500.0 ), uniform( -500.0, 500.0 ) ),
50+
new Complex128( uniform( -500.0, 500.0 ), uniform( -500.0, 500.0 ) )
51+
];
52+
53+
b.tic();
54+
for ( i = 0; i < b.iterations; i++ ) {
55+
y = cfloor( values[ i%values.length ] );
56+
if ( isnan( real( y ) ) ) {
57+
b.fail( 'should not return NaN' );
58+
}
59+
}
60+
b.toc();
61+
if ( isnan( real( y ) ) ) {
62+
b.fail( 'should not return NaN' );
63+
}
64+
b.pass( 'benchmark finished' );
65+
b.end();
66+
});

0 commit comments

Comments
 (0)