quadmath 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.
@@ -0,0 +1,31 @@
1
+ /*******************************************************************************
2
+ main.c -- QuadMath EntryPoint
3
+
4
+ Author: Hironobu Inatsuka
5
+ *******************************************************************************/
6
+ #include <ruby.h>
7
+ #include <quadmath.h>
8
+ #define USE_GLOBAL_VARIABLE
9
+ #include "rb_quadmath.h"
10
+ #include "internal/rb_quadmath.h"
11
+ #include "missing/ool_quad2str.c"
12
+
13
+ void InitVM_Float128(void);
14
+ void InitVM_Complex128(void);
15
+ void InitVM_Numerable(void);
16
+ void InitVM_QuadMath(void);
17
+
18
+ // EntryPoint
19
+ void
20
+ Init_quadmath(void)
21
+ {
22
+ rb_cFloat128 = rb_define_class("Float128", rb_cNumeric);
23
+ rb_cComplex128 = rb_define_class("Complex128", rb_cNumeric);
24
+ rb_mQuadMath = rb_define_module("QuadMath");
25
+
26
+ InitVM(Float128);
27
+ InitVM(Complex128);
28
+ InitVM(Numerable);
29
+ InitVM(QuadMath);
30
+ }
31
+
@@ -0,0 +1,158 @@
1
+ // Written by Takuya Ooura
2
+ #include <quadmath.h>
3
+
4
+ __complex128
5
+ cerfcq(__complex128 x)
6
+ {
7
+ const __float128
8
+ pv = 1.8419880743036792792631929248006767493e+01Q,
9
+ ph = 9.4599403715183963963159646240033837464e+00Q,
10
+ p0 = 2.1093083061644187538279122968913808152e-01Q,
11
+ p1 = 1.6713797949733065528971052035163045322e-01Q,
12
+ p2 = 1.0494102880451803704489103456267864462e-01Q,
13
+ p3 = 5.2209624806229062497556308453704817574e-02Q,
14
+ p4 = 2.0582158194044619069754225289969978299e-02Q,
15
+ p5 = 6.4293391618431334949721030322694803569e-03Q,
16
+ p6 = 1.5913908100149480106505036886507485785e-03Q,
17
+ p7 = 3.1212060500464898607481297780989148689e-04Q,
18
+ p8 = 4.8506855193831619356742051276480109919e-05Q,
19
+ p9 = 5.9733626677651815061875193953000538326e-06Q,
20
+ p10 = 5.8286735523223186734841193923199386322e-07Q,
21
+ p11 = 4.5066690471880700341073630648957059945e-08Q,
22
+ p12 = 2.7610653454261808871589140980422088532e-09Q,
23
+ p13 = 1.3403949680961254958324655659147790094e-10Q,
24
+ p14 = 5.1561314110869289752886735305964573946e-12Q,
25
+ p15 = 1.5716297853674992841622413214543994197e-13Q,
26
+ p16 = 3.7958724379391814374198930599398267061e-15Q,
27
+ p17 = 7.2645388829894728683842661597496303959e-17Q,
28
+ p18 = 1.1016397065175311063529497475707242525e-18Q,
29
+ p19 = 1.3237506731591609005566634525737840832e-20Q,
30
+ p20 = 1.2603985415835627864680027724651354389e-22Q,
31
+ p21 = 9.5092151781247278003169665785149729821e-25Q,
32
+ p22 = 5.6848177046496801634666761604409403206e-27Q,
33
+ p23 = 2.6929202705338711046737832028758053393e-29Q,
34
+ p24 = 1.0108006977320702265677957534508423789e-31Q,
35
+ p25 = 3.0063715680065086923565072577882673057e-34Q,
36
+ p26 = 7.0852448481490904907112832127691803349e-37Q,
37
+ q0 = 2.9088820866572159615394846141476878557e-02Q,
38
+ q1 = 2.6179938779914943653855361527329190702e-01Q,
39
+ q2 = 7.2722052166430399038487115353692196393e-01Q,
40
+ q3 = 1.4253522224620358211543474609323670493e+00Q,
41
+ q4 = 2.3561944901923449288469825374596271631e+00Q,
42
+ q5 = 3.5197473248552313134627763831187023054e+00Q,
43
+ q6 = 4.9160107264506949750017289979095924762e+00Q,
44
+ q7 = 6.5449846949787359134638403818322976754e+00Q,
45
+ q8 = 8.4066692304393541288491105348868179031e+00Q,
46
+ q9 = 1.0501064332832549621157539457073153159e+01Q,
47
+ q10 = 1.2828170002158322390389127148391303444e+01Q,
48
+ q11 = 1.5387986238416672436543873608841268757e+01Q,
49
+ q12 = 1.8180513041607599759621778838423049098e+01Q,
50
+ q13 = 2.1205750411731104359622842837136644468e+01Q,
51
+ q14 = 2.4463698348787186236547065604982054867e+01Q,
52
+ q15 = 2.7954356852775845390394447141959280294e+01Q,
53
+ q16 = 3.1677725923697081821164987448068320749e+01Q,
54
+ q17 = 3.5633805561550895528858686523309176233e+01Q,
55
+ q18 = 3.9822595766337286513475544367681846745e+01Q,
56
+ q19 = 4.4244096538056254775015560981186332286e+01Q,
57
+ q20 = 4.8898307876707800313478736363822632855e+01Q,
58
+ q21 = 5.3785229782291923128865070515590748453e+01Q,
59
+ q22 = 5.8904862254808623221174563436490679079e+01Q,
60
+ q23 = 6.4257205294257900590407215126522424733e+01Q,
61
+ q24 = 6.9842258900639755236563025585685985416e+01Q,
62
+ q25 = 7.5660023073954187159641994813981361128e+01Q,
63
+ q26 = 8.1710497814201196359644122811408551868e+01Q,
64
+ r0 = 1.0857833597842664924141880507518822324e-01Q,
65
+ r1 = 1.9330394605384376865851659517702988226e-01Q,
66
+ r2 = 1.3634629684679999083131393208557974008e-01Q,
67
+ r3 = 7.6204577450604403788088248675471849578e-02Q,
68
+ r4 = 3.3748451951221171387030636574487677141e-02Q,
69
+ r5 = 1.1843000251292400843913857684704052043e-02Q,
70
+ r6 = 3.2930983812757205929921213829383580821e-03Q,
71
+ r7 = 7.2557574646222760967368809292892366817e-04Q,
72
+ r8 = 1.2667645289367856821531300675005701424e-04Q,
73
+ r9 = 1.7524438664090954799894562703988992670e-05Q,
74
+ r10 = 1.9210002539217758384351411001702958461e-06Q,
75
+ r11 = 1.6685753127194156512431242433234203465e-07Q,
76
+ r12 = 1.1484161468186100454021914187739990566e-08Q,
77
+ r13 = 6.2630784459909945721312231747915945961e-10Q,
78
+ r14 = 2.7065216004464856039123247342635784082e-11Q,
79
+ r15 = 9.2676629018209927646524369276088075961e-13Q,
80
+ r16 = 2.5145718215575387941885792873856026053e-14Q,
81
+ r17 = 5.4062104214337911880413049229210178595e-16Q,
82
+ r18 = 9.2099427616964263777001122276945386232e-18Q,
83
+ r19 = 1.2432429403206980797482152563988923532e-19Q,
84
+ r20 = 1.3298117235769445146920469835700830835e-21Q,
85
+ r21 = 1.1270920794418483512403852639398106151e-23Q,
86
+ r22 = 7.5694395178532891627960685040600391752e-26Q,
87
+ r23 = 4.0281268032076992671072314251173518774e-28Q,
88
+ r24 = 1.6985472346741765564942981815307583270e-30Q,
89
+ r25 = 5.6752788970027027984246568768226680280e-33Q,
90
+ r26 = 1.5025601745064174185565587049015131885e-35Q,
91
+ s1 = 1.1635528346628863846157938456590751423e-01Q,
92
+ s2 = 4.6542113386515455384631753826363005692e-01Q,
93
+ s3 = 1.0471975511965977461542144610931676281e+00Q,
94
+ s4 = 1.8616845354606182153852701530545202277e+00Q,
95
+ s5 = 2.9088820866572159615394846141476878557e+00Q,
96
+ s6 = 4.1887902047863909846168578443726705123e+00Q,
97
+ s7 = 5.7014088898481432846173898437294681972e+00Q,
98
+ s8 = 7.4467381418424728615410806122180809107e+00Q,
99
+ s9 = 9.4247779607693797153879301498385086526e+00Q,
100
+ s10 = 1.1635528346628863846157938456590751423e+01Q,
101
+ s11 = 1.4078989299420925253851105532474809222e+01Q,
102
+ s12 = 1.6755160819145563938467431377490682049e+01Q,
103
+ s13 = 1.9664042905802779900006915991638369905e+01Q,
104
+ s14 = 2.2805635559392573138469559374917872789e+01Q,
105
+ s15 = 2.6179938779914943653855361527329190702e+01Q,
106
+ s16 = 2.9786952567369891446164322448872323643e+01Q,
107
+ s17 = 3.3626676921757416515396442139547271612e+01Q,
108
+ s18 = 3.7699111843077518861551720599354034610e+01Q,
109
+ s19 = 4.2004257331330198484630157828292612637e+01Q,
110
+ s20 = 4.6542113386515455384631753826363005692e+01Q,
111
+ s21 = 5.1312680008633289561556508593565213775e+01Q,
112
+ s22 = 5.6315957197683701015404422129899236887e+01Q,
113
+ s23 = 6.1551944953666689746175494435365075027e+01Q,
114
+ s24 = 6.7020643276582255753869725509962728196e+01Q,
115
+ s25 = 7.2722052166430399038487115353692196393e+01Q,
116
+ s26= 7.8656171623211119600027663966553479619e+01Q;
117
+ __complex128 y = x * x;
118
+
119
+ if (fabsq(crealq(x))+fabsq(cimagq(x)) < ph)
120
+ {
121
+ __complex128 z = cexpq(pv*x);
122
+
123
+ if (crealq(z) >= 0)
124
+ y = cexpq(-y)*x*(p26/(y+q26)
125
+ +p25/(y+q25)+p24/(y+q24)+p23/(y+q23)
126
+ +p22/(y+q22)+p21/(y+q21)+p20/(y+q20)
127
+ +p19/(y+q19)+p18/(y+q18)+p17/(y+q17)
128
+ +p16/(y+q16)+p15/(y+q15)+p14/(y+q14)
129
+ +p13/(y+q13)+p12/(y+q12)+p11/(y+q11)
130
+ +p10/(y+q10)+p9/(y+q9)+p8/(y+q8)+p7/(y+q7)
131
+ +p6/(y+q6)+p5/(y+q5)+p4/(y+q4)+p3/(y+q3)
132
+ +p2/(y+q2)+p1/(y+q1)+p0/(y+q0))+2/(1+z);
133
+ else
134
+ y = cexpq(-y)*x*(r26/(y+s26)
135
+ +r25/(y+s25)+r24/(y+s24)+r23/(y+s23)
136
+ +r22/(y+s22)+r21/(y+s21)+r20/(y+s20)
137
+ +r19/(y+s19)+r18/(y+s18)+r17/(y+s17)
138
+ +r16/(y+s16)+r15/(y+s15)+r14/(y+s14)
139
+ +r13/(y+s13)+r12/(y+s12)+r11/(y+s11)
140
+ +r10/(y+s10)+r9/(y+s9)+r8/(y+s8)+r7/(y+s7)
141
+ +r6/(y+s6)+r5/(y+s5)+r4/(y+s4)+r3/(y+s3)
142
+ +r2/(y+s2)+r1/(y+s1)+r0/y)+2/(1-z);
143
+ }
144
+ else
145
+ {
146
+ y = cexpq(-y)*x*(p26/(y+q26)
147
+ +p25/(y+q25)+p24/(y+q24)+p23/(y+q23)
148
+ +p22/(y+q22)+p21/(y+q21)+p20/(y+q20)
149
+ +p19/(y+q19)+p18/(y+q18)+p17/(y+q17)
150
+ +p16/(y+q16)+p15/(y+q15)+p14/(y+q14)
151
+ +p13/(y+q13)+p12/(y+q12)+p11/(y+q11)
152
+ +p10/(y+q10)+p9/(y+q9)+p8/(y+q8)+p7/(y+q7)
153
+ +p6/(y+q6)+p5/(y+q5)+p4/(y+q4)+p3/(y+q3)
154
+ +p2/(y+q2)+p1/(y+q1)+p0/(y+q0));
155
+ if (crealq(x) < 0) y=y+2;
156
+ }
157
+ return y;
158
+ }
@@ -0,0 +1,35 @@
1
+ // Written by Takuya Ooura
2
+ #include <quadmath.h>
3
+
4
+ __complex128
5
+ cerfq(__complex128 x)
6
+ {
7
+ const __float128
8
+ p0 = 1.1283791670955125738961589031215451717e+00Q,
9
+ p1 =-3.7612638903183752463205296770718172390e-01Q,
10
+ p2 = 1.1283791670955125738961589031215451717e-01Q,
11
+ p3 =-2.6866170645131251759432354836227265993e-02Q,
12
+ p4 = 5.2239776254421878421118467737108572763e-03Q,
13
+ p5 =-8.5483270234508528325466583569814028158e-04Q,
14
+ p6 = 1.2055332981789664251027338708563516792e-04Q,
15
+ p7 =-1.4925650358406250977462419353459592218e-05Q,
16
+ p8 = 1.6462114365889247401612962522198079652e-06Q,
17
+ p9 =-1.6365844691234924317393003677039026555e-07Q,
18
+ p10 = 1.4807192815879217239546050945892452597e-08Q,
19
+ p11 =-1.2290555301717927352982888136906778836e-09Q,
20
+ p12 = 9.4227590646504109706202142382951971074e-11Q,
21
+ p13 =-6.7113668551641103779346255258512799910e-12Q;
22
+
23
+ if (fabsq(crealq(x))+fabsq(cimagq(x)) > 0.125)
24
+ if (crealq(x) >= 0)
25
+ return 1.q-cerfcq(x);
26
+ else
27
+ return cerfcq(-x)-1.q;
28
+ else
29
+ {
30
+ __complex128 y = x * x;
31
+ return (((((((((((((p13*y+p12)*y+p11)*y+p10)*y
32
+ +p9)*y+p8)*y+p7)*y+p6)*y+p5)*y+p4)*y
33
+ +p3)*y+p2)*y+p1)*y+p0)*x;
34
+ }
35
+ }
@@ -0,0 +1,43 @@
1
+ #include <quadmath.h>
2
+
3
+ /* hypot()実装: Moler-Morrison法 */
4
+ static inline __float128
5
+ hypot_mm_method(__float128 x, __float128 y)
6
+ {
7
+ __float128 t;
8
+ static int iter_cnt = 4; // float = 2, double = 3, __float128 = 4
9
+
10
+ // x = fabs(x); y = fabs(y);
11
+ if (x < y) { t = x; x = y; y = t; }
12
+ if (y == 0) return x;
13
+ for (int i = 0; i < iter_cnt; i++)
14
+ {
15
+ t = y / x; t *= t; t /= 4 + t;
16
+ x += 2 * x * t; y *= t;
17
+ }
18
+ return x;
19
+ }
20
+
21
+
22
+ __float128
23
+ cl2norm2q(__complex128 z, __complex128 w)
24
+ {
25
+ __float128 z_real = crealq(z), z_imag = cimagq(z),
26
+ w_real = crealq(w), w_imag = cimagq(w);
27
+
28
+ if (z_imag == 0 && w_imag == 0)
29
+ return hypotq(z_real, w_real);
30
+ else if (finiteq(z_real) && finiteq(z_imag) &&
31
+ finiteq(w_real) && finiteq(w_imag))
32
+ {
33
+ __float128 abs_z = cabsq(z), abs_w = cabsq(w);
34
+ return hypot_mm_method(abs_z, abs_w);
35
+ }
36
+ else if (isnanq(z_real) || isnanq(z_imag) ||
37
+ isnanq(w_real) || isnanq(w_imag))
38
+ {
39
+ return nanq("");
40
+ }
41
+ else
42
+ return HUGE_VALQ;
43
+ }
@@ -0,0 +1,61 @@
1
+ // Written by Takuya Ooura
2
+ #include <quadmath.h>
3
+
4
+ __complex128
5
+ clgammaq(__complex128 x)
6
+ {
7
+ const __float128
8
+ pi = 3.1415926535897932384626433832795028842e+00L,
9
+ pv = 1.7073384106072256336552635469768405988e+01L,
10
+ pr = 9.6430280376084227593136665415665434890e-08L,
11
+ p0 = 1.4885966277379481312144836654780489977e-05L,
12
+ p1 = 9.8197319346551593835492039252950643250e-04L,
13
+ p2 = 3.6452833584596387259416230162968814334e-02L,
14
+ p3 = 8.4440218943313053279736838769169637475e-01L,
15
+ p4 = 1.2799395416392675659501629085367313130e+01L,
16
+ p5 = 1.2958416314697458304456172805819466959e+02L,
17
+ p6 = 8.7934757442085093139482632461747688925e+02L,
18
+ p7 = 3.9603132208822057375892166788749852003e+03L,
19
+ p8 = 1.1570567689267327614796506829853701257e+04L,
20
+ p9 = 2.1118371610821741632467257070275867771e+04L,
21
+ p10 = 2.2735240766521371105419781548988441852e+04L,
22
+ p11 = 1.3237220278612707484073165339915814580e+04L,
23
+ p12 = 3.6413985805433870475220843772414784920e+03L,
24
+ p13 = 3.7799827284494982250871944924580183350e+02L,
25
+ p14 = 9.7548265781613156543352803894655242645e+00L,
26
+ p15 = 2.4781878010146311991379531059279396603e-02L,
27
+ q1 = 9.9999999999999999999999999999999505954e-01L,
28
+ q2 = 2.0000000000000000000000000000054314870e+00L,
29
+ q3 = 2.9999999999999999999999999979818447021e+00L,
30
+ q4 = 4.0000000000000000000000003832010974513e+00L,
31
+ q5 = 4.9999999999999999999999549613824869296e+00L,
32
+ q6 = 6.0000000000000000000036828053823278869e+00L,
33
+ q7 = 6.9999999999999999997722128314314457093e+00L,
34
+ q8 = 8.0000000000000000114079473554600382027e+00L,
35
+ q9 = 8.9999999999999995074649343321072905406e+00L,
36
+ q10 = 1.0000000000000019570887665497626544354e+01L,
37
+ q11 = 1.0999999999999226781739409388855954774e+01L,
38
+ q12 = 1.2000000000033685360735653796874490304e+01L,
39
+ q13 = 1.2999999998107373865740824582565523337e+01L,
40
+ q14 = 1.4000000179833580993347884693337842721e+01L,
41
+ q15 = 1.4999950264715053014007976344403787119e+01L;
42
+ __complex128 w = x, y;
43
+ __float128 r, s;
44
+
45
+ if (crealq(x) < 0) w = 1 - x;
46
+
47
+ y = clogq((((((((((((((((p15/(w+q15)+p14)/(w+q14)
48
+ +p13)/(w+q13)+p12)/(w+q12)+p11)/(w+q11)
49
+ +p10)/(w+q10)+p9)/(w+q9)+p8)/(w+q8)
50
+ +p7)/(w+q7)+p6)/(w+q6)+p5)/(w+q5)+p4)/(w+q4)
51
+ +p3)/(w+q3)+p2)/(w+q2)+p1)/(w+q1)+p0)/w+pr)
52
+ +(w-0.5q)*clogq(w+pv)-w;
53
+
54
+ if (crealq(x) < 0) y = clogq(pi/csinq(pi*x))-y;
55
+
56
+ // FIXME: 虚部に$2\pi$分が加減算されない。FORTRANの近接丸め関数はCの近接丸め関数とは異なる
57
+ r = 0.5L-(1i * y)/(2*pi);
58
+ s = floorq(r)-1.q;
59
+
60
+ return y + (0.q + ((2*pi)*(floorq(r-s)+s)) * 1i);
61
+ }
@@ -0,0 +1,56 @@
1
+ // Written by Takuya Ooura
2
+ #include <quadmath.h>
3
+
4
+ __complex128
5
+ ctgammaq(__complex128 x)
6
+ {
7
+ const __float128
8
+ pi = 3.1415926535897932384626433832795028842e+00Q,
9
+ pv = 1.7073384106072256336552635469768405988e+01Q,
10
+ pr = 9.6430280376084227593136665415665434890e-08Q,
11
+ p0 = 1.4885966277379481312144836654780489977e-05Q,
12
+ p1 = 9.8197319346551593835492039252950643250e-04Q,
13
+ p2 = 3.6452833584596387259416230162968814334e-02Q,
14
+ p3 = 8.4440218943313053279736838769169637475e-01Q,
15
+ p4 = 1.2799395416392675659501629085367313130e+01Q,
16
+ p5 = 1.2958416314697458304456172805819466959e+02Q,
17
+ p6 = 8.7934757442085093139482632461747688925e+02Q,
18
+ p7 = 3.9603132208822057375892166788749852003e+03Q,
19
+ p8 = 1.1570567689267327614796506829853701257e+04Q,
20
+ p9 = 2.1118371610821741632467257070275867771e+04Q,
21
+ p10 = 2.2735240766521371105419781548988441852e+04Q,
22
+ p11 = 1.3237220278612707484073165339915814580e+04Q,
23
+ p12 = 3.6413985805433870475220843772414784920e+03Q,
24
+ p13 = 3.7799827284494982250871944924580183350e+02Q,
25
+ p14 = 9.7548265781613156543352803894655242645e+00Q,
26
+ p15 = 2.4781878010146311991379531059279396603e-02Q,
27
+ q1 = 9.9999999999999999999999999999999505954e-01Q,
28
+ q2 = 2.0000000000000000000000000000054314870e+00Q,
29
+ q3 = 2.9999999999999999999999999979818447021e+00Q,
30
+ q4 = 4.0000000000000000000000003832010974513e+00Q,
31
+ q5 = 4.9999999999999999999999549613824869296e+00Q,
32
+ q6 = 6.0000000000000000000036828053823278869e+00Q,
33
+ q7 = 6.9999999999999999997722128314314457093e+00Q,
34
+ q8 = 8.0000000000000000114079473554600382027e+00Q,
35
+ q9 = 8.9999999999999995074649343321072905406e+00Q,
36
+ q10 = 1.0000000000000019570887665497626544354e+01Q,
37
+ q11 = 1.0999999999999226781739409388855954774e+01Q,
38
+ q12 = 1.2000000000033685360735653796874490304e+01Q,
39
+ q13 = 1.2999999998107373865740824582565523337e+01Q,
40
+ q14 = 1.4000000179833580993347884693337842721e+01Q,
41
+ q15 = 1.4999950264715053014007976344403787119e+01Q;
42
+ __complex128 w = x, y;
43
+
44
+ if (crealq(x) < 0) w = 1 - x;
45
+
46
+ y = ((((((((((((((((p15/(w+q15)+p14)/(w+q14)
47
+ +p13)/(w+q13)+p12)/(w+q12)+p11)/(w+q11)
48
+ +p10)/(w+q10)+p9)/(w+q9)+p8)/(w+q8)
49
+ +p7)/(w+q7)+p6)/(w+q6)+p5)/(w+q5)+p4)/(w+q4)
50
+ +p3)/(w+q3)+p2)/(w+q2)+p1)/(w+q1)+p0)/w+pr)
51
+ *cexpq((w-0.5)*clogq(w+pv)-w);
52
+
53
+ if (crealq(x) < 0) y = pi/(y*csinq(pi*x));
54
+
55
+ return y;
56
+ }