Skip to content

Commit 7f215d6

Browse files
committed
Refactor to support complex number objects and add C implementation
1 parent bf1be9d commit 7f215d6

File tree

20 files changed

+930
-458
lines changed

20 files changed

+930
-458
lines changed

lib/node_modules/@stdlib/math/base/ops/csub/README.md

+112-49
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ limitations under the License.
1818
1919
-->
2020

21-
# subtract
21+
# csub
2222

23-
> Subtract two complex numbers.
23+
> Subtract two double-precision complex floating-point numbers.
2424
2525
<section class="intro">
2626

@@ -36,27 +36,26 @@ limitations under the License.
3636
var csub = require( '@stdlib/math/base/ops/csub' );
3737
```
3838

39-
#### csub( \[out,] re1, im1, re2, im2 )
39+
#### csub( z1, z2 )
4040

41-
Subtracts two `complex` numbers where each `complex` number is comprised of a **real** component `re` and an **imaginary** component `im`.
41+
Subtracts two double-precision complex floating-point numbers.
4242

4343
```javascript
44-
var v = csub( 5.0, 3.0, -2.0, 1.0 );
45-
// returns [ 7.0, 2.0 ]
46-
```
44+
var Complex128 = require( '@stdlib/complex/float64' );
45+
var real = require( '@stdlib/complex/real' );
46+
var imag = require( '@stdlib/complex/imag' );
4747

48-
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.
48+
var z1 = new Complex128( 5.0, 3.0 );
49+
var z2 = new Complex128( -2.0, 1.0 );
4950

50-
```javascript
51-
var Float64Array = require( '@stdlib/array/float64' );
51+
var v = csub( z1, z2 );
52+
// returns <Complex128>
5253

53-
var out = new Float64Array( 2 );
54+
var re = real( v );
55+
// returns 7.0
5456

55-
var v = csub( out, 5.0, 3.0, -2.0, 1.0 );
56-
// returns <Float64Array>[ 7.0, 2.0 ]
57-
58-
var bool = ( v === out );
59-
// returns true
57+
var im = imag( v );
58+
// returns 2.0
6059
```
6160

6261
</section>
@@ -71,32 +70,20 @@ var bool = ( v === out );
7170

7271
```javascript
7372
var Complex128 = require( '@stdlib/complex/float64' );
74-
var randu = require( '@stdlib/random/base/randu' );
75-
var round = require( '@stdlib/math/base/special/round' );
76-
var real = require( '@stdlib/complex/real' );
77-
var imag = require( '@stdlib/complex/imag' );
73+
var discreteUniform = require( '@stdlib/random/base/discrete-uniform' ).factory;
7874
var csub = require( '@stdlib/math/base/ops/csub' );
7975

80-
var re;
81-
var im;
76+
var rand;
8277
var z1;
8378
var z2;
8479
var z3;
85-
var o;
8680
var i;
8781

