@@ -102,7 +102,7 @@ public static TVectorDouble CosDouble<TVectorDouble, TVectorInt64>(TVectorDouble
102
102
result = TVectorDouble . MultiplyAddEstimate ( TVectorDouble . Create ( - 0.5 ) , x2 , TVectorDouble . One ) ;
103
103
}
104
104
}
105
- else
105
+ else if ( TVectorDouble . LessThanAll ( ax , TVectorDouble . Create ( 5000000.0 ) ) )
106
106
{
107
107
// at least one element is: |x| > (pi / 4) -or- infinite -or- nan
108
108
( TVectorDouble r , TVectorDouble rr , TVectorInt64 region ) = SinCosReduce < TVectorDouble , TVectorInt64 > ( ax ) ;
@@ -136,12 +136,29 @@ public static TVectorDouble CosDouble<TVectorDouble, TVectorInt64>(TVectorDouble
136
136
result
137
137
) ;
138
138
}
139
+ else
140
+ {
141
+ return ScalarFallback ( x ) ;
142
+ }
139
143
140
144
return TVectorDouble . ConditionalSelect (
141
145
Unsafe . BitCast < TVectorInt64 , TVectorDouble > ( TVectorInt64 . GreaterThan ( ux , TVectorInt64 . Create ( ARG_SMALLER - 1 ) ) ) ,
142
146
result , // for elements: |x| >= 2^-27, infinity, or NaN
143
147
TVectorDouble . One // for elements: 2^-27 > |x|
144
148
) ;
149
+
150
+ static TVectorDouble ScalarFallback ( TVectorDouble x )
151
+ {
152
+ TVectorDouble result = TVectorDouble . Zero ;
153
+
154
+ for ( int i = 0 ; i < TVectorDouble . Count ; i ++ )
155
+ {
156
+ double scalar = double . Cos ( x . GetElement ( i ) ) ;
157
+ result = result . WithElement ( i , scalar ) ;
158
+ }
159
+
160
+ return result ;
161
+ }
145
162
}
146
163
147
164
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
@@ -244,7 +261,7 @@ public static TVectorSingle CosSingle<TVectorSingle, TVectorInt32, TVectorDouble
244
261
result = TVectorSingle . MultiplyAddEstimate ( TVectorSingle . Create ( - 0.5f ) , x2 , TVectorSingle . One ) ;
245
262
}
246
263
}
247
- else
264
+ else if ( TVectorSingle . LessThanAll ( ax , TVectorSingle . Create ( 5000000.0f ) ) )
248
265
{
249
266
// at least one element is: |x| > (pi / 4) -or- infinite -or- nan
250
267
@@ -276,6 +293,10 @@ public static TVectorSingle CosSingle<TVectorSingle, TVectorInt32, TVectorDouble
276
293
result
277
294
) ;
278
295
}
296
+ else
297
+ {
298
+ return ScalarFallback ( x ) ;
299
+ }
279
300
280
301
return TVectorSingle . ConditionalSelect (
281
302
Unsafe . BitCast < TVectorInt32 , TVectorSingle > ( TVectorInt32 . GreaterThan ( ux , TVectorInt32 . Create ( ARG_SMALLER - 1 ) ) ) ,
@@ -303,6 +324,19 @@ static TVectorDouble CoreImpl(TVectorDouble ax)
303
324
- result // region 1 or 2
304
325
) ;
305
326
}
327
+
328
+ static TVectorSingle ScalarFallback ( TVectorSingle x )
329
+ {
330
+ TVectorSingle result = TVectorSingle . Zero ;
331
+
332
+ for ( int i = 0 ; i < TVectorSingle . Count ; i ++ )
333
+ {
334
+ float scalar = float . Cos ( x . GetElement ( i ) ) ;
335
+ result = result . WithElement ( i , scalar ) ;
336
+ }
337
+
338
+ return result ;
339
+ }
306
340
}
307
341
308
342
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
@@ -1733,24 +1767,22 @@ public static (TVectorDouble Sin, TVectorDouble Cos) SinCosDouble<TVectorDouble,
1733
1767
cosResult = TVectorDouble . MultiplyAddEstimate ( TVectorDouble . Create ( - 0.5 ) , x2 , TVectorDouble . One ) ;
1734
1768
}
1735
1769
}
1736
- else
1770
+ else if ( TVectorDouble . LessThanAll ( ax , TVectorDouble . Create ( 5000000.0 ) ) )
1737
1771
{
1738
1772
// at least one element is: |x| > (pi / 4) -or- infinite -or- nan
1739
1773
( TVectorDouble r , TVectorDouble rr , TVectorInt64 region ) = SinCosReduce < TVectorDouble , TVectorInt64 > ( ax ) ;
1740
1774
1741
1775
TVectorDouble sin = SinDoubleLarge ( r , rr ) ;
1742
1776
TVectorDouble cos = CosDoubleLarge ( r , rr ) ;
1743
1777
1744
- TVectorDouble regionMask = Unsafe . BitCast < TVectorInt64 , TVectorDouble > ( TVectorInt64 . Equals ( region & TVectorInt64 . One , TVectorInt64 . Zero ) ) ;
1745
-
1746
1778
sinResult = TVectorDouble . ConditionalSelect (
1747
- regionMask ,
1779
+ Unsafe . BitCast < TVectorInt64 , TVectorDouble > ( TVectorInt64 . Equals ( region & TVectorInt64 . One , TVectorInt64 . Zero ) ) ,
1748
1780
sin , // region 0 or 2
1749
1781
cos // region 1 or 3
1750
1782
) ;
1751
1783
1752
1784
cosResult = TVectorDouble . ConditionalSelect (
1753
- regionMask ,
1785
+ Unsafe . BitCast < TVectorInt64 , TVectorDouble > ( TVectorInt64 . Equals ( region & TVectorInt64 . One , TVectorInt64 . Zero ) ) ,
1754
1786
cos , // region 0 or 2
1755
1787
sin // region 1 or 3
1756
1788
) ;
@@ -1770,51 +1802,64 @@ public static (TVectorDouble Sin, TVectorDouble Cos) SinCosDouble<TVectorDouble,
1770
1802
) ;
1771
1803
1772
1804
// Propagate the NaN that was passed in
1773
- TVectorDouble nanMask = TVectorDouble . IsNaN ( x ) ;
1774
-
1775
1805
sinResult = TVectorDouble . ConditionalSelect (
1776
- nanMask ,
1806
+ TVectorDouble . IsNaN ( x ) ,
1777
1807
x ,
1778
1808
sinResult
1779
1809
) ;
1780
1810
1781
1811
cosResult = TVectorDouble . ConditionalSelect (
1782
- nanMask ,
1812
+ TVectorDouble . IsNaN ( x ) ,
1783
1813
x ,
1784
1814
cosResult
1785
1815
) ;
1786
1816
1787
1817
// Return NaN for infinity
1788
- TVectorDouble infinityMask = TVectorDouble . IsPositiveInfinity ( ax ) ;
1789
-
1790
1818
sinResult = TVectorDouble . ConditionalSelect (
1791
- infinityMask ,
1819
+ TVectorDouble . IsPositiveInfinity ( ax ) ,
1792
1820
TVectorDouble . Create ( double . NaN ) ,
1793
1821
sinResult
1794
1822
) ;
1795
1823
1796
1824
cosResult = TVectorDouble . ConditionalSelect (
1797
- infinityMask ,
1825
+ TVectorDouble . IsPositiveInfinity ( ax ) ,
1798
1826
TVectorDouble . Create ( double . NaN ) ,
1799
1827
cosResult
1800
1828
) ;
1801
1829
}
1802
-
1803
- TVectorDouble argNotSmallerMask = Unsafe . BitCast < TVectorInt64 , TVectorDouble > ( TVectorInt64 . GreaterThan ( ux , TVectorInt64 . Create ( ARG_SMALLER - 1 ) ) ) ;
1830
+ else
1831
+ {
1832
+ return ScalarFallback ( x ) ;
1833
+ }
1804
1834
1805
1835
sinResult = TVectorDouble . ConditionalSelect (
1806
- argNotSmallerMask ,
1836
+ Unsafe . BitCast < TVectorInt64 , TVectorDouble > ( TVectorInt64 . GreaterThan ( ux , TVectorInt64 . Create ( ARG_SMALLER - 1 ) ) ) ,
1807
1837
sinResult , // for elements: |x| >= 2^-27, infinity, or NaN
1808
1838
x // for elements: 2^-27 > |x|
1809
1839
) ;
1810
1840
1811
1841
cosResult = TVectorDouble . ConditionalSelect (
1812
- argNotSmallerMask ,
1842
+ Unsafe . BitCast < TVectorInt64 , TVectorDouble > ( TVectorInt64 . GreaterThan ( ux , TVectorInt64 . Create ( ARG_SMALLER - 1 ) ) ) ,
1813
1843
cosResult , // for elements: |x| >= 2^-27, infinity, or NaN
1814
1844
TVectorDouble . One // for elements: 2^-27 > |x|
1815
1845
) ;
1816
1846
1817
1847
return ( sinResult , cosResult ) ;
1848
+
1849
+ static ( TVectorDouble Sin , TVectorDouble Cos ) ScalarFallback ( TVectorDouble x )
1850
+ {
1851
+ TVectorDouble sinResult = TVectorDouble . Zero ;
1852
+ TVectorDouble cosResult = TVectorDouble . Zero ;
1853
+
1854
+ for ( int i = 0 ; i < TVectorDouble . Count ; i ++ )
1855
+ {
1856
+ ( double sinScalar , double cosScalar ) = double . SinCos ( x . GetElement ( i ) ) ;
1857
+ sinResult = sinResult . WithElement ( i , sinScalar ) ;
1858
+ cosResult = cosResult . WithElement ( i , cosScalar ) ;
1859
+ }
1860
+
1861
+ return ( sinResult , cosResult ) ;
1862
+ }
1818
1863
}
1819
1864
1820
1865
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
@@ -1886,7 +1931,7 @@ public static (TVectorSingle Sin, TVectorSingle Cos) SinCosSingle<TVectorSingle,
1886
1931
cosResult = TVectorSingle . MultiplyAddEstimate ( TVectorSingle . Create ( - 0.5f ) , x2 , TVectorSingle . One ) ;
1887
1932
}
1888
1933
}
1889
- else
1934
+ else if ( TVectorSingle . LessThanAll ( ax , TVectorSingle . Create ( 5000000.0f ) ) )
1890
1935
{
1891
1936
// at least one element is: |x| > (pi / 4) -or- infinite -or- nan
1892
1937
@@ -1907,48 +1952,46 @@ public static (TVectorSingle Sin, TVectorSingle Cos) SinCosSingle<TVectorSingle,
1907
1952
}
1908
1953
1909
1954
// Propagate the NaN that was passed in
1910
- TVectorSingle nanMask = TVectorSingle . IsNaN ( x ) ;
1911
-
1912
1955
sinResult = TVectorSingle . ConditionalSelect (
1913
- nanMask ,
1956
+ TVectorSingle . IsNaN ( x ) ,
1914
1957
x ,
1915
1958
sinResult
1916
1959
) ;
1917
1960
1918
1961
cosResult = TVectorSingle . ConditionalSelect (
1919
- nanMask ,
1962
+ TVectorSingle . IsNaN ( x ) ,
1920
1963
x ,
1921
1964
cosResult
1922
1965
) ;
1923
1966
1924
1967
// Return NaN for infinity
1925
- TVectorSingle infinityMask = TVectorSingle . IsPositiveInfinity ( ax ) ;
1926
-
1927
1968
sinResult = TVectorSingle . ConditionalSelect (
1928
- infinityMask ,
1969
+ TVectorSingle . IsPositiveInfinity ( ax ) ,
1929
1970
TVectorSingle . Create ( float . NaN ) ,
1930
1971
sinResult
1931
1972
) ;
1932
1973
1933
1974
cosResult = TVectorSingle . ConditionalSelect (
1934
- infinityMask ,
1975
+ TVectorSingle . IsPositiveInfinity ( ax ) ,
1935
1976
TVectorSingle . Create ( float . NaN ) ,
1936
1977
cosResult
1937
1978
) ;
1938
1979
1939
1980
return ( sinResult , cosResult ) ;
1940
1981
}
1941
-
1942
- TVectorSingle argNotSmallerMask = Unsafe . BitCast < TVectorInt32 , TVectorSingle > ( TVectorInt32 . GreaterThan ( ux , TVectorInt32 . Create ( ARG_SMALLER - 1 ) ) ) ;
1982
+ else
1983
+ {
1984
+ return ScalarFallback ( x ) ;
1985
+ }
1943
1986
1944
1987
sinResult = TVectorSingle . ConditionalSelect (
1945
- argNotSmallerMask ,
1988
+ Unsafe . BitCast < TVectorInt32 , TVectorSingle > ( TVectorInt32 . GreaterThan ( ux , TVectorInt32 . Create ( ARG_SMALLER - 1 ) ) ) ,
1946
1989
sinResult , // for elements: |x| >= 2^-27, infinity, or NaN
1947
1990
x // for elements: 2^-27 > |x|
1948
1991
) ;
1949
1992
1950
1993
cosResult = TVectorSingle . ConditionalSelect (
1951
- argNotSmallerMask ,
1994
+ Unsafe . BitCast < TVectorInt32 , TVectorSingle > ( TVectorInt32 . GreaterThan ( ux , TVectorInt32 . Create ( ARG_SMALLER - 1 ) ) ) ,
1952
1995
cosResult , // for elements: |x| >= 2^-27, infinity, or NaN
1953
1996
TVectorSingle . One // for elements: 2^-27 > |x|
1954
1997
) ;
@@ -1963,16 +2006,14 @@ public static (TVectorSingle Sin, TVectorSingle Cos) SinCosSingle<TVectorSingle,
1963
2006
TVectorDouble sin = SinSinglePoly ( r ) ;
1964
2007
TVectorDouble cos = CosSingleLarge ( r ) ;
1965
2008
1966
- TVectorDouble regionMask = Unsafe . BitCast < TVectorInt64 , TVectorDouble > ( TVectorInt64 . Equals ( region & TVectorInt64 . One , TVectorInt64 . Zero ) ) ;
1967
-
1968
2009
TVectorDouble sinResult = TVectorDouble . ConditionalSelect (
1969
- regionMask ,
2010
+ Unsafe . BitCast < TVectorInt64 , TVectorDouble > ( TVectorInt64 . Equals ( region & TVectorInt64 . One , TVectorInt64 . Zero ) ) ,
1970
2011
sin , // region 0 or 2
1971
2012
cos // region 1 or 3
1972
2013
) ;
1973
2014
1974
2015
TVectorDouble cosResult = TVectorDouble . ConditionalSelect (
1975
- regionMask ,
2016
+ Unsafe . BitCast < TVectorInt64 , TVectorDouble > ( TVectorInt64 . Equals ( region & TVectorInt64 . One , TVectorInt64 . Zero ) ) ,
1976
2017
cos , // region 0 or 2
1977
2018
sin // region 1 or 3
1978
2019
) ;
@@ -1993,6 +2034,21 @@ public static (TVectorSingle Sin, TVectorSingle Cos) SinCosSingle<TVectorSingle,
1993
2034
1994
2035
return ( sinResult , cosResult ) ;
1995
2036
}
2037
+
2038
+ static ( TVectorSingle Sin , TVectorSingle Cos ) ScalarFallback ( TVectorSingle x )
2039
+ {
2040
+ TVectorSingle sinResult = TVectorSingle . Zero ;
2041
+ TVectorSingle cosResult = TVectorSingle . Zero ;
2042
+
2043
+ for ( int i = 0 ; i < TVectorSingle . Count ; i ++ )
2044
+ {
2045
+ ( float sinScalar , float cosScalar ) = float . SinCos ( x . GetElement ( i ) ) ;
2046
+ sinResult = sinResult . WithElement ( i , sinScalar ) ;
2047
+ cosResult = cosResult . WithElement ( i , cosScalar ) ;
2048
+ }
2049
+
2050
+ return ( sinResult , cosResult ) ;
2051
+ }
1996
2052
}
1997
2053
1998
2054
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
@@ -2076,7 +2132,7 @@ public static TVectorDouble SinDouble<TVectorDouble, TVectorInt64>(TVectorDouble
2076
2132
result = TVectorDouble . MultiplyAddEstimate ( TVectorDouble . Create ( - 0.16666666666666666 ) , x3 , x ) ;
2077
2133
}
2078
2134
}
2079
- else
2135
+ else if ( TVectorDouble . LessThanAll ( ax , TVectorDouble . Create ( 5000000.0 ) ) )
2080
2136
{
2081
2137
// at least one element is: |x| > (pi / 4) -or- infinite -or- nan
2082
2138
( TVectorDouble r , TVectorDouble rr , TVectorInt64 region ) = SinCosReduce < TVectorDouble , TVectorInt64 > ( ax ) ;
@@ -2112,12 +2168,29 @@ public static TVectorDouble SinDouble<TVectorDouble, TVectorInt64>(TVectorDouble
2112
2168
result
2113
2169
) ;
2114
2170
}
2171
+ else
2172
+ {
2173
+ return ScalarFallback ( x ) ;
2174
+ }
2115
2175
2116
2176
return TVectorDouble . ConditionalSelect (
2117
2177
Unsafe . BitCast < TVectorInt64 , TVectorDouble > ( TVectorInt64 . GreaterThan ( ux , TVectorInt64 . Create ( ARG_SMALLER - 1 ) ) ) ,
2118
2178
result , // for elements: |x| >= 2^-27, infinity, or NaN
2119
2179
x // for elements: 2^-27 > |x|
2120
2180
) ;
2181
+
2182
+ static TVectorDouble ScalarFallback ( TVectorDouble x )
2183
+ {
2184
+ TVectorDouble result = TVectorDouble . Zero ;
2185
+
2186
+ for ( int i = 0 ; i < TVectorDouble . Count ; i ++ )
2187
+ {
2188
+ double scalar = double . Sin ( x . GetElement ( i ) ) ;
2189
+ result = result . WithElement ( i , scalar ) ;
2190
+ }
2191
+
2192
+ return result ;
2193
+ }
2121
2194
}
2122
2195
2123
2196
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
@@ -2215,7 +2288,7 @@ public static TVectorSingle SinSingle<TVectorSingle, TVectorInt32, TVectorDouble
2215
2288
result = TVectorSingle . MultiplyAddEstimate ( TVectorSingle . Create ( - 0.16666667f ) , x3 , x ) ;
2216
2289
}
2217
2290
}
2218
- else
2291
+ else if ( TVectorSingle . LessThanAll ( ax , TVectorSingle . Create ( 5000000.0f ) ) )
2219
2292
{
2220
2293
// at least one element is: |x| > (pi / 4) -or- infinite -or- nan
2221
2294
@@ -2247,6 +2320,10 @@ public static TVectorSingle SinSingle<TVectorSingle, TVectorInt32, TVectorDouble
2247
2320
result
2248
2321
) ;
2249
2322
}
2323
+ else
2324
+ {
2325
+ return ScalarFallback ( x ) ;
2326
+ }
2250
2327
2251
2328
return TVectorSingle . ConditionalSelect (
2252
2329
Unsafe . BitCast < TVectorInt32 , TVectorSingle > ( TVectorInt32 . GreaterThan ( ux , TVectorInt32 . Create ( ARG_SMALLER - 1 ) ) ) ,
@@ -2277,6 +2354,19 @@ static TVectorDouble CoreImpl(TVectorDouble x)
2277
2354
- result // negative in region 0 or 2, positive in region 1 or 3
2278
2355
) ;
2279
2356
}
2357
+
2358
+ static TVectorSingle ScalarFallback ( TVectorSingle x )
2359
+ {
2360
+ TVectorSingle result = TVectorSingle . Zero ;
2361
+
2362
+ for ( int i = 0 ; i < TVectorSingle . Count ; i ++ )
2363
+ {
2364
+ float scalar = float . Sin ( x . GetElement ( i ) ) ;
2365
+ result = result . WithElement ( i , scalar ) ;
2366
+ }
2367
+
2368
+ return result ;
2369
+ }
2280
2370
}
2281
2371
2282
2372
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
0 commit comments