xref: /inferno-os/libinterp/math.c (revision cd03a2dc3bfa8e793b2e4702966706c10d69b314)
137da2899SCharles.Forsyth #include "lib9.h"
237da2899SCharles.Forsyth #include "interp.h"
337da2899SCharles.Forsyth #include "isa.h"
437da2899SCharles.Forsyth #include "runt.h"
537da2899SCharles.Forsyth #include "raise.h"
637da2899SCharles.Forsyth #include "mathi.h"
737da2899SCharles.Forsyth #include "mathmod.h"
837da2899SCharles.Forsyth 
937da2899SCharles.Forsyth static union
1037da2899SCharles.Forsyth {
1137da2899SCharles.Forsyth 	double x;
1237da2899SCharles.Forsyth 	uvlong u;
1337da2899SCharles.Forsyth } bits64;
1437da2899SCharles.Forsyth 
1537da2899SCharles.Forsyth static union{
1637da2899SCharles.Forsyth 	float x;
1737da2899SCharles.Forsyth 	unsigned int u;
1837da2899SCharles.Forsyth } bits32;
1937da2899SCharles.Forsyth 
2037da2899SCharles.Forsyth void
mathmodinit(void)2137da2899SCharles.Forsyth mathmodinit(void)
2237da2899SCharles.Forsyth {
2337da2899SCharles.Forsyth 	builtinmod("$Math", Mathmodtab, Mathmodlen);
2437da2899SCharles.Forsyth 	fmtinstall('g', gfltconv);
2537da2899SCharles.Forsyth 	fmtinstall('G', gfltconv);
2637da2899SCharles.Forsyth 	fmtinstall('e', gfltconv);
2737da2899SCharles.Forsyth 	/* fmtinstall('E', gfltconv); */	/* avoid clash with ether address */
2837da2899SCharles.Forsyth 	fmtinstall(0x00c9, gfltconv);	/* L'É' */
2937da2899SCharles.Forsyth 	fmtinstall('f', gfltconv);
3037da2899SCharles.Forsyth }
3137da2899SCharles.Forsyth 
3237da2899SCharles.Forsyth void
Math_import_int(void * fp)3337da2899SCharles.Forsyth Math_import_int(void *fp)
3437da2899SCharles.Forsyth {
3537da2899SCharles.Forsyth 	F_Math_import_int *f;
3637da2899SCharles.Forsyth 	int i, n;
3737da2899SCharles.Forsyth 	unsigned int u;
3837da2899SCharles.Forsyth 	unsigned char *bp;
3937da2899SCharles.Forsyth 	int *x;
4037da2899SCharles.Forsyth 
4137da2899SCharles.Forsyth 	f = fp;
4237da2899SCharles.Forsyth 	n = f->x->len;
4337da2899SCharles.Forsyth 	if(f->b->len!=4*n)
4437da2899SCharles.Forsyth 		error(exMathia);
4537da2899SCharles.Forsyth 	bp = (unsigned char *)(f->b->data);
4637da2899SCharles.Forsyth 	x = (int*)(f->x->data);
4737da2899SCharles.Forsyth 	for(i=0; i<n; i++){
4837da2899SCharles.Forsyth 		u = *bp++;
4937da2899SCharles.Forsyth 		u = (u<<8) | *bp++;
5037da2899SCharles.Forsyth 		u = (u<<8) | *bp++;
5137da2899SCharles.Forsyth 		u = (u<<8) | *bp++;
5237da2899SCharles.Forsyth 		x[i] = u;
5337da2899SCharles.Forsyth 	}
5437da2899SCharles.Forsyth }
5537da2899SCharles.Forsyth 
5637da2899SCharles.Forsyth void
Math_import_real32(void * fp)5737da2899SCharles.Forsyth Math_import_real32(void *fp)
5837da2899SCharles.Forsyth {
5937da2899SCharles.Forsyth 	F_Math_import_int *f;
6037da2899SCharles.Forsyth 	int i, n;
6137da2899SCharles.Forsyth 	unsigned int u;
6237da2899SCharles.Forsyth 	unsigned char *bp;
6337da2899SCharles.Forsyth 	double *x;
6437da2899SCharles.Forsyth 
6537da2899SCharles.Forsyth 	f = fp;
6637da2899SCharles.Forsyth 	n = f->x->len;
6737da2899SCharles.Forsyth 	if(f->b->len!=4*n)
6837da2899SCharles.Forsyth 		error(exMathia);
6937da2899SCharles.Forsyth 	bp = (unsigned char *)(f->b->data);
7037da2899SCharles.Forsyth 	x = (double*)(f->x->data);
7137da2899SCharles.Forsyth 	for(i=0; i<n; i++){
7237da2899SCharles.Forsyth 		u = *bp++;
7337da2899SCharles.Forsyth 		u = (u<<8) | *bp++;
7437da2899SCharles.Forsyth 		u = (u<<8) | *bp++;
7537da2899SCharles.Forsyth 		u = (u<<8) | *bp++;
7637da2899SCharles.Forsyth 		bits32.u = u;
7737da2899SCharles.Forsyth 		x[i] = bits32.x;
7837da2899SCharles.Forsyth 	}
7937da2899SCharles.Forsyth }
8037da2899SCharles.Forsyth 
8137da2899SCharles.Forsyth void
Math_import_real(void * fp)8237da2899SCharles.Forsyth Math_import_real(void *fp)
8337da2899SCharles.Forsyth {
8437da2899SCharles.Forsyth 	F_Math_import_int *f;
8537da2899SCharles.Forsyth 	int i, n;
8637da2899SCharles.Forsyth 	uvlong u;
8737da2899SCharles.Forsyth 	unsigned char *bp;
8837da2899SCharles.Forsyth 	double *x;
8937da2899SCharles.Forsyth 
9037da2899SCharles.Forsyth 	f = fp;
9137da2899SCharles.Forsyth 	n = f->x->len;
9237da2899SCharles.Forsyth 	if(f->b->len!=8*n)
9337da2899SCharles.Forsyth 		error(exMathia);
9437da2899SCharles.Forsyth 	bp = f->b->data;
9537da2899SCharles.Forsyth 	x = (double*)(f->x->data);
9637da2899SCharles.Forsyth 	for(i=0; i<n; i++){
9737da2899SCharles.Forsyth 		u = *bp++;
9837da2899SCharles.Forsyth 		u = (u<<8) | *bp++;
9937da2899SCharles.Forsyth 		u = (u<<8) | *bp++;
10037da2899SCharles.Forsyth 		u = (u<<8) | *bp++;
10137da2899SCharles.Forsyth 		u = (u<<8) | *bp++;
10237da2899SCharles.Forsyth 		u = (u<<8) | *bp++;
10337da2899SCharles.Forsyth 		u = (u<<8) | *bp++;
10437da2899SCharles.Forsyth 		u = (u<<8) | *bp++;
10537da2899SCharles.Forsyth 		bits64.u = u;
10637da2899SCharles.Forsyth 		x[i] = bits64.x;
10737da2899SCharles.Forsyth 	}
10837da2899SCharles.Forsyth }
10937da2899SCharles.Forsyth 
11037da2899SCharles.Forsyth void
Math_export_int(void * fp)11137da2899SCharles.Forsyth Math_export_int(void *fp)
11237da2899SCharles.Forsyth {
11337da2899SCharles.Forsyth 	F_Math_export_int *f;
11437da2899SCharles.Forsyth 	int i, n;
11537da2899SCharles.Forsyth 	unsigned int u;
11637da2899SCharles.Forsyth 	unsigned char *bp;
11737da2899SCharles.Forsyth 	int *x;
11837da2899SCharles.Forsyth 
11937da2899SCharles.Forsyth 	f = fp;
12037da2899SCharles.Forsyth 	n = f->x->len;
12137da2899SCharles.Forsyth 	if(f->b->len!=4*n)
12237da2899SCharles.Forsyth 		error(exMathia);
12337da2899SCharles.Forsyth 	bp = (unsigned char *)(f->b->data);
12437da2899SCharles.Forsyth 	x = (int*)(f->x->data);
12537da2899SCharles.Forsyth 	for(i=0; i<n; i++){
12637da2899SCharles.Forsyth 		u = x[i];
12737da2899SCharles.Forsyth 		*bp++ = u>>24;
12837da2899SCharles.Forsyth 		*bp++ = u>>16;
12937da2899SCharles.Forsyth 		*bp++ = u>>8;
13037da2899SCharles.Forsyth 		*bp++ = u;
13137da2899SCharles.Forsyth 	}
13237da2899SCharles.Forsyth }
13337da2899SCharles.Forsyth 
13437da2899SCharles.Forsyth void
Math_export_real32(void * fp)13537da2899SCharles.Forsyth Math_export_real32(void *fp)
13637da2899SCharles.Forsyth {
13737da2899SCharles.Forsyth 	F_Math_export_int *f;
13837da2899SCharles.Forsyth 	int i, n;
13937da2899SCharles.Forsyth 	unsigned int u;
14037da2899SCharles.Forsyth 	unsigned char *bp;
14137da2899SCharles.Forsyth 	double *x;
14237da2899SCharles.Forsyth 
14337da2899SCharles.Forsyth 	f = fp;
14437da2899SCharles.Forsyth 	n = f->x->len;
14537da2899SCharles.Forsyth 	if(f->b->len!=4*n)
14637da2899SCharles.Forsyth 		error(exMathia);
14737da2899SCharles.Forsyth 	bp = (unsigned char *)(f->b->data);
14837da2899SCharles.Forsyth 	x = (double*)(f->x->data);
14937da2899SCharles.Forsyth 	for(i=0; i<n; i++){
15037da2899SCharles.Forsyth 		bits32.x = x[i];
15137da2899SCharles.Forsyth 		u = bits32.u;
15237da2899SCharles.Forsyth 		*bp++ = u>>24;
15337da2899SCharles.Forsyth 		*bp++ = u>>16;
15437da2899SCharles.Forsyth 		*bp++ = u>>8;
15537da2899SCharles.Forsyth 		*bp++ = u;
15637da2899SCharles.Forsyth 	}
15737da2899SCharles.Forsyth }
15837da2899SCharles.Forsyth 
15937da2899SCharles.Forsyth void
Math_export_real(void * fp)16037da2899SCharles.Forsyth Math_export_real(void *fp)
16137da2899SCharles.Forsyth {
16237da2899SCharles.Forsyth 	F_Math_export_int *f;
16337da2899SCharles.Forsyth 	int i, n;
16437da2899SCharles.Forsyth 	uvlong u;
16537da2899SCharles.Forsyth 	unsigned char *bp;
16637da2899SCharles.Forsyth 	double *x;
16737da2899SCharles.Forsyth 
16837da2899SCharles.Forsyth 	f = fp;
16937da2899SCharles.Forsyth 	n = f->x->len;
17037da2899SCharles.Forsyth 	if(f->b->len!=8*n)
17137da2899SCharles.Forsyth 		error(exMathia);
17237da2899SCharles.Forsyth 	bp = (unsigned char *)(f->b->data);
17337da2899SCharles.Forsyth 	x = (double*)(f->x->data);
17437da2899SCharles.Forsyth 	for(i=0; i<n; i++){
17537da2899SCharles.Forsyth 		bits64.x = x[i];
17637da2899SCharles.Forsyth 		u = bits64.u;
17737da2899SCharles.Forsyth 		*bp++ = u>>56;
17837da2899SCharles.Forsyth 		*bp++ = u>>48;
17937da2899SCharles.Forsyth 		*bp++ = u>>40;
18037da2899SCharles.Forsyth 		*bp++ = u>>32;
18137da2899SCharles.Forsyth 		*bp++ = u>>24;
18237da2899SCharles.Forsyth 		*bp++ = u>>16;
18337da2899SCharles.Forsyth 		*bp++ = u>>8;
18437da2899SCharles.Forsyth 		*bp++ = u;
18537da2899SCharles.Forsyth 	}
18637da2899SCharles.Forsyth }
18737da2899SCharles.Forsyth 
18837da2899SCharles.Forsyth 
18937da2899SCharles.Forsyth void
Math_bits32real(void * fp)19037da2899SCharles.Forsyth Math_bits32real(void *fp)
19137da2899SCharles.Forsyth {
19237da2899SCharles.Forsyth 	F_Math_bits32real *f;
19337da2899SCharles.Forsyth 
19437da2899SCharles.Forsyth 	f = fp;
19537da2899SCharles.Forsyth 	bits32.u = f->b;
19637da2899SCharles.Forsyth 	*f->ret = bits32.x;
19737da2899SCharles.Forsyth }
19837da2899SCharles.Forsyth 
19937da2899SCharles.Forsyth void
Math_bits64real(void * fp)20037da2899SCharles.Forsyth Math_bits64real(void *fp)
20137da2899SCharles.Forsyth {
20237da2899SCharles.Forsyth 	F_Math_bits64real *f;
20337da2899SCharles.Forsyth 
20437da2899SCharles.Forsyth 	f = fp;
20537da2899SCharles.Forsyth 	bits64.u = f->b;
20637da2899SCharles.Forsyth 	*f->ret = bits64.x;
20737da2899SCharles.Forsyth }
20837da2899SCharles.Forsyth 
20937da2899SCharles.Forsyth void
Math_realbits32(void * fp)21037da2899SCharles.Forsyth Math_realbits32(void *fp)
21137da2899SCharles.Forsyth {
21237da2899SCharles.Forsyth 	F_Math_realbits32 *f;
21337da2899SCharles.Forsyth 
21437da2899SCharles.Forsyth 	f = fp;
21537da2899SCharles.Forsyth 	bits32.x = f->x;
21637da2899SCharles.Forsyth 	*f->ret = bits32.u;
21737da2899SCharles.Forsyth }
21837da2899SCharles.Forsyth 
21937da2899SCharles.Forsyth void
Math_realbits64(void * fp)22037da2899SCharles.Forsyth Math_realbits64(void *fp)
22137da2899SCharles.Forsyth {
22237da2899SCharles.Forsyth 	F_Math_realbits64 *f;
22337da2899SCharles.Forsyth 
22437da2899SCharles.Forsyth 	f = fp;
22537da2899SCharles.Forsyth 	bits64.x = f->x;
22637da2899SCharles.Forsyth 	*f->ret = bits64.u;
22737da2899SCharles.Forsyth }
22837da2899SCharles.Forsyth 
22937da2899SCharles.Forsyth 
23037da2899SCharles.Forsyth void
Math_getFPcontrol(void * fp)23137da2899SCharles.Forsyth Math_getFPcontrol(void *fp)
23237da2899SCharles.Forsyth {
23337da2899SCharles.Forsyth 	F_Math_getFPcontrol *f;
23437da2899SCharles.Forsyth 
23537da2899SCharles.Forsyth 	f = fp;
23637da2899SCharles.Forsyth 
23737da2899SCharles.Forsyth 	*f->ret = getFPcontrol();
23837da2899SCharles.Forsyth }
23937da2899SCharles.Forsyth 
24037da2899SCharles.Forsyth void
Math_getFPstatus(void * fp)24137da2899SCharles.Forsyth Math_getFPstatus(void *fp)
24237da2899SCharles.Forsyth {
24337da2899SCharles.Forsyth 	F_Math_getFPstatus *f;
24437da2899SCharles.Forsyth 
24537da2899SCharles.Forsyth 	f = fp;
24637da2899SCharles.Forsyth 
24737da2899SCharles.Forsyth 	*f->ret = getFPstatus();
24837da2899SCharles.Forsyth }
24937da2899SCharles.Forsyth 
25037da2899SCharles.Forsyth void
Math_finite(void * fp)25137da2899SCharles.Forsyth Math_finite(void *fp)
25237da2899SCharles.Forsyth {
25337da2899SCharles.Forsyth 	F_Math_finite *f;
25437da2899SCharles.Forsyth 
25537da2899SCharles.Forsyth 	f = fp;
25637da2899SCharles.Forsyth 
25737da2899SCharles.Forsyth 	*f->ret = finite(f->x);
25837da2899SCharles.Forsyth }
25937da2899SCharles.Forsyth 
26037da2899SCharles.Forsyth void
Math_ilogb(void * fp)26137da2899SCharles.Forsyth Math_ilogb(void *fp)
26237da2899SCharles.Forsyth {
26337da2899SCharles.Forsyth 	F_Math_ilogb *f;
26437da2899SCharles.Forsyth 
26537da2899SCharles.Forsyth 	f = fp;
26637da2899SCharles.Forsyth 
26737da2899SCharles.Forsyth 	*f->ret = ilogb(f->x);
26837da2899SCharles.Forsyth }
26937da2899SCharles.Forsyth 
27037da2899SCharles.Forsyth void
Math_isnan(void * fp)27137da2899SCharles.Forsyth Math_isnan(void *fp)
27237da2899SCharles.Forsyth {
27337da2899SCharles.Forsyth 	F_Math_isnan *f;
27437da2899SCharles.Forsyth 
27537da2899SCharles.Forsyth 	f = fp;
27637da2899SCharles.Forsyth 
277*cd03a2dcSforsyth 	*f->ret = isNaN(f->x);
27837da2899SCharles.Forsyth }
27937da2899SCharles.Forsyth 
28037da2899SCharles.Forsyth void
Math_acos(void * fp)28137da2899SCharles.Forsyth Math_acos(void *fp)
28237da2899SCharles.Forsyth {
28337da2899SCharles.Forsyth 	F_Math_acos *f;
28437da2899SCharles.Forsyth 
28537da2899SCharles.Forsyth 	f = fp;
28637da2899SCharles.Forsyth 
28737da2899SCharles.Forsyth 	*f->ret = __ieee754_acos(f->x);
28837da2899SCharles.Forsyth }
28937da2899SCharles.Forsyth 
29037da2899SCharles.Forsyth void
Math_acosh(void * fp)29137da2899SCharles.Forsyth Math_acosh(void *fp)
29237da2899SCharles.Forsyth {
29337da2899SCharles.Forsyth 	F_Math_acosh *f;
29437da2899SCharles.Forsyth 
29537da2899SCharles.Forsyth 	f = fp;
29637da2899SCharles.Forsyth 
29737da2899SCharles.Forsyth 	*f->ret = __ieee754_acosh(f->x);
29837da2899SCharles.Forsyth }
29937da2899SCharles.Forsyth 
30037da2899SCharles.Forsyth void
Math_asin(void * fp)30137da2899SCharles.Forsyth Math_asin(void *fp)
30237da2899SCharles.Forsyth {
30337da2899SCharles.Forsyth 	F_Math_asin *f;
30437da2899SCharles.Forsyth 
30537da2899SCharles.Forsyth 	f = fp;
30637da2899SCharles.Forsyth 
30737da2899SCharles.Forsyth 	*f->ret = __ieee754_asin(f->x);
30837da2899SCharles.Forsyth }
30937da2899SCharles.Forsyth 
31037da2899SCharles.Forsyth void
Math_asinh(void * fp)31137da2899SCharles.Forsyth Math_asinh(void *fp)
31237da2899SCharles.Forsyth {
31337da2899SCharles.Forsyth 	F_Math_asinh *f;
31437da2899SCharles.Forsyth 
31537da2899SCharles.Forsyth 	f = fp;
31637da2899SCharles.Forsyth 
31737da2899SCharles.Forsyth 	*f->ret = asinh(f->x);
31837da2899SCharles.Forsyth }
31937da2899SCharles.Forsyth 
32037da2899SCharles.Forsyth void
Math_atan(void * fp)32137da2899SCharles.Forsyth Math_atan(void *fp)
32237da2899SCharles.Forsyth {
32337da2899SCharles.Forsyth 	F_Math_atan *f;
32437da2899SCharles.Forsyth 
32537da2899SCharles.Forsyth 	f = fp;
32637da2899SCharles.Forsyth 
32737da2899SCharles.Forsyth 	*f->ret = atan(f->x);
32837da2899SCharles.Forsyth }
32937da2899SCharles.Forsyth 
33037da2899SCharles.Forsyth void
Math_atanh(void * fp)33137da2899SCharles.Forsyth Math_atanh(void *fp)
33237da2899SCharles.Forsyth {
33337da2899SCharles.Forsyth 	F_Math_atanh *f;
33437da2899SCharles.Forsyth 
33537da2899SCharles.Forsyth 	f = fp;
33637da2899SCharles.Forsyth 
33737da2899SCharles.Forsyth 	*f->ret = __ieee754_atanh(f->x);
33837da2899SCharles.Forsyth }
33937da2899SCharles.Forsyth 
34037da2899SCharles.Forsyth void
Math_cbrt(void * fp)34137da2899SCharles.Forsyth Math_cbrt(void *fp)
34237da2899SCharles.Forsyth {
34337da2899SCharles.Forsyth 	F_Math_cbrt *f;
34437da2899SCharles.Forsyth 
34537da2899SCharles.Forsyth 	f = fp;
34637da2899SCharles.Forsyth 
34737da2899SCharles.Forsyth 	*f->ret = cbrt(f->x);
34837da2899SCharles.Forsyth }
34937da2899SCharles.Forsyth 
35037da2899SCharles.Forsyth void
Math_ceil(void * fp)35137da2899SCharles.Forsyth Math_ceil(void *fp)
35237da2899SCharles.Forsyth {
35337da2899SCharles.Forsyth 	F_Math_ceil *f;
35437da2899SCharles.Forsyth 
35537da2899SCharles.Forsyth 	f = fp;
35637da2899SCharles.Forsyth 
35737da2899SCharles.Forsyth 	*f->ret = ceil(f->x);
35837da2899SCharles.Forsyth }
35937da2899SCharles.Forsyth 
36037da2899SCharles.Forsyth void
Math_cos(void * fp)36137da2899SCharles.Forsyth Math_cos(void *fp)
36237da2899SCharles.Forsyth {
36337da2899SCharles.Forsyth 	F_Math_cos *f;
36437da2899SCharles.Forsyth 
36537da2899SCharles.Forsyth 	f = fp;
36637da2899SCharles.Forsyth 
36737da2899SCharles.Forsyth 	*f->ret = cos(f->x);
36837da2899SCharles.Forsyth }
36937da2899SCharles.Forsyth 
37037da2899SCharles.Forsyth void
Math_cosh(void * fp)37137da2899SCharles.Forsyth Math_cosh(void *fp)
37237da2899SCharles.Forsyth {
37337da2899SCharles.Forsyth 	F_Math_cosh *f;
37437da2899SCharles.Forsyth 
37537da2899SCharles.Forsyth 	f = fp;
37637da2899SCharles.Forsyth 
37737da2899SCharles.Forsyth 	*f->ret = __ieee754_cosh(f->x);
37837da2899SCharles.Forsyth }
37937da2899SCharles.Forsyth 
38037da2899SCharles.Forsyth void
Math_erf(void * fp)38137da2899SCharles.Forsyth Math_erf(void *fp)
38237da2899SCharles.Forsyth {
38337da2899SCharles.Forsyth 	F_Math_erf *f;
38437da2899SCharles.Forsyth 
38537da2899SCharles.Forsyth 	f = fp;
38637da2899SCharles.Forsyth 
38737da2899SCharles.Forsyth 	*f->ret = erf(f->x);
38837da2899SCharles.Forsyth }
38937da2899SCharles.Forsyth 
39037da2899SCharles.Forsyth void
Math_erfc(void * fp)39137da2899SCharles.Forsyth Math_erfc(void *fp)
39237da2899SCharles.Forsyth {
39337da2899SCharles.Forsyth 	F_Math_erfc *f;
39437da2899SCharles.Forsyth 
39537da2899SCharles.Forsyth 	f = fp;
39637da2899SCharles.Forsyth 
39737da2899SCharles.Forsyth 	*f->ret = erfc(f->x);
39837da2899SCharles.Forsyth }
39937da2899SCharles.Forsyth 
40037da2899SCharles.Forsyth void
Math_exp(void * fp)40137da2899SCharles.Forsyth Math_exp(void *fp)
40237da2899SCharles.Forsyth {
40337da2899SCharles.Forsyth 	F_Math_exp *f;
40437da2899SCharles.Forsyth 
40537da2899SCharles.Forsyth 	f = fp;
40637da2899SCharles.Forsyth 
40737da2899SCharles.Forsyth 	*f->ret = __ieee754_exp(f->x);
40837da2899SCharles.Forsyth }
40937da2899SCharles.Forsyth 
41037da2899SCharles.Forsyth void
Math_expm1(void * fp)41137da2899SCharles.Forsyth Math_expm1(void *fp)
41237da2899SCharles.Forsyth {
41337da2899SCharles.Forsyth 	F_Math_expm1 *f;
41437da2899SCharles.Forsyth 
41537da2899SCharles.Forsyth 	f = fp;
41637da2899SCharles.Forsyth 
41737da2899SCharles.Forsyth 	*f->ret = expm1(f->x);
41837da2899SCharles.Forsyth }
41937da2899SCharles.Forsyth 
42037da2899SCharles.Forsyth void
Math_fabs(void * fp)42137da2899SCharles.Forsyth Math_fabs(void *fp)
42237da2899SCharles.Forsyth {
42337da2899SCharles.Forsyth 	F_Math_fabs *f;
42437da2899SCharles.Forsyth 
42537da2899SCharles.Forsyth 	f = fp;
42637da2899SCharles.Forsyth 
42737da2899SCharles.Forsyth 	*f->ret = fabs(f->x);
42837da2899SCharles.Forsyth }
42937da2899SCharles.Forsyth 
43037da2899SCharles.Forsyth void
Math_floor(void * fp)43137da2899SCharles.Forsyth Math_floor(void *fp)
43237da2899SCharles.Forsyth {
43337da2899SCharles.Forsyth 	F_Math_floor *f;
43437da2899SCharles.Forsyth 
43537da2899SCharles.Forsyth 	f = fp;
43637da2899SCharles.Forsyth 
43737da2899SCharles.Forsyth 	*f->ret = floor(f->x);
43837da2899SCharles.Forsyth }
43937da2899SCharles.Forsyth 
44037da2899SCharles.Forsyth void
Math_j0(void * fp)44137da2899SCharles.Forsyth Math_j0(void *fp)
44237da2899SCharles.Forsyth {
44337da2899SCharles.Forsyth 	F_Math_j0 *f;
44437da2899SCharles.Forsyth 
44537da2899SCharles.Forsyth 	f = fp;
44637da2899SCharles.Forsyth 
44737da2899SCharles.Forsyth 	*f->ret = __ieee754_j0(f->x);
44837da2899SCharles.Forsyth }
44937da2899SCharles.Forsyth 
45037da2899SCharles.Forsyth void
Math_j1(void * fp)45137da2899SCharles.Forsyth Math_j1(void *fp)
45237da2899SCharles.Forsyth {
45337da2899SCharles.Forsyth 	F_Math_j1 *f;
45437da2899SCharles.Forsyth 
45537da2899SCharles.Forsyth 	f = fp;
45637da2899SCharles.Forsyth 
45737da2899SCharles.Forsyth 	*f->ret = __ieee754_j1(f->x);
45837da2899SCharles.Forsyth }
45937da2899SCharles.Forsyth 
46037da2899SCharles.Forsyth void
Math_log(void * fp)46137da2899SCharles.Forsyth Math_log(void *fp)
46237da2899SCharles.Forsyth {
46337da2899SCharles.Forsyth 	F_Math_log *f;
46437da2899SCharles.Forsyth 
46537da2899SCharles.Forsyth 	f = fp;
46637da2899SCharles.Forsyth 
46737da2899SCharles.Forsyth 	*f->ret = __ieee754_log(f->x);
46837da2899SCharles.Forsyth }
46937da2899SCharles.Forsyth 
47037da2899SCharles.Forsyth void
Math_log10(void * fp)47137da2899SCharles.Forsyth Math_log10(void *fp)
47237da2899SCharles.Forsyth {
47337da2899SCharles.Forsyth 	F_Math_log10 *f;
47437da2899SCharles.Forsyth 
47537da2899SCharles.Forsyth 	f = fp;
47637da2899SCharles.Forsyth 
47737da2899SCharles.Forsyth 	*f->ret = __ieee754_log10(f->x);
47837da2899SCharles.Forsyth }
47937da2899SCharles.Forsyth 
48037da2899SCharles.Forsyth void
Math_log1p(void * fp)48137da2899SCharles.Forsyth Math_log1p(void *fp)
48237da2899SCharles.Forsyth {
48337da2899SCharles.Forsyth 	F_Math_log1p *f;
48437da2899SCharles.Forsyth 
48537da2899SCharles.Forsyth 	f = fp;
48637da2899SCharles.Forsyth 
48737da2899SCharles.Forsyth 	*f->ret = log1p(f->x);
48837da2899SCharles.Forsyth }
48937da2899SCharles.Forsyth 
49037da2899SCharles.Forsyth void
Math_rint(void * fp)49137da2899SCharles.Forsyth Math_rint(void *fp)
49237da2899SCharles.Forsyth {
49337da2899SCharles.Forsyth 	F_Math_rint *f;
49437da2899SCharles.Forsyth 
49537da2899SCharles.Forsyth 	f = fp;
49637da2899SCharles.Forsyth 
49737da2899SCharles.Forsyth 	*f->ret = rint(f->x);
49837da2899SCharles.Forsyth }
49937da2899SCharles.Forsyth 
50037da2899SCharles.Forsyth void
Math_sin(void * fp)50137da2899SCharles.Forsyth Math_sin(void *fp)
50237da2899SCharles.Forsyth {
50337da2899SCharles.Forsyth 	F_Math_sin *f;
50437da2899SCharles.Forsyth 
50537da2899SCharles.Forsyth 	f = fp;
50637da2899SCharles.Forsyth 
50737da2899SCharles.Forsyth 	*f->ret = sin(f->x);
50837da2899SCharles.Forsyth }
50937da2899SCharles.Forsyth 
51037da2899SCharles.Forsyth void
Math_sinh(void * fp)51137da2899SCharles.Forsyth Math_sinh(void *fp)
51237da2899SCharles.Forsyth {
51337da2899SCharles.Forsyth 	F_Math_sinh *f;
51437da2899SCharles.Forsyth 
51537da2899SCharles.Forsyth 	f = fp;
51637da2899SCharles.Forsyth 
51737da2899SCharles.Forsyth 	*f->ret = __ieee754_sinh(f->x);
51837da2899SCharles.Forsyth }
51937da2899SCharles.Forsyth 
52037da2899SCharles.Forsyth void
Math_sqrt(void * fp)52137da2899SCharles.Forsyth Math_sqrt(void *fp)
52237da2899SCharles.Forsyth {
52337da2899SCharles.Forsyth 	F_Math_sqrt *f;
52437da2899SCharles.Forsyth 
52537da2899SCharles.Forsyth 	f = fp;
52637da2899SCharles.Forsyth 
52737da2899SCharles.Forsyth 	*f->ret = __ieee754_sqrt(f->x);
52837da2899SCharles.Forsyth }
52937da2899SCharles.Forsyth 
53037da2899SCharles.Forsyth void
Math_tan(void * fp)53137da2899SCharles.Forsyth Math_tan(void *fp)
53237da2899SCharles.Forsyth {
53337da2899SCharles.Forsyth 	F_Math_tan *f;
53437da2899SCharles.Forsyth 
53537da2899SCharles.Forsyth 	f = fp;
53637da2899SCharles.Forsyth 
53737da2899SCharles.Forsyth 	*f->ret = tan(f->x);
53837da2899SCharles.Forsyth }
53937da2899SCharles.Forsyth 
54037da2899SCharles.Forsyth void
Math_tanh(void * fp)54137da2899SCharles.Forsyth Math_tanh(void *fp)
54237da2899SCharles.Forsyth {
54337da2899SCharles.Forsyth 	F_Math_tanh *f;
54437da2899SCharles.Forsyth 
54537da2899SCharles.Forsyth 	f = fp;
54637da2899SCharles.Forsyth 
54737da2899SCharles.Forsyth 	*f->ret = tanh(f->x);
54837da2899SCharles.Forsyth }
54937da2899SCharles.Forsyth 
55037da2899SCharles.Forsyth void
Math_y0(void * fp)55137da2899SCharles.Forsyth Math_y0(void *fp)
55237da2899SCharles.Forsyth {
55337da2899SCharles.Forsyth 	F_Math_y0 *f;
55437da2899SCharles.Forsyth 
55537da2899SCharles.Forsyth 	f = fp;
55637da2899SCharles.Forsyth 
55737da2899SCharles.Forsyth 	*f->ret = __ieee754_y0(f->x);
55837da2899SCharles.Forsyth }
55937da2899SCharles.Forsyth 
56037da2899SCharles.Forsyth void
Math_y1(void * fp)56137da2899SCharles.Forsyth Math_y1(void *fp)
56237da2899SCharles.Forsyth {
56337da2899SCharles.Forsyth 	F_Math_y1 *f;
56437da2899SCharles.Forsyth 
56537da2899SCharles.Forsyth 	f = fp;
56637da2899SCharles.Forsyth 
56737da2899SCharles.Forsyth 	*f->ret = __ieee754_y1(f->x);
56837da2899SCharles.Forsyth }
56937da2899SCharles.Forsyth 
57037da2899SCharles.Forsyth void
Math_fdim(void * fp)57137da2899SCharles.Forsyth Math_fdim(void *fp)
57237da2899SCharles.Forsyth {
57337da2899SCharles.Forsyth 	F_Math_fdim *f;
57437da2899SCharles.Forsyth 
57537da2899SCharles.Forsyth 	f = fp;
57637da2899SCharles.Forsyth 
57737da2899SCharles.Forsyth 	*f->ret = fdim(f->x, f->y);
57837da2899SCharles.Forsyth }
57937da2899SCharles.Forsyth 
58037da2899SCharles.Forsyth void
Math_fmax(void * fp)58137da2899SCharles.Forsyth Math_fmax(void *fp)
58237da2899SCharles.Forsyth {
58337da2899SCharles.Forsyth 	F_Math_fmax *f;
58437da2899SCharles.Forsyth 
58537da2899SCharles.Forsyth 	f = fp;
58637da2899SCharles.Forsyth 
58737da2899SCharles.Forsyth 	*f->ret = fmax(f->x, f->y);
58837da2899SCharles.Forsyth }
58937da2899SCharles.Forsyth 
59037da2899SCharles.Forsyth void
Math_fmin(void * fp)59137da2899SCharles.Forsyth Math_fmin(void *fp)
59237da2899SCharles.Forsyth {
59337da2899SCharles.Forsyth 	F_Math_fmin *f;
59437da2899SCharles.Forsyth 
59537da2899SCharles.Forsyth 	f = fp;
59637da2899SCharles.Forsyth 
59737da2899SCharles.Forsyth 	*f->ret = fmin(f->x, f->y);
59837da2899SCharles.Forsyth }
59937da2899SCharles.Forsyth 
60037da2899SCharles.Forsyth void
Math_fmod(void * fp)60137da2899SCharles.Forsyth Math_fmod(void *fp)
60237da2899SCharles.Forsyth {
60337da2899SCharles.Forsyth 	F_Math_fmod *f;
60437da2899SCharles.Forsyth 
60537da2899SCharles.Forsyth 	f = fp;
60637da2899SCharles.Forsyth 
60737da2899SCharles.Forsyth 	*f->ret = __ieee754_fmod(f->x, f->y);
60837da2899SCharles.Forsyth }
60937da2899SCharles.Forsyth 
61037da2899SCharles.Forsyth void
Math_hypot(void * fp)61137da2899SCharles.Forsyth Math_hypot(void *fp)
61237da2899SCharles.Forsyth {
61337da2899SCharles.Forsyth 	F_Math_hypot *f;
61437da2899SCharles.Forsyth 
61537da2899SCharles.Forsyth 	f = fp;
61637da2899SCharles.Forsyth 
61737da2899SCharles.Forsyth 	*f->ret = __ieee754_hypot(f->x, f->y);
61837da2899SCharles.Forsyth }
61937da2899SCharles.Forsyth 
62037da2899SCharles.Forsyth void
Math_nextafter(void * fp)62137da2899SCharles.Forsyth Math_nextafter(void *fp)
62237da2899SCharles.Forsyth {
62337da2899SCharles.Forsyth 	F_Math_nextafter *f;
62437da2899SCharles.Forsyth 
62537da2899SCharles.Forsyth 	f = fp;
62637da2899SCharles.Forsyth 
62737da2899SCharles.Forsyth 	*f->ret = nextafter(f->x, f->y);
62837da2899SCharles.Forsyth }
62937da2899SCharles.Forsyth 
63037da2899SCharles.Forsyth void
Math_pow(void * fp)63137da2899SCharles.Forsyth Math_pow(void *fp)
63237da2899SCharles.Forsyth {
63337da2899SCharles.Forsyth 	F_Math_pow *f;
63437da2899SCharles.Forsyth 
63537da2899SCharles.Forsyth 	f = fp;
63637da2899SCharles.Forsyth 
63737da2899SCharles.Forsyth 	*f->ret = __ieee754_pow(f->x, f->y);
63837da2899SCharles.Forsyth }
63937da2899SCharles.Forsyth 
64037da2899SCharles.Forsyth 
64137da2899SCharles.Forsyth 
64237da2899SCharles.Forsyth void
Math_FPcontrol(void * fp)64337da2899SCharles.Forsyth Math_FPcontrol(void *fp)
64437da2899SCharles.Forsyth {
64537da2899SCharles.Forsyth 	F_Math_FPcontrol *f;
64637da2899SCharles.Forsyth 
64737da2899SCharles.Forsyth 	f = fp;
64837da2899SCharles.Forsyth 
64937da2899SCharles.Forsyth 	*f->ret = FPcontrol(f->r, f->mask);
65037da2899SCharles.Forsyth }
65137da2899SCharles.Forsyth 
65237da2899SCharles.Forsyth void
Math_FPstatus(void * fp)65337da2899SCharles.Forsyth Math_FPstatus(void *fp)
65437da2899SCharles.Forsyth {
65537da2899SCharles.Forsyth 	F_Math_FPstatus *f;
65637da2899SCharles.Forsyth 
65737da2899SCharles.Forsyth 	f = fp;
65837da2899SCharles.Forsyth 
65937da2899SCharles.Forsyth 	*f->ret = FPstatus(f->r, f->mask);
66037da2899SCharles.Forsyth }
66137da2899SCharles.Forsyth 
66237da2899SCharles.Forsyth void
Math_atan2(void * fp)66337da2899SCharles.Forsyth Math_atan2(void *fp)
66437da2899SCharles.Forsyth {
66537da2899SCharles.Forsyth 	F_Math_atan2 *f;
66637da2899SCharles.Forsyth 
66737da2899SCharles.Forsyth 	f = fp;
66837da2899SCharles.Forsyth 
66937da2899SCharles.Forsyth 	*f->ret = __ieee754_atan2(f->y, f->x);
67037da2899SCharles.Forsyth }
67137da2899SCharles.Forsyth 
67237da2899SCharles.Forsyth void
Math_copysign(void * fp)67337da2899SCharles.Forsyth Math_copysign(void *fp)
67437da2899SCharles.Forsyth {
67537da2899SCharles.Forsyth 	F_Math_copysign *f;
67637da2899SCharles.Forsyth 
67737da2899SCharles.Forsyth 	f = fp;
67837da2899SCharles.Forsyth 
67937da2899SCharles.Forsyth 	*f->ret = copysign(f->x, f->s);
68037da2899SCharles.Forsyth }
68137da2899SCharles.Forsyth 
68237da2899SCharles.Forsyth void
Math_jn(void * fp)68337da2899SCharles.Forsyth Math_jn(void *fp)
68437da2899SCharles.Forsyth {
68537da2899SCharles.Forsyth 	F_Math_jn *f;
68637da2899SCharles.Forsyth 
68737da2899SCharles.Forsyth 	f = fp;
68837da2899SCharles.Forsyth 
68937da2899SCharles.Forsyth 	*f->ret = __ieee754_jn(f->n, f->x);
69037da2899SCharles.Forsyth }
69137da2899SCharles.Forsyth 
69237da2899SCharles.Forsyth void
Math_lgamma(void * fp)69337da2899SCharles.Forsyth Math_lgamma(void *fp)
69437da2899SCharles.Forsyth {
69537da2899SCharles.Forsyth 	F_Math_lgamma *f;
69637da2899SCharles.Forsyth 
69737da2899SCharles.Forsyth 	f = fp;
69837da2899SCharles.Forsyth 
69937da2899SCharles.Forsyth 	f->ret->t1 = __ieee754_lgamma_r(f->x, &f->ret->t0);
70037da2899SCharles.Forsyth }
70137da2899SCharles.Forsyth 
70237da2899SCharles.Forsyth void
Math_modf(void * fp)70337da2899SCharles.Forsyth Math_modf(void *fp)
70437da2899SCharles.Forsyth {
70537da2899SCharles.Forsyth 	F_Math_modf *f;
70637da2899SCharles.Forsyth 	double ipart;
70737da2899SCharles.Forsyth 
70837da2899SCharles.Forsyth 	f = fp;
70937da2899SCharles.Forsyth 
71037da2899SCharles.Forsyth 	f->ret->t1 = modf(f->x, &ipart);
71137da2899SCharles.Forsyth 	f->ret->t0 = ipart;
71237da2899SCharles.Forsyth }
71337da2899SCharles.Forsyth 
71437da2899SCharles.Forsyth void
Math_pow10(void * fp)71537da2899SCharles.Forsyth Math_pow10(void *fp)
71637da2899SCharles.Forsyth {
71737da2899SCharles.Forsyth 	F_Math_pow10 *f;
71837da2899SCharles.Forsyth 
71937da2899SCharles.Forsyth 	f = fp;
72037da2899SCharles.Forsyth 
72137da2899SCharles.Forsyth 	*f->ret = ipow10(f->p);
72237da2899SCharles.Forsyth }
72337da2899SCharles.Forsyth 
72437da2899SCharles.Forsyth void
Math_remainder(void * fp)72537da2899SCharles.Forsyth Math_remainder(void *fp)
72637da2899SCharles.Forsyth {
72737da2899SCharles.Forsyth 	F_Math_remainder *f;
72837da2899SCharles.Forsyth 
72937da2899SCharles.Forsyth 	f = fp;
73037da2899SCharles.Forsyth 
73137da2899SCharles.Forsyth 	*f->ret = __ieee754_remainder(f->x, f->p);
73237da2899SCharles.Forsyth }
73337da2899SCharles.Forsyth 
73437da2899SCharles.Forsyth void
Math_scalbn(void * fp)73537da2899SCharles.Forsyth Math_scalbn(void *fp)
73637da2899SCharles.Forsyth {
73737da2899SCharles.Forsyth 	F_Math_scalbn *f;
73837da2899SCharles.Forsyth 
73937da2899SCharles.Forsyth 	f = fp;
74037da2899SCharles.Forsyth 
74137da2899SCharles.Forsyth 	*f->ret = scalbn(f->x, f->n);
74237da2899SCharles.Forsyth }
74337da2899SCharles.Forsyth 
74437da2899SCharles.Forsyth void
Math_yn(void * fp)74537da2899SCharles.Forsyth Math_yn(void *fp)
74637da2899SCharles.Forsyth {
74737da2899SCharles.Forsyth 	F_Math_yn *f;
74837da2899SCharles.Forsyth 
74937da2899SCharles.Forsyth 	f = fp;
75037da2899SCharles.Forsyth 
75137da2899SCharles.Forsyth 	*f->ret = __ieee754_yn(f->n, f->x);
75237da2899SCharles.Forsyth }
75337da2899SCharles.Forsyth 
75437da2899SCharles.Forsyth 
75537da2899SCharles.Forsyth /**** sorting real vectors through permutation vector ****/
75637da2899SCharles.Forsyth /* qsort from coma:/usr/jlb/qsort/qsort.dir/qsort.c on 28 Sep '92
75737da2899SCharles.Forsyth  char* has been changed to uchar*, static internal functions.
75837da2899SCharles.Forsyth  specialized to swapping ints (which are 32-bit anyway in limbo).
75937da2899SCharles.Forsyth  converted uchar* to int* (and substituted 1 for es).
76037da2899SCharles.Forsyth */
76137da2899SCharles.Forsyth 
76237da2899SCharles.Forsyth static int
cmp(int * u,int * v,double * x)76337da2899SCharles.Forsyth cmp(int *u, int *v, double *x)
76437da2899SCharles.Forsyth {
76537da2899SCharles.Forsyth 	return ((x[*u]==x[*v])? 0 : ((x[*u]<x[*v])? -1 : 1));
76637da2899SCharles.Forsyth }
76737da2899SCharles.Forsyth 
76837da2899SCharles.Forsyth #define swap(u, v) {int t = *(u); *(u) = *(v); *(v) = t;}
76937da2899SCharles.Forsyth 
77037da2899SCharles.Forsyth #define vecswap(u, v, n) if(n>0){	\
77137da2899SCharles.Forsyth     int i = n;				\
77237da2899SCharles.Forsyth     register int *pi = u;		\
77337da2899SCharles.Forsyth     register int *pj = v;		\
77437da2899SCharles.Forsyth     do {				\
77537da2899SCharles.Forsyth         register int t = *pi;		\
77637da2899SCharles.Forsyth         *pi++ = *pj;			\
77737da2899SCharles.Forsyth         *pj++ = t;			\
77837da2899SCharles.Forsyth     } while (--i > 0);			\
77937da2899SCharles.Forsyth }
78037da2899SCharles.Forsyth 
78137da2899SCharles.Forsyth #define minimum(x, y) ((x)<=(y) ? (x) : (y))
78237da2899SCharles.Forsyth 
78337da2899SCharles.Forsyth static int *
med3(int * a,int * b,int * c,double * x)78437da2899SCharles.Forsyth med3(int *a, int *b, int *c, double *x)
78537da2899SCharles.Forsyth {	return cmp(a, b, x) < 0 ?
78637da2899SCharles.Forsyth 		  (cmp(b, c, x) < 0 ? b : (cmp(a, c, x) < 0 ? c : a ) )
78737da2899SCharles.Forsyth 		: (cmp(b, c, x) > 0 ? b : (cmp(a, c, x) < 0 ? a : c ) );
78837da2899SCharles.Forsyth }
78937da2899SCharles.Forsyth 
79037da2899SCharles.Forsyth void
rqsort(int * a,int n,double * x)79137da2899SCharles.Forsyth rqsort(int *a, int n, double *x)
79237da2899SCharles.Forsyth {
79337da2899SCharles.Forsyth 	int *pa, *pb, *pc, *pd, *pl, *pm, *pn;
79437da2899SCharles.Forsyth 	int  d, r;
79537da2899SCharles.Forsyth 
79637da2899SCharles.Forsyth 	if (n < 7) { /* Insertion sort on small arrays */
79737da2899SCharles.Forsyth 		for (pm = a + 1; pm < a + n; pm++)
79837da2899SCharles.Forsyth 			for (pl = pm; pl > a && cmp(pl-1, pl, x) > 0; pl--)
79937da2899SCharles.Forsyth 				swap(pl, pl-1);
80037da2899SCharles.Forsyth 		return;
80137da2899SCharles.Forsyth 	}
80237da2899SCharles.Forsyth 	pm = a + (n/2);
80337da2899SCharles.Forsyth 	if (n > 7) {
80437da2899SCharles.Forsyth 		pl = a;
80537da2899SCharles.Forsyth 		pn = a + (n-1);
80637da2899SCharles.Forsyth 		if (n > 40) { /* On big arrays, pseudomedian of 9 */
80737da2899SCharles.Forsyth 			d = (n/8);
80837da2899SCharles.Forsyth 			pl = med3(pl, pl+d, pl+2*d, x);
80937da2899SCharles.Forsyth 			pm = med3(pm-d, pm, pm+d, x);
81037da2899SCharles.Forsyth 			pn = med3(pn-2*d, pn-d, pn, x);
81137da2899SCharles.Forsyth 		}
81237da2899SCharles.Forsyth 		pm = med3(pl, pm, pn, x); /* On mid arrays, med of 3 */
81337da2899SCharles.Forsyth 	}
81437da2899SCharles.Forsyth 	swap(a, pm); /* On tiny arrays, partition around middle */
81537da2899SCharles.Forsyth 	pa = pb = a + 1;
81637da2899SCharles.Forsyth 	pc = pd = a + (n-1);
81737da2899SCharles.Forsyth 	for (;;) {
81837da2899SCharles.Forsyth 		while (pb <= pc && (r = cmp(pb, a, x)) <= 0) {
81937da2899SCharles.Forsyth 			if (r == 0) { swap(pa, pb); pa++; }
82037da2899SCharles.Forsyth 			pb++;
82137da2899SCharles.Forsyth 		}
82237da2899SCharles.Forsyth 		while (pb <= pc && (r = cmp(pc, a, x)) >= 0) {
82337da2899SCharles.Forsyth 			if (r == 0) { swap(pc, pd); pd--; }
82437da2899SCharles.Forsyth 			pc--;
82537da2899SCharles.Forsyth 		}
82637da2899SCharles.Forsyth 		if (pb > pc) break;
82737da2899SCharles.Forsyth 		swap(pb, pc);
82837da2899SCharles.Forsyth 		pb++;
82937da2899SCharles.Forsyth 		pc--;
83037da2899SCharles.Forsyth 	}
83137da2899SCharles.Forsyth 	pn = a + n;
83237da2899SCharles.Forsyth 	r = minimum(pa-a,  pb-pa);   vecswap(a,  pb-r, r);
83337da2899SCharles.Forsyth 	r = minimum(pd-pc, pn-pd-1); vecswap(pb, pn-r, r);
83437da2899SCharles.Forsyth 	if ((r = pb-pa) > 1) rqsort(a, r, x);
83537da2899SCharles.Forsyth 	if ((r = pd-pc) > 1) rqsort(pn-r, r, x);
83637da2899SCharles.Forsyth }
83737da2899SCharles.Forsyth 
83837da2899SCharles.Forsyth void
Math_sort(void * fp)83937da2899SCharles.Forsyth Math_sort(void*fp)
84037da2899SCharles.Forsyth {
84137da2899SCharles.Forsyth 	F_Math_sort *f;
84237da2899SCharles.Forsyth 	int	i, pilen, xlen, *p;
84337da2899SCharles.Forsyth 
84437da2899SCharles.Forsyth 	f = fp;
84537da2899SCharles.Forsyth 
84637da2899SCharles.Forsyth 	/* check that permutation contents are in [0,n-1] !!! */
84737da2899SCharles.Forsyth 	p = (int*) (f->pi->data);
84837da2899SCharles.Forsyth 	pilen = f->pi->len;
84937da2899SCharles.Forsyth 	xlen = f->x->len - 1;
85037da2899SCharles.Forsyth 
85137da2899SCharles.Forsyth 	for(i = 0; i < pilen; i++) {
85237da2899SCharles.Forsyth 		if((*p < 0) || (xlen < *p))
85337da2899SCharles.Forsyth 			error(exMathia);
85437da2899SCharles.Forsyth 		p++;
85537da2899SCharles.Forsyth 	}
85637da2899SCharles.Forsyth 
85737da2899SCharles.Forsyth 	rqsort( (int*)(f->pi->data), f->pi->len, (double*)(f->x->data));
85837da2899SCharles.Forsyth }
85937da2899SCharles.Forsyth 
86037da2899SCharles.Forsyth 
86137da2899SCharles.Forsyth /************ BLAS ***************/
86237da2899SCharles.Forsyth 
86337da2899SCharles.Forsyth void
Math_dot(void * fp)86437da2899SCharles.Forsyth Math_dot(void *fp)
86537da2899SCharles.Forsyth {
86637da2899SCharles.Forsyth 	F_Math_dot *f;
86737da2899SCharles.Forsyth 
86837da2899SCharles.Forsyth 	f = fp;
86937da2899SCharles.Forsyth 	if(f->x->len!=f->y->len)
87037da2899SCharles.Forsyth 		error(exMathia);	/* incompatible lengths */
87137da2899SCharles.Forsyth 	*f->ret = dot(f->x->len, (double*)(f->x->data), (double*)(f->y->data));
87237da2899SCharles.Forsyth }
87337da2899SCharles.Forsyth 
87437da2899SCharles.Forsyth void
Math_iamax(void * fp)87537da2899SCharles.Forsyth Math_iamax(void *fp)
87637da2899SCharles.Forsyth {
87737da2899SCharles.Forsyth 	F_Math_iamax *f;
87837da2899SCharles.Forsyth 
87937da2899SCharles.Forsyth 	f = fp;
88037da2899SCharles.Forsyth 
88137da2899SCharles.Forsyth 	*f->ret = iamax(f->x->len, (double*)(f->x->data));
88237da2899SCharles.Forsyth }
88337da2899SCharles.Forsyth 
88437da2899SCharles.Forsyth void
Math_norm2(void * fp)88537da2899SCharles.Forsyth Math_norm2(void *fp)
88637da2899SCharles.Forsyth {
88737da2899SCharles.Forsyth 	F_Math_norm2 *f;
88837da2899SCharles.Forsyth 
88937da2899SCharles.Forsyth 	f = fp;
89037da2899SCharles.Forsyth 
89137da2899SCharles.Forsyth 	*f->ret = norm2(f->x->len, (double*)(f->x->data));
89237da2899SCharles.Forsyth }
89337da2899SCharles.Forsyth 
89437da2899SCharles.Forsyth void
Math_norm1(void * fp)89537da2899SCharles.Forsyth Math_norm1(void *fp)
89637da2899SCharles.Forsyth {
89737da2899SCharles.Forsyth 	F_Math_norm1 *f;
89837da2899SCharles.Forsyth 
89937da2899SCharles.Forsyth 	f = fp;
90037da2899SCharles.Forsyth 
90137da2899SCharles.Forsyth 	*f->ret = norm1(f->x->len, (double*)(f->x->data));
90237da2899SCharles.Forsyth }
90337da2899SCharles.Forsyth 
90437da2899SCharles.Forsyth void
Math_gemm(void * fp)90537da2899SCharles.Forsyth Math_gemm(void *fp)
90637da2899SCharles.Forsyth {
90737da2899SCharles.Forsyth 	F_Math_gemm *f = fp;
90837da2899SCharles.Forsyth 	int nrowa, ncola, nrowb, ncolb, mn, ld, m, n;
90937da2899SCharles.Forsyth 	double *adata = 0, *bdata = 0, *cdata;
91037da2899SCharles.Forsyth 	int nota = f->transa=='N';
91137da2899SCharles.Forsyth 	int notb = f->transb=='N';
91237da2899SCharles.Forsyth 	if(nota){
91337da2899SCharles.Forsyth 		nrowa = f->m;
91437da2899SCharles.Forsyth 		ncola = f->k;
91537da2899SCharles.Forsyth 	}else{
91637da2899SCharles.Forsyth 		nrowa = f->k;
91737da2899SCharles.Forsyth 		ncola = f->m;
91837da2899SCharles.Forsyth 	}
91937da2899SCharles.Forsyth 	if(notb){
92037da2899SCharles.Forsyth 		nrowb = f->k;
92137da2899SCharles.Forsyth 		ncolb = f->n;
92237da2899SCharles.Forsyth 	}else{
92337da2899SCharles.Forsyth 		nrowb = f->n;
92437da2899SCharles.Forsyth 		ncolb = f->k;
92537da2899SCharles.Forsyth 	}
92637da2899SCharles.Forsyth 	if(     (!nota && f->transa!='C' && f->transa!='T') ||
92737da2899SCharles.Forsyth 		(!notb && f->transb!='C' && f->transb!='T') ||
92837da2899SCharles.Forsyth 		(f->m < 0 || f->n < 0 || f->k < 0) ){
92937da2899SCharles.Forsyth 		error(exMathia);
93037da2899SCharles.Forsyth 	}
93137da2899SCharles.Forsyth 	if(f->a != H){
93237da2899SCharles.Forsyth 		mn = f->a->len;
93337da2899SCharles.Forsyth 		adata = (double*)(f->a->data);
93437da2899SCharles.Forsyth 		ld = f->lda;
93537da2899SCharles.Forsyth 		if(ld<nrowa || ld*(ncola-1)>mn)
93637da2899SCharles.Forsyth 			error(exBounds);
93737da2899SCharles.Forsyth 	}
93837da2899SCharles.Forsyth 	if(f->b != H){
93937da2899SCharles.Forsyth 		mn = f->b->len;
94037da2899SCharles.Forsyth 		ld = f->ldb;
94137da2899SCharles.Forsyth 		bdata = (double*)(f->b->data);
94237da2899SCharles.Forsyth 		if(ld<nrowb || ld*(ncolb-1)>mn)
94337da2899SCharles.Forsyth 			error(exBounds);
94437da2899SCharles.Forsyth 	}
94537da2899SCharles.Forsyth 	m = f->m;
94637da2899SCharles.Forsyth 	n = f->n;
94737da2899SCharles.Forsyth 	mn = f->c->len;
94837da2899SCharles.Forsyth 	cdata = (double*)(f->c->data);
94937da2899SCharles.Forsyth 	ld = f->ldc;
95037da2899SCharles.Forsyth 	if(ld<m || ld*(n-1)>mn)
95137da2899SCharles.Forsyth 		error(exBounds);
95237da2899SCharles.Forsyth 
95337da2899SCharles.Forsyth 	gemm(f->transa, f->transb, f->m, f->n, f->k, f->alpha,
95437da2899SCharles.Forsyth 		adata, f->lda, bdata, f->ldb, f->beta, cdata, f->ldc);
95537da2899SCharles.Forsyth }
956