82+
rand = discreteUniform( -50, 50 );
8883
for ( i = 0; i < 100; i++ ) {
89-
re = round( randu()*100.0 ) - 50.0;
90-
im = round( randu()*100.0 ) - 50.0;
91-
z1 = new Complex128( re, im );
92-
93-
re = round( randu()*100.0 ) - 50.0;
94-
im = round( randu()*100.0 ) - 50.0;
95-
z2 = new Complex128( re, im );
96-
97-
o = csub( real(z1), imag(z1), real(z2), imag(z2) );
98-
z3 = new Complex128( o[ 0 ], o[ 1 ] );
99-
84+
z1 = new Complex128( rand(), rand() );
85+
z2 = new Complex128( rand(), rand() );
86+
z3 = csub( z1, z2 );
10087
console.log( '(%s) - (%s) = %s', z1.toString(), z2.toString(), z3.toString() );
10188
}
10289
```
@@ -105,35 +92,111 @@ for ( i = 0; i < 100; i++ ) {
10592

10693
<!-- /.examples -->
10794

108-
<!-- Section for related `stdlib` packages. Do not manually edit this section, as it is automatically populated. -->
109-
110-
<section class="related">
95+
<!-- C interface documentation. -->
11196

11297
* * *
11398

114-
## See Also
99+
<section class="c">
100+
101+
## C APIs
115102

116-
- <span class="package-name">[`@stdlib/math/base/ops/cadd`][@stdlib/math/base/ops/cadd]</span><span class="delimiter">: </span><span class="description">add two complex numbers.</span>
117-
- <span class="package-name">[`@stdlib/math/base/ops/cdiv`][@stdlib/math/base/ops/cdiv]</span><span class="delimiter">: </span><span class="description">divide two complex numbers.</span>
118-
- <span class="package-name">[`@stdlib/math/base/ops/cmul`][@stdlib/math/base/ops/cmul]</span><span class="delimiter">: </span><span class="description">multiply two complex numbers.</span>
103+
<!-- Section to include introductory text. Make sure to keep an empty line after the intro `section` element and another before the `/section` close. -->
104+
105+
<section class="intro">
119106

120107
</section>
121108

122-
<!-- /.related -->
109+
<!-- /.intro -->
123110

124-
<!-- Section for all links. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
111+
<!-- C usage documentation. -->
125112

126-
<section class="links">
113+
<section class="usage">
127114

128-
<!-- <related-links> -->
115+
### Usage
129116

130-
[@stdlib/math/base/ops/cadd]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/math/base/ops/cadd
117+
```c
118+
#include "stdlib/math/base/ops/csub.h"
119+
```
120+
121+
#### stdlib_base_csub( z1, z2 )
131122

132-
[@stdlib/math/base/ops/cdiv]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/math/base/ops/cdiv
123+
Subtracts two double-precision complex floating-point numbers.
133124

134-
[@stdlib/math/base/ops/cmul]: https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/math/base/ops/cmul
125+
```c
126+
#include <complex.h>
135127

