@stdlib/math-base-special-sincosf 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +192 -0
- package/NOTICE +1 -0
- package/README.md +292 -0
- package/SECURITY.md +5 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +7 -0
- package/docs/types/index.d.ts +100 -0
- package/include/stdlib/math/base/special/sincosf.h +38 -0
- package/lib/assign.js +223 -0
- package/lib/index.js +68 -0
- package/lib/main.js +57 -0
- package/lib/native.js +61 -0
- package/manifest.json +90 -0
- package/package.json +87 -0
- package/src/addon.c +41 -0
- package/src/main.c +175 -0
package/src/main.c
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
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/sincosf.h"
|
|
20
|
+
#include "stdlib/math/base/special/kernel_sincosf.h"
|
|
21
|
+
#include "stdlib/math/base/special/rempio2f.h"
|
|
22
|
+
#include "stdlib/constants/float64/half_pi.h"
|
|
23
|
+
#include "stdlib/constants/float32/abs_mask.h"
|
|
24
|
+
#include "stdlib/constants/float32/exponent_mask.h"
|
|
25
|
+
#include "stdlib/number/float32/base/to_word.h"
|
|
26
|
+
#include <stdint.h>
|
|
27
|
+
|
|
28
|
+
// PI/4 = 0.7853981256484985 => 0 01111110 10010010000111111011010 => 0x3f490fda = 1061752768
|
|
29
|
+
static const int32_t PIO4_WORD = 0x3f490fda;
|
|
30
|
+
|
|
31
|
+
// 3*PI/4 = 2.356194257736206 => 0 10000000 00101101100101111100011 => 0x4016cbe3 = 1075235811
|
|
32
|
+
static const int32_t THREE_PIO4_WORD = 0x4016cbe3;
|
|
33
|
+
|
|
34
|
+
// 5*PI/4 = 3.9269907474517822 => 0 10000000 11110110101001111010001 => 0x407b53d1 = 1081824209
|
|
35
|
+
static const int32_t FIVE_PIO4_WORD = 0x407b53d1;
|
|
36
|
+
|
|
37
|
+
// 7*PI/4 = 5.497786998748779 => 0 10000001 01011111110110111011111 => 0x40afeddf = 1085271519
|
|
38
|
+
static const int32_t SEVEN_PIO4_WORD = 0x40afeddf;
|
|
39
|
+
|
|
40
|
+
// 9*PI/4 = 7.068583011627197 => 0 10000001 11000100011000111010101 => 0x40e231d5 = 1088565717
|
|
41
|
+
static const int32_t NINE_PIO4_WORD = 0x40e231d5;
|
|
42
|
+
|
|
43
|
+
// 2^-12 = 0.000244140625 => 0 01110011 00000000000000000000000 => 0x39800000 = 964689920
|
|
44
|
+
static const int32_t SMALL_WORD = 0x39800000;
|
|
45
|
+
|
|
46
|
+
// Small multiples of PI/2 in double-precision floating-point format:
|
|
47
|
+
static const double PIO2 = STDLIB_CONSTANT_FLOAT64_HALF_PI; // 0x3FF921FB, 0x54442D18
|
|
48
|
+
static const double PI = 2.0 * STDLIB_CONSTANT_FLOAT64_HALF_PI; // 0x400921FB, 0x54442D18
|
|
49
|
+
static const double THREE_PIO2 = 3.0 * STDLIB_CONSTANT_FLOAT64_HALF_PI; // 0x4012D97C, 0x7F3321D2
|
|
50
|
+
static const double TWO_PI = 4.0 * STDLIB_CONSTANT_FLOAT64_HALF_PI; // 0x401921FB, 0x54442D18
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Simultaneously computes the sine and cosine of a single-precision floating-point number (in radians).
|
|
54
|
+
*
|
|
55
|
+
* ## Method
|
|
56
|
+
*
|
|
57
|
+
* - Let \\(S\\), \\(C\\), and \\(T\\) denote the \\(\sin\\), \\(\cos\\) and \\(\tan\\), respectively, on \\(\[-\pi/4, +\pi/4\]\\).
|
|
58
|
+
*
|
|
59
|
+
* - Reduce the argument \\(x\\) to \\(y = x-k\pi/2\\) in \\(\[-\pi/4, +\pi/4\]\\), and let \\(n = k \mod 4\\).
|
|
60
|
+
*
|
|
61
|
+
* - We have
|
|
62
|
+
*
|
|
63
|
+
* | n | sin(x) | cos(x) | tan(x) |
|
|
64
|
+
* | - | ------ | ------ | ------ |
|
|
65
|
+
* | 0 | S | C | T |
|
|
66
|
+
* | 1 | C | -S | -1/T |
|
|
67
|
+
* | 2 | -S | -C | T |
|
|
68
|
+
* | 3 | -C | S | -1/T |
|
|
69
|
+
*
|
|
70
|
+
* @param x input value
|
|
71
|
+
* @param sine destination to store the sine
|
|
72
|
+
* @param cosine destination to store the cosine
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* float x = 0.0f;
|
|
76
|
+
*
|
|
77
|
+
* float cosine;
|
|
78
|
+
* float sine;
|
|
79
|
+
* stdlib_base_sincosf( x, &sine, &cosine );
|
|
80
|
+
*/
|
|
81
|
+
void stdlib_base_sincosf( const float x, float* sine, float* cosine ) {
|
|
82
|
+
uint32_t uix;
|
|
83
|
+
int32_t ix;
|
|
84
|
+
int32_t n;
|
|
85
|
+
float tmp;
|
|
86
|
+
double y;
|
|
87
|
+
|
|
88
|
+
stdlib_base_float32_to_word( x, &uix );
|
|
89
|
+
ix = (int32_t)uix;
|
|
90
|
+
ix &= STDLIB_CONSTANT_FLOAT32_ABS_MASK;
|
|
91
|
+
|
|
92
|
+
// Case: |x| ~<= π/4
|
|
93
|
+
if ( ix <= PIO4_WORD ) {
|
|
94
|
+
// Case: |x| < 2^-12
|
|
95
|
+
if ( ix < SMALL_WORD ) {
|
|
96
|
+
if ( (int32_t)x == 0 ) {
|
|
97
|
+
*sine = x;
|
|
98
|
+
*cosine = 1.0f;
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
stdlib_base_kernel_sincosf( (double)x, sine, cosine );
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
// Case: |x| ~<= 5π/4
|
|
106
|
+
if ( ix <= FIVE_PIO4_WORD ) {
|
|
107
|
+
// Case: |x| ~<= 3π/4
|
|
108
|
+
if ( ix <= THREE_PIO4_WORD ) {
|
|
109
|
+
if ( (int32_t)uix > 0 ) {
|
|
110
|
+
stdlib_base_kernel_sincosf( (double)x - PIO2, cosine, sine );
|
|
111
|
+
*cosine = -( *cosine );
|
|
112
|
+
} else {
|
|
113
|
+
stdlib_base_kernel_sincosf( (double)x + PIO2, cosine, sine );
|
|
114
|
+
*sine = -( *sine );
|
|
115
|
+
}
|
|
116
|
+
} else {
|
|
117
|
+
if ( (int32_t)uix > 0 ) {
|
|
118
|
+
stdlib_base_kernel_sincosf( (double)x - PI, sine, cosine );
|
|
119
|
+
} else {
|
|
120
|
+
stdlib_base_kernel_sincosf( (double)x + PI, sine, cosine );
|
|
121
|
+
}
|
|
122
|
+
*sine = -( *sine );
|
|
123
|
+
*cosine = -( *cosine );
|
|
124
|
+
}
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
// Case: |x| ~<= 9π/4
|
|
128
|
+
if ( ix <= NINE_PIO4_WORD ) {
|
|
129
|
+
// Case: |x| ~<= 7π/4
|
|
130
|
+
if ( ix <= SEVEN_PIO4_WORD ) {
|
|
131
|
+
if ( (int32_t)uix > 0 ) {
|
|
132
|
+
stdlib_base_kernel_sincosf( (double)x - THREE_PIO2, cosine, sine );
|
|
133
|
+
*sine = -( *sine );
|
|
134
|
+
} else {
|
|
135
|
+
stdlib_base_kernel_sincosf( (double)x + THREE_PIO2, cosine, sine );
|
|
136
|
+
*cosine = -( *cosine );
|
|
137
|
+
}
|
|
138
|
+
} else if ( (int32_t)uix > 0 ) {
|
|
139
|
+
stdlib_base_kernel_sincosf( (double)x - TWO_PI, sine, cosine );
|
|
140
|
+
} else {
|
|
141
|
+
stdlib_base_kernel_sincosf( (double)x + TWO_PI, sine, cosine );
|
|
142
|
+
}
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
// Case: x is NaN or infinity
|
|
146
|
+
if ( ix >= STDLIB_CONSTANT_FLOAT32_EXPONENT_MASK ) {
|
|
147
|
+
*sine = 0.0f / 0.0f; // NaN
|
|
148
|
+
*cosine = 0.0f / 0.0f; // NaN
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
// Argument reduction...
|
|
152
|
+
n = stdlib_base_rempio2f( x, &y );
|
|
153
|
+
|
|
154
|
+
// Compute the sine and cosine together:
|
|
155
|
+
stdlib_base_kernel_sincosf( y, sine, cosine );
|
|
156
|
+
|
|
157
|
+
switch ( n & 3 ) {
|
|
158
|
+
case 0:
|
|
159
|
+
return;
|
|
160
|
+
case 1:
|
|
161
|
+
tmp = *cosine;
|
|
162
|
+
*cosine = -( *sine );
|
|
163
|
+
*sine = tmp;
|
|
164
|
+
return;
|
|
165
|
+
case 2:
|
|
166
|
+
*sine = -( *sine );
|
|
167
|
+
*cosine = -( *cosine );
|
|
168
|
+
return;
|
|
169
|
+
default:
|
|
170
|
+
tmp = -( *cosine );
|
|
171
|
+
*cosine = *sine;
|
|
172
|
+
*sine = tmp;
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
}
|