Skip to content

Commit 8619abb

Browse files
committed
feat: add C implementation
--- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: na - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: na - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: passed - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: na - task: lint_typescript_tests status: na - task: lint_license_headers status: passed ---
1 parent 538eb61 commit 8619abb

File tree

5 files changed

+350
-0
lines changed

5 files changed

+350
-0
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2025 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+
#ifndef STDLIB_MATH_BASE_SPECIAL_KERNEL_SINCOS_H
20+
#define STDLIB_MATH_BASE_SPECIAL_KERNEL_SINCOS_H
21+
22+
/*
23+
* If C++, prevent name mangling so that the compiler emits a binary file having undecorated names, thus mirroring the behavior of a C compiler.
24+
*/
25+
#ifdef __cplusplus
26+
extern "C" {
27+
#endif
28+
29+
/**
30+
* Simultaneously computes the sine and cosine of an angle measured in radians on the interval [-π/4, π/4].
31+
*/
32+
void stdlib_base_kernel_sincos( const double x, const double y, double* sine, double* cosine );
33+
34+
#ifdef __cplusplus
35+
}
36+
#endif
37+
38+
#endif // !STDLIB_MATH_BASE_SPECIAL_KERNEL_SINCOS_H
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2025 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 Float64Array = require( '@stdlib/array/float64' );
24+
var addon = require( './../src/addon.node' );
25+
26+
27+
// MAIN //
28+
29+
/**
30+
* Simultaneously computes the sine and cosine of an angle measured in radians on the interval \\( \approx \[-\pi/4, \pi/4\] \\) (except for \\(-0\\)), where \\( \pi/4 \approx 0.7854 \\).
31+
*
32+
* @private
33+
* @param {number} x - input value (in radians, assumed to be bounded by `~π/4` in magnitude)
34+
* @param {number} y - tail of `x`
35+
* @param {Array<number>} out - output array
36+
* @param {integer} stride - output array stride
37+
* @param {NonNegativeInteger} offset - output array index offset
38+
* @returns {Array<number>} sine and cosine
39+
*
40+
* @example
41+
* var v = kernelSincos( 0.0, 0.0 );
42+
* // returns <Float64Array>[ ~0.0, ~1.0 ]
43+
*
44+
* @example
45+
* var v = kernelSincos( 3.141592653589793/2.0, 0.0 );
46+
* // returns <Float64Array>[ ~1.0, ~0.0 ]
47+
*
48+
* @example
49+
* var v = kernelSincos( -3.141592653589793/6.0, 0.0 );
50+
* // returns <Float64Array>[ ~-0.5, ~0.866 ]
51+
*
52+
* @example
53+
* var v = kernelSincos( NaN, 0.0 );
54+
* // returns <Float64Array>[ NaN, NaN ]
55+
*/
56+
function kernelSincos( x, y ) {
57+
var out = new Float64Array( 2 );
58+
addon( x, y, out );
59+
return out;
60+
}
61+
62+
63+
// EXPORTS //
64+
65+
module.exports = kernelSincos;
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#/
2+
# @license Apache-2.0
3+
#
4+
# Copyright (c) 2025 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+
# VARIABLES #
20+
21+
ifndef VERBOSE
22+
QUIET := @
23+
else
24+
QUIET :=
25+
endif
26+
27+
# Determine the OS ([1][1], [2][2]).
28+
#
29+
# [1]: https://en.wikipedia.org/wiki/Uname#Examples
30+
# [2]: http://stackoverflow.com/a/27776822/2225624
31+
OS ?= $(shell uname)
32+
ifneq (, $(findstring MINGW,$(OS)))
33+
OS := WINNT
34+
else
35+
ifneq (, $(findstring MSYS,$(OS)))
36+
OS := WINNT
37+
else
38+
ifneq (, $(findstring CYGWIN,$(OS)))
39+
OS := WINNT
40+
else
41+
ifneq (, $(findstring Windows_NT,$(OS)))
42+
OS := WINNT
43+
endif
44+
endif
45+
endif
46+
endif
47+
48+
49+
# RULES #
50+
51+
#/
52+
# Removes generated files for building an add-on.
53+
#
54+
# @example
55+
# make clean-addon
56+
#/
57+
clean-addon:
58+
$(QUIET) -rm -f *.o *.node
59+
60+
.PHONY: clean-addon
61+
62+
#/
63+
# Removes generated files.
64+
#
65+
# @example
66+
# make clean
67+
#/
68+
clean: clean-addon
69+
70+
.PHONY: clean
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2025 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+
#include "stdlib/math/base/special/kernel_sincos.h"
20+
#include "stdlib/napi/argv.h"
21+
#include "stdlib/napi/argv_double.h"
22+
#include "stdlib/napi/argv_float64array.h"
23+
#include "stdlib/napi/export.h"
24+
#include <node_api.h>
25+
26+
/**
27+
* Receives JavaScript callback invocation data.
28+
*
29+
* @param env environment under which the function is invoked
30+
* @param info callback data
31+
* @return Node-API value
32+
*/
33+
static napi_value addon( napi_env env, napi_callback_info info ) {
34+
STDLIB_NAPI_ARGV( env, info, argv, argc, 3 );
35+
STDLIB_NAPI_ARGV_DOUBLE( env, x, argv, 0 );
36+
STDLIB_NAPI_ARGV_DOUBLE( env, y, argv, 1 );
37+
STDLIB_NAPI_ARGV_FLOAT64ARRAY( env, z, zlen, argv, 2 );
38+
stdlib_base_kernel_sincos( x, y, &z[0], &z[1] );
39+
return NULL;
40+
}
41+
42+
STDLIB_NAPI_MODULE_EXPORT_FCN( addon )
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2025 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+
#include "stdlib/math/base/special/kernel_sincos.h"
20+
21+
static const double S1 = -1.66666666666666324348e-01; // 0xBFC55555, 0x55555549
22+
23+
// BEGIN: polyval_s24
24+
25+
/**
26+
* Evaluates a polynomial.
27+
*
28+
* ## Notes
29+
*
30+
* - The implementation uses [Horner's rule][horners-method] for efficient computation.
31+
*
32+
* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method
33+
*
34+
* @param x value at which to evaluate the polynomial
35+
* @return evaluated polynomial
36+
*/
37+
static double polyval_s24( const double x ) {
38+
return 0.00833333333332249 + (x * (-0.0001984126982985795 + (x * 0.0000027557313707070068)));
39+
}
40+
41+
// END: polyval_s24// BEGIN: polyval_s56
42+
43+
/**
44+
* Evaluates a polynomial.
45+
*
46+
* ## Notes
47+
*
48+
* - The implementation uses [Horner's rule][horners-method] for efficient computation.
49+
*
50+
* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method
51+
*
52+
* @param x value at which to evaluate the polynomial
53+
* @return evaluated polynomial
54+
*/
55+
static double polyval_s56( const double x ) {
56+
return -2.5050760253406863e-8 + (x * 1.58969099521155e-10);
57+
}
58+
59+
// END: polyval_s56// BEGIN: polyval_c13
60+
61+
/**
62+
* Evaluates a polynomial.
63+
*
64+
* ## Notes
65+
*
66+
* - The implementation uses [Horner's rule][horners-method] for efficient computation.
67+
*
68+
* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method
69+
*
70+
* @param x value at which to evaluate the polynomial
71+
* @return evaluated polynomial
72+
*/
73+
static double polyval_c13( const double x ) {
74+
return 0.0416666666666666 + (x * (-0.001388888888887411 + (x * 0.00002480158728947673)));
75+
}
76+
77+
// END: polyval_c13// BEGIN: polyval_c46
78+
79+
/**
80+
* Evaluates a polynomial.
81+
*
82+
* ## Notes
83+
*
84+
* - The implementation uses [Horner's rule][horners-method] for efficient computation.
85+
*
86+
* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method
87+
*
88+
* @param x value at which to evaluate the polynomial
89+
* @return evaluated polynomial
90+
*/
91+
static double polyval_c46( const double x ) {
92+
return -2.7557314351390663e-7 + (x * (2.087572321298175e-9 + (x * -1.1359647557788195e-11)));
93+
}
94+
95+
// END: polyval_c46
96+
97+
/**
98+
* Simultaneously computes the sine and cosine of an angle measured in radians on the interval \\( \approx \[-\pi/4, \pi/4\] \\) (except for \\(-0\\)), where \\( \pi/4 \approx 0.7854 \\).
99+
*
100+
* @param x input value (in radians, assumed to be bounded by `~π/4` in magnitude)
101+
* @param y tail of `x`
102+
* @param sine destination to store the sine
103+
* @param cosine destination to store the cosine
104+
*
105+
* @example
106+
* double x = 0.0;
107+
* double y = 0.0;
108+
*
109+
* double cosine;
110+
* double sine;
111+
* stdlib_base_kernel_sincos( x, y, &sine, &cosine );
112+
*/
113+
void stdlib_base_kernel_sincos( const double x, const double y, double* sine, double* cosine ) {
114+
double hz;
115+
double r;
116+
double v;
117+
double w;
118+
double z;
119+
120+
z = x * x;
121+
w = z * z;
122+
r = polyval_s24( z ) + (z * w * polyval_s56( z ));
123+
v = z * x;
124+
if ( y == 0.0 ) {
125+
*sine = x + (v * (S1 + (z*r)));
126+
} else {
127+
*sine = x - (((z*((0.5*y) - (v*r))) - y) - (v*S1));
128+
}
129+
r = z * polyval_c13( z );
130+
r += w * w * polyval_c46( z );
131+
hz = 0.5 * z;
132+
w = 1.0 - hz;
133+
*cosine = w + ( ((1.0-w) - hz) + ((z*r) - (x*y)) );
134+
return;
135+
}

0 commit comments

Comments
 (0)