136-
<!-- </related-links> -->
128+
double complex z1 = 5.0 + 3.0*I;
129+
double complex z2 = -2.0 + 1.0*I;
130+
131+
double complex out = stdlib_base_csub( z1, z2 );
132+
// returns 7.0+2.0*I
133+
```
134+
135+
The function accepts the following arguments:
136+
137+
- **z1**: `[in] double complex` input value.
138+
- **z2**: `[in] double complex` input value.
139+
140+
```c
141+
double complex stdlib_base_csub( const double complex z1, const double complex z2 );
142+
```
143+
144+
</section>
145+
146+
<!-- /.usage -->
147+
148+
<!-- C API usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
149+
150+
<section class="notes">
151+
152+
</section>
153+
154+
<!-- /.notes -->
155+
156+
<!-- C API usage examples. -->
157+
158+
<section class="examples">
159+
160+
### Examples
161+
162+
```c
163+
#include "stdlib/math/base/ops/csub.h"
164+
#include <stdio.h>
165+
#include <complex.h>
166+
167+
int main() {
168+
double complex x[] = { 3.14+1.5*I, -3.14-1.5*I, 0.0+0.0*I, 0.0/0.0+0.0/0.0*I };
169+
170+
double complex v;
171+
double complex y;
172+
int i;
173+
for ( i = 0; i < 4; i++ ) {
174+
v = x[ i ];
175+
y = stdlib_base_csub( v, v );
176+
printf( "z = %lf + %lfi\ncsub(z, z) = %lf + %lfi\n", creal( v ), cimag( v ), creal( y ), cimag( y ) );
177+
}
178+
}
179+
```
180+
181+
</section>
182+
183+
<!-- /.examples -->
184+
185+
</section>
186+
187+
<!-- /.c -->
188+
189+
<!-- Section for related `stdlib` packages. Do not manually edit this section, as it is automatically populated. -->
190+
191+
<section class="related">
192+
193+
</section>
194+
195+
<!-- /.related -->
196+
197+
<!-- Section for all links. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
198+
199+
<section class="links">
137200

138201
</section>
139202

lib/node_modules/@stdlib/math/base/ops/csub/benchmark/benchmark.js

+18-102
Original file line numberDiff line numberDiff line change
@@ -21,123 +21,39 @@
2121
// MODULES //
2222

2323
var bench = require( '@stdlib/bench' );
24-
var randu = require( '@stdlib/random/base/randu' );
25-
var isArray = require( '@stdlib/assert/is-array' );
24+
var uniform = require( '@stdlib/random/base/uniform' );
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' );
2629
var pkg = require( './../package.json' ).name;
27-
var csub = require( './../lib' );
30+
var sub = require( './../lib' );
2831

2932

3033
// MAIN //
3134

3235
bench( pkg, function benchmark( b ) {
33-
var re1;
34-
var re2;
35-
var im1;
36-
var im2;
37-
var y;
38-
var i;
39-
40-
b.tic();
41-
for ( i = 0; i < b.iterations; i++ ) {
42-
re1 = ( randu()*1000.0 ) - 500.0;
43-
im1 = ( randu()*1000.0 ) - 500.0;
44-
re2 = ( randu()*1000.0 ) - 500.0;
45-
im2 = ( randu()*1000.0 ) - 500.0;
46-
y = csub( re1, im1, re2, im2 );
47-
if ( y.length === 0 ) {
48-
b.fail( 'should not be empty' );
49-
}
50-
}
51-
b.toc();
52-
if ( !isArray( y ) ) {
53-
b.fail( 'should return an array' );
54-
}
55-
b.pass( 'benchmark finished' );
56-
b.end();
57-
});
58-
59-
bench( pkg+'::memory_reuse', function benchmark( b ) {
60-
var re1;
61-
var re2;
62-
var im1;
63-
var im2;
36+
var values;
6437
var out;
65-
var y;
66-
var i;
67-
68-
out = new Array( 2 );
69-
70-
b.tic();
71-
for ( i = 0; i < b.iterations; i++ ) {
72-
re1 = ( randu()*1000.0 ) - 500.0;
73-
im1 = ( randu()*1000.0 ) - 500.0;
74-
re2 = ( randu()*1000.0 ) - 500.0;
75-
im2 = ( randu()*1000.0 ) - 500.0;
76-
y = csub( out, re1, im1, re2, im2 );
77-
if ( y.length === 0 ) {
78-
b.fail( 'should not be empty' );
79-
}
80-
}
81-
b.toc();
82-
if ( !isArray( y ) ) {
83-
b.fail( 'should return an array' );
84-
}
85-
b.pass( 'benchmark finished' );
86-
b.end();
87-
});
88-
89-
bench( pkg+'::built-in', function benchmark( b ) {
90-
var re1;
91-
var re2;
92-
var im1;
93-
var im2;
94-
var y;
95-
var i;
96-
97-
b.tic();
98-
for ( i = 0; i < b.iterations; i++ ) {
99-
re1 = ( randu()*1000.0 ) - 500.0;
100-
im1 = ( randu()*1000.0 ) - 500.0;
101-
re2 = ( randu()*1000.0 ) - 500.0;
102-
im2 = ( randu()*1000.0 ) - 500.0;
103-
y = [ re1-re2, im1-im2 ];
104-
if ( y.length === 0 ) {
105-
b.fail( 'should not be empty' );
106-
}
107-
}
108-
b.toc();
109-
if ( !isArray( y ) ) {
110-
b.fail( 'should return an array' );
111-
}
112-
b.pass( 'benchmark finished' );
113-
b.end();
114-
});
115-
116-
bench( pkg+'::built-in,memory_reuse', function benchmark( b ) {
117-
var re1;
118-
var re2;
119-
var im1;
120-
var im2;
121-
var y;
38+
var z;
12239
var i;
12340

124-
y = new Array( 2 );
41+
values = [
42+
new Complex128( uniform( -500.0, 500.0 ), uniform( -500.0, 500.0 ) ),
43+
new Complex128( uniform( -500.0, 500.0 ), uniform( -500.0, 500.0 ) )
44+
];
12545

12646
b.tic();
12747
for ( i = 0; i < b.iterations; i++ ) {
128-
re1 = ( randu()*1000.0 ) - 500.0;
129-
im1 = ( randu()*1000.0 ) - 500.0;
130-
re2 = ( randu()*1000.0 ) - 500.0;
131-
im2 = ( randu()*1000.0 ) - 500.0;
132-
y[ 0 ] = re1 - re2;
133-
y[ 1 ] = im1 - im2;
134-
if ( y.length === 0 ) {
135-
b.fail( 'should not be empty' );
48+
z = values[ i%values.length ];
49+
out = sub( z, z );
50+
if ( typeof out !== 'object' ) {
51+
b.fail( 'should return an object' );
13652
}
13753
}
13854
b.toc();
139-
if ( !isArray( y ) ) {
140-
b.fail( 'should return an array' );
55+
if ( isnan( real( out ) ) || isnan( imag( out ) ) ) {
56+
b.fail( 'should not return NaN' );
14157
}
14258
b.pass( 'benchmark finished' );
14359
b.end();

0 commit comments

Comments
 (0)