@stdlib/math-base-special-trigammaf 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/src/main.c ADDED
@@ -0,0 +1,215 @@
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
+ * ## Notice
20
+ *
21
+ * The original C++ code and copyright notice are from the [Boost library]{@link http://www.boost.org/doc/libs/1_88_0/boost/math/special_functions/trigamma.hpp}. The implementation follows the original but has been reformatted and modified for use in stdlib.
22
+ *
23
+ * ```text
24
+ * (C) Copyright John Maddock 2006.
25
+ *
26
+ * Use, modification and distribution are subject to the
27
+ * Boost Software License, Version 1.0. (See accompanying file
28
+ * LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
29
+ * ```
30
+ */
31
+
32
+ #include "stdlib/math/base/special/trigammaf.h"
33
+ #include "stdlib/math/base/special/absf.h"
34
+ #include "stdlib/math/base/special/floorf.h"
35
+ #include "stdlib/math/base/special/sinpif.h"
36
+ #include "stdlib/constants/float32/pi_squared.h"
37
+
38
+ static const float YOFFSET12 = 2.1093254089355469f;
39
+
40
+ /* Begin auto-generated functions. The following functions are auto-generated. Do not edit directly. */
41
+
42
+ // BEGIN: rational_p12q12
43
+
44
+ /**
45
+ * Evaluates a rational function (i.e., the ratio of two polynomials described by the coefficients stored in \\(P\\) and \\(Q\\)).
46
+ *
47
+ * ## Notes
48
+ *
49
+ * - Coefficients should be sorted in ascending degree.
50
+ * - The implementation uses [Horner's rule][horners-method] for efficient computation.
51
+ *
52
+ * [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method
53
+ *
54
+ * @param x value at which to evaluate the rational function
55
+ * @return evaluated rational function
56
+ */
57
+ static float rational_p12q12( const float x ) {
58
+ float ax;
59
+ float ix;
60
+ float s1;
61
+ float s2;
62
+ if ( x == 0.0f ) {
63
+ return -1.1093280605946045f;
64
+ }
65
+ if ( x < 0.0f ) {
66
+ ax = -x;
67
+ } else {
68
+ ax = x;
69
+ }
70
+ if ( ax <= 1.0f ) {
71
+ s1 = -1.1093280605946045f + (x * (-3.831067447261932f + (x * (-3.3703848401898284f + (x * (0.2808057446798121f + (x * (1.6638069578676165f + (x * 0.6446838681910284f)))))))));
72
+ s2 = 1.0f + (x * (3.453538966854115f + (x * (4.520892698785143f + (x * (2.701273417835153f + (x * (0.6446879839978561f + (x * -2.0314516859987727e-7f)))))))));
73
+ } else {
74
+ ix = 1.0f / x;
75
+ s1 = 0.6446838681910284f + (ix * (1.6638069578676165f + (ix * (0.2808057446798121f + (ix * (-3.3703848401898284f + (ix * (-3.831067447261932f + (ix * -1.1093280605946045f)))))))));
76
+ s2 = -2.0314516859987727e-7f + (ix * (0.6446879839978561f + (ix * (2.701273417835153f + (ix * (4.520892698785143f + (ix * (3.453538966854115f + (ix * 1.0f)))))))));
77
+ }
78
+ return s1 / s2;
79
+ }
80
+
81
+ // END: rational_p12q12
82
+
83
+ // BEGIN: rational_p24q24
84
+
85
+ /**
86
+ * Evaluates a rational function (i.e., the ratio of two polynomials described by the coefficients stored in \\(P\\) and \\(Q\\)).
87
+ *
88
+ * ## Notes
89
+ *
90
+ * - Coefficients should be sorted in ascending degree.
91
+ * - The implementation uses [Horner's rule][horners-method] for efficient computation.
92
+ *
93
+ * [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method
94
+ *
95
+ * @param x value at which to evaluate the rational function
96
+ * @return evaluated rational function
97
+ */
98
+ static float rational_p24q24( const float x ) {
99
+ float ax;
100
+ float ix;
101
+ float s1;
102
+ float s2;
103
+ if ( x == 0.0f ) {
104
+ return -1.3803835004508848e-8f;
105
+ }
106
+ if ( x < 0.0f ) {
107
+ ax = -x;
108
+ } else {
109
+ ax = x;
110
+ }
111
+ if ( ax <= 1.0f ) {
112
+ s1 = -1.3803835004508848e-8f + (x * (0.5000004915854026f + (x * (1.6077979838469347f + (x * (2.5645435828098253f + (x * (2.0534873203680393f + (x * 0.7456698111156592f)))))))));
113
+ s2 = 1.0f + (x * (2.882278766237617f + (x * (4.168166055409092f + (x * (2.7853527819234465f + (x * (0.7496767184804479f + (x * -0.0005706911241624681f)))))))));
114
+ } else {
115
+ ix = 1.0f / x;
116
+ s1 = 0.7456698111156592f + (ix * (2.0534873203680393f + (ix * (2.5645435828098253f + (ix * (1.6077979838469347f + (ix * (0.5000004915854026f + (ix * -1.3803835004508848e-8f)))))))));
117
+ s2 = -0.0005706911241624681f + (ix * (0.7496767184804479f + (ix * (2.7853527819234465f + (ix * (4.168166055409092f + (ix * (2.882278766237617f + (ix * 1.0f)))))))));
118
+ }
119
+ return s1 / s2;
120
+ }
121
+
122
+ // END: rational_p24q24
123
+
124
+ // BEGIN: rational_p4infq4inf
125
+
126
+ /**
127
+ * Evaluates a rational function (i.e., the ratio of two polynomials described by the coefficients stored in \\(P\\) and \\(Q\\)).
128
+ *
129
+ * ## Notes
130
+ *
131
+ * - Coefficients should be sorted in ascending degree.
132
+ * - The implementation uses [Horner's rule][horners-method] for efficient computation.
133
+ *
134
+ * [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method
135
+ *
136
+ * @param x value at which to evaluate the rational function
137
+ * @return evaluated rational function
138
+ */
139
+ static float rational_p4infq4inf( const float x ) {
140
+ float ax;
141
+ float ix;
142
+ float s1;
143
+ float s2;
144
+ if ( x == 0.0f ) {
145
+ return 6.894758194870125e-18f;
146
+ }
147
+ if ( x < 0.0f ) {
148
+ ax = -x;
149
+ } else {
150
+ ax = x;
151
+ }
152
+ if ( ax <= 1.0f ) {
153
+ s1 = 6.894758194870125e-18f + (x * (0.49999999999998973f + (x * (1.0177274392923794f + (x * (2.498208511343429f + (x * (2.1921221359427596f + (x * (1.5897035272532765f + (x * 0.40154388356961734f)))))))))));
154
+ s2 = 1.0f + (x * (1.7021215452463931f + (x * (4.4290431747556465f + (x * (2.9745631894384923f + (x * (2.3013614809773615f + (x * (0.28360399799075753f + (x * 0.022892987908906898f)))))))))));
155
+ } else {
156
+ ix = 1.0f / x;
157
+ s1 = 0.40154388356961734f + (ix * (1.5897035272532765f + (ix * (2.1921221359427596f + (ix * (2.498208511343429f + (ix * (1.0177274392923794f + (ix * (0.49999999999998973f + (ix * 6.894758194870125e-18f)))))))))));
158
+ s2 = 0.022892987908906898f + (ix * (0.28360399799075753f + (ix * (2.3013614809773615f + (ix * (2.9745631894384923f + (ix * (4.4290431747556465f + (ix * (1.7021215452463931f + (ix * 1.0f)))))))))));
159
+ }
160
+ return s1 / s2;
161
+ }
162
+
163
+ // END: rational_p4infq4inf
164
+
165
+ /* End auto-generated functions. */
166
+
167
+ /**
168
+ * Evaluates the trigamma function for a single-precision floating-point number.
169
+ *
170
+ * @param x input value
171
+ * @return function value
172
+ *
173
+ * @example
174
+ * float v = stdlib_base_trigammaf( -2.5f );
175
+ * // returns ~9.539f
176
+ */
177
+ float stdlib_base_trigammaf( const float x ) {
178
+ float result;
179
+ float xc;
180
+ float s;
181
+ float y;
182
+ float z;
183
+
184
+ result = 0.0f;
185
+
186
+ // Check for negative arguments and use reflection:
187
+ if ( x <= 0.0f ) {
188
+ if ( stdlib_base_floorf( x ) == x ) {
189
+ return 0.0f / 0.0f; // NaN
190
+ }
191
+ // Reflect:
192
+ z = 1.0f - x;
193
+ if ( z < 1.0f ) {
194
+ result = 1.0f / ( z * z );
195
+ z += 1.0f;
196
+ }
197
+ s = ( stdlib_base_absf( x ) < stdlib_base_absf( z ) ) ? stdlib_base_sinpif( x ) : stdlib_base_sinpif( z );
198
+ return result - stdlib_base_trigammaf( z ) + ( STDLIB_CONSTANT_FLOAT32_PI_SQUARED / ( s*s ) );
199
+ }
200
+ xc = x;
201
+ if ( xc < 1.0f ) {
202
+ result = 1.0f / ( xc*xc );
203
+ xc += 1.0f;
204
+ }
205
+ if ( xc <= 2.0f ) {
206
+ result += ( YOFFSET12 + rational_p12q12( xc ) ) / ( xc * xc );
207
+ } else if ( xc <= 4.0f ) {
208
+ y = 1.0f / xc;
209
+ result += ( 1.0f + rational_p24q24( y ) ) / xc;
210
+ } else {
211
+ y = 1.0f / xc;
212
+ result += ( 1.0f + rational_p4infq4inf( y ) ) / xc;
213
+ }
214
+ return result;
215
+ }