home *** CD-ROM | disk | FTP | other *** search
- /* linalg - Lisp interface for basic linear algebra routines */
- /* XLISP-STAT 2.1 Copyright (c) 1990, by Luke Tierney */
- /* Additions to Xlisp 2.1, Copyright (c) 1989 by David Michael Betz */
- /* You may give out copies of this software; for conditions see the */
- /* file COPYING included with this distribution. */
-
- #include <stdlib.h>
- #include "xlisp.h"
- #include "osdef.h"
- #ifdef ANSI
- #include "xlproto.h"
- #include "xlsproto.h"
- #else
- #include "xlfun.h"
- #include "xlsfun.h"
- #endif ANSI
- #include "xlsvar.h"
-
- #ifdef ANSI
- LVAL vector_to_data(Vector,int,int,int),matrix_to_data(Matrix,int,int,int),
- kernel(int),
- add_contour_point(int,int,int,int,RVector,RVector,RMatrix,double,LVAL);
- char *allocate(unsigned,unsigned);
- void free_alloc(void *),baddata(LVAL),badmatrix(LVAL),badsquarematrix(LVAL),
- badsequence(LVAL),
- get_smoother_data(Vector *,Vector *,int *,Vector *,Vector *,int *,int);
- int data_mode(LVAL);
- Vector data_to_vector(LVAL,int);
- Matrix data_to_matrix(LVAL,int);
- #else
- LVAL vector_to_data(),matrix_to_data(),
- kernel(),
- add_contour_point();
- char *allocate();
- void free_alloc(),baddata(),badmatrix(),badsquarematrix(),
- badsequence(),
- get_smoother_data();
- int data_mode();
- Vector data_to_vector();
- Matrix data_to_matrix();
- #endif ANSI
-
- /************************************************************************/
- /** **/
- /** Storage Allocation Functions **/
- /** **/
- /************************************************************************/
-
- static char *allocate(n, m)
- unsigned n, m;
- {
- char *p = calloc(n, m);
- if (p == nil) xlfail("allocation failed");
- return(p);
- }
-
- static void free_alloc(p)
- /* char*/ void *p;/* changed JKL */
- {
- if (p != nil) free(p);
- }
-
- IVector ivector(n)
- unsigned n;
- {
- return((IVector) allocate(n, sizeof(int)));
- }
-
- RVector rvector(n)
- unsigned n;
- {
- return((RVector) allocate(n, sizeof(double)));
- }
-
- CVector cvector(n)
- unsigned n;
- {
- return((CVector) allocate(n, sizeof(Complex)));
- }
-
- void free_vector(v) Vector v; { free_alloc(v); }
-
- IMatrix imatrix(n, m)
- unsigned n, m;
- {
- int i;
- IMatrix mat = (IMatrix) allocate(n, sizeof(IVector));
- for (i = 0; i < n; i++) mat[i] = (IVector) allocate(m, sizeof(int));
- return(mat);
- }
-
- RMatrix rmatrix(n, m)
- unsigned n, m;
- {
- int i;
- RMatrix mat = (RMatrix) allocate(n, sizeof(RVector));
- for (i = 0; i < n; i++) mat[i] = (RVector) allocate(m, sizeof(double));
- return(mat);
- }
-
- CMatrix cmatrix(n, m)
- unsigned n, m;
- {
- int i;
- CMatrix mat = (CMatrix) allocate(n, sizeof(CVector));
- for (i = 0; i < n; i++) mat[i] = (CVector) allocate(m, sizeof(Complex));
- return(mat);
- }
-
- void free_matrix(mat, n)
- Matrix mat;
- int n;
- {
- int i;
-
- if (mat != nil) for (i = 0; i < n; i++) free_alloc(mat[i]);
- free_alloc(mat);
- }
-
- /************************************************************************/
- /** **/
- /** Lisp to/from C Data Translation Functions **/
- /** **/
- /************************************************************************/
-
- static void baddata(data)
- LVAL data;
- {
- xlerror("bad linear algebra data", data);
- }
-
- static void badmatrix(data)
- LVAL data;
- {
- xlerror("not a matrix", data);
- }
-
- static void badsquarematrix(data)
- LVAL data;
- {
- xlerror("not a square matrix", data);
- }
-
- static void badsequence(data)
- LVAL data;
- {
- xlerror("not a sequence", data);
- }
-
- static int data_mode(data)
- LVAL data;
- {
- LVAL item;
- int i, n;
- int mode = IN;
-
- if (! consp(data) && ! vectorp(data) && ! displacedarrayp(data))
- baddata(data);
-
- if (! consp(data)) data = arraydata(data);
- n = seqlen(data);
- for (i = 0; i < n; i++) {
- item = getnextelement(&data, i);
- if (! realp(item) && ! complexp(item)) baddata(item);
- if (floatp(item) && mode == IN) mode = RE;
- else if (complexp(item)) mode = CX;
- }
- return(mode);
- }
-
- static Vector data_to_vector(data, mode)
- LVAL data;
- int mode;
- {
- LVAL item;
- int i, n;
- Vector v;
- IVector iv;
- RVector rv;
- CVector cv;
-
- if (! sequencep(data)) baddata(data);
- n = seqlen(data);
-
- switch (mode) {
- case IN: iv = ivector(n); v = (Vector) iv; break;
- case RE: rv = rvector(n); v = (Vector) rv; break;
- case CX: cv = cvector(n); v = (Vector) cv; break;
- }
-
- for (i = 0; i < n; i++) {
- item = getnextelement(&data, i);
- switch (mode) {
- case IN: iv[i] = getfixnum(item); break;
- case RE: rv[i] = makedouble(item); break;
- case CX: cv[i] = makecomplex(item); break;
- }
- }
- return(v);
- }
-
- static Matrix data_to_matrix(data, mode)
- LVAL data;
- int mode;
- {
- LVAL item;
- int i, j, n, m;
- Matrix mat;
- IMatrix imat;
- RMatrix rmat;
- CMatrix cmat;
-
- if (! matrixp(data)) baddata(data);
- n = numrows(data); m = numcols(data);
-
- switch (mode) {
- case IN: imat = imatrix(n, m); mat = (Matrix) imat; break;
- case RE: rmat = rmatrix(n, m); mat = (Matrix) rmat; break;
- case CX: cmat = cmatrix(n, m); mat = (Matrix) cmat; break;
- }
-
- data = arraydata(data);
- for (i = 0; i < n; i++) {
- for (j = 0; j < m; j++) {
- item = getelement(data, i * m + j);
- switch (mode) {
- case IN: imat[i][j] = getfixnum(item); break;
- case RE: rmat[i][j] = makedouble(item); break;
- case CX: cmat[i][j] = makecomplex(item); break;
- }
- }
- }
- return(mat);
- }
-
- static LVAL vector_to_data(v, n, mode, as_list)
- Vector v;
- int n, mode, as_list;
- {
- LVAL data;
- int i;
- IVector iv = (IVector) v;
- RVector rv = (RVector) v;
- CVector cv = (CVector) v;
-
- xlsave1(data);
- data = newvector(n);
- for (i = 0; i < n; i++) {
- switch (mode) {
- case IN: setelement(data, i, cvfixnum((FIXTYPE) iv[i])); break;
- case RE: setelement(data, i, cvflonum((FLOTYPE) rv[i])); break;
- case CX: setelement(data, i, cvcomplex(cv[i])); break;
- }
- }
- if (as_list) data = coerce_to_list(data);
- xlpop();
- return(data);
- }
-
- static LVAL matrix_to_data(mat, n, m, mode)
- Matrix mat;
- int n, m, mode;
- {
- LVAL data, dim, data_matrix;
- int i, j;
- IMatrix imat = (IMatrix) mat;
- RMatrix rmat = (RMatrix) mat;
- CMatrix cmat = (CMatrix) mat;
-
- xlstkcheck(2);
- xlsave(dim);
- xlsave(data_matrix);
-
- dim = integer_list_2(n, m);
- data_matrix = newarray(dim, NIL, NIL);
- data = arraydata(data_matrix);
- for (i = 0; i < n; i++) {
- for (j = 0; j < m; j++) {
- switch (mode) {
- case IN: setelement(data, i * m + j, cvfixnum((FIXTYPE) imat[i][j])); break;
- case RE: setelement(data, i * m + j, cvflonum((FLOTYPE) rmat[i][j])); break;
- case CX: setelement(data, i * m + j, cvcomplex(cmat[i][j])); break;
- }
- }
- }
- xlpopn(2);
- return(data_matrix);
- }
-
- /************************************************************************/
- /** **/
- /** Machine Epsilon Determination **/
- /** **/
- /************************************************************************/
-
- double macheps()
- {
- static int calculated = FALSE;
- static double epsilon = 1.0;
-
- if (! calculated)
- while (1.0 + epsilon / 2.0 != 1.0) epsilon = epsilon / 2.0;
- calculated = TRUE;
- return(epsilon);
- }
-
- /************************************************************************/
- /** **/
- /** Lisp Interfaces to Linear Algebra Routines **/
- /** **/
- /************************************************************************/
-
- LVAL xslu_decomp()
- {
- LVAL data, result, temp;
- Matrix mat;
- IVector iv;
- double d;
- int n, m, mode, singular;
-
- data = xlgetarg();
- xllastarg();
-
- if (! matrixp(data)) badmatrix(data);
- n = numrows(data);
- m = numcols(data);
- if (n != m || n <= 0 || m <= 0) badsquarematrix(data);
-
- xlsave1(result);
- result = mklist(4, NIL); /* redundant assignment to nil in macro JKL */
- temp = result;
-
- mode = data_mode(data);
- if (mode == IN) mode = RE;
- mat = data_to_matrix(data, mode);
- iv = ivector(n);
- singular = crludcmp(mat, n, iv, mode, &d);
- rplaca(temp, matrix_to_data(mat, n, n, mode)); temp = cdr(temp);
- rplaca(temp, vector_to_data((Vector)iv, n, IN, FALSE)); temp = cdr(temp);
- rplaca(temp, cvflonum((FLOTYPE) d)); temp = cdr(temp);
- rplaca(temp, (singular) ? s_true : NIL);
-
- free_matrix(mat, n);
- free_vector((Vector)iv); /* casts added JKL */
- xlpop();
- return(result);
- }
-
- LVAL xslu_solve()
- {
- LVAL ludecomp, la, lindx, lb, result;
- Matrix a;
- Vector b, indx;
- int n, m, a_mode, b_mode, mode, singular;
-
- ludecomp = xlgalist();
- lb = xlgetarg();
- xllastarg();
-
- la = (consp(ludecomp)) ? car(ludecomp) : NIL;
- lindx = (consp(cdr(ludecomp))) ? car(cdr(ludecomp)) : NIL;
- if (! matrixp(la)) badmatrix(la);
- n = numrows(la);
- m = numcols(la);
-
- if (n != m || n <= 0 || m <= 0) badsquarematrix(la);
-
- if (! sequencep(lindx)) badsequence(lindx);
- if (data_mode(lindx) != IN) xlerror("not an integer sequence", lindx);
- if (! sequencep(lb)) badsequence(lb);
- if (seqlen(lb) != n) xlerror("bad sequence length", lb);
-
- a_mode = data_mode(la);
- b_mode = data_mode(lb);
- mode = max(a_mode, b_mode);
- if (mode == IN) mode = RE;
-
- a = data_to_matrix(la, mode);
- indx = data_to_vector(lindx, IN);
- b = data_to_vector(lb, mode);
-
- singular = crlubksb(a, n, (IVector)indx, b, mode);/* cast added JKL */
- result = vector_to_data(b, n, mode, listp(lb));
- free_matrix(a, n);
- free_vector(indx);
- free_vector(b);
-
- if (singular) xlfail("matrix is (numerically) singular");
- return(result);
- }
-
- LVAL xslu_determinant()
- {
- LVAL data, result;
- Matrix mat;
- CMatrix cmat;
- RMatrix rmat;
- IVector iv;
- double d, rd1, d2, magn;
- Complex cd1;
- int m, n, i, mode;
-
- data = xlgetarg();
- xllastarg();
-
- if (! matrixp(data)) badmatrix(data);
- m = numrows(data);
- n = numcols(data);
- if (n != m || n <= 0 || m <= 0) badsquarematrix(data);
-
- mode = data_mode(data);
- if (mode == IN) mode = RE;
- mat = data_to_matrix(data, mode);
- iv = ivector(n);
- crludcmp(mat, n, iv, mode, &d);
-
- switch (mode) {
- case RE:
- rmat = (RMatrix) mat;
- rd1 = d;
- d2 = 0.0;
- for (i = 0; i < n; i++) {
- if ((magn = fabs(rmat[i][i])) == 0.0) {
- rd1 = 0.0;
- break;
- }
- rd1 *= rmat[i][i] / magn;
- d2 += log(magn);
- }
- result = cvflonum((FLOTYPE) rd1 * exp(d2));
- break;
- case CX:
- cmat = (CMatrix) mat;
- cd1 = cart2complex(d, 0.0);
- d2 = 0.0;
- for (i = 0; i < n; i++) {
- if ((magn = modulus(cmat[i][i])) == 0.0) {
- cd1 = cart2complex(0.0, 0.0);
- break;
- }
- cd1 = polar2complex(modulus(cd1), phase(cd1) + phase(cmat[i][i]));
- d2 += log(magn);
- }
- result = cvcomplex(cmul(cd1, cart2complex(exp(d2), 0.0)));
- break;
- }
-
- free_matrix(mat, n);
- free_vector((Vector)iv);/* cast added JKL */
- return(result);
- }
-
- LVAL xslu_inverse()
- {
- LVAL data, result;
- Matrix mat, inv;
- CMatrix cinv;
- RMatrix rinv;
- CVector cv;
- RVector rv;
- Vector v;
- IVector iv;
- double d;
- int m, n, i, j, mode, singular;
-
- data = xlgetarg();
- xllastarg();
-
- if (! matrixp(data)) badmatrix(data);
- m = numrows(data);
- n = numcols(data);
- if (n != m || n <= 0 || m <= 0) badsquarematrix(data);
-
- mode = data_mode(data);
- if (mode == IN) mode = RE;
- mat = data_to_matrix(data, mode);
- iv = ivector(n);
- inv = (mode == RE) ? (Matrix) rmatrix(n,n) : (Matrix) cmatrix(n,n);
- rinv = (RMatrix) inv;
- cinv = (CMatrix) inv;
- v = (mode == RE) ? (Vector) rvector(n) : (Vector) cvector(n);
- rv = (RVector) v;
- cv = (CVector) v;
-
- singular = crludcmp(mat, n, iv, mode, &d);
-
- if (! singular) {
- for (j = 0; j < n; j++) {
- for (i = 0; i < n; i++) {
- if (mode == RE) rv[i] = 0.0;
- else cv[i] = cart2complex(0.0, 0.0);
- }
- if (mode == RE) rv[j] = 1.0;
- else cv[j] = cart2complex(1.0, 0.0);
-
- singular = singular || crlubksb(mat, n, iv, v, mode);
-
- for (i = 0; i < n; i++) {
- if (mode == RE) rinv[i][j] = rv[i];
- else cinv[i][j] = cv[i];
- }
- }
- result = matrix_to_data(inv, n, n, mode);
- }
-
- free_matrix(mat, n);
- free_matrix(inv, n);
- free_vector((Vector)iv);/* cast added JKL */
- free_vector(v);
- if (singular) xlfail("matrix is (numerically) singular");
- return(result);
- }
-
- LVAL xssv_decomp()
- {
- LVAL data, result, temp;
- Matrix mat, v;
- Vector w;
- int n, m, mode, converged;
-
- data = xlgetarg();
- xllastarg();
-
- if (! matrixp(data)) badmatrix(data);
- m = numrows(data);
- n = numcols(data);
- if (n <= 0 || m <= 0) baddata(data);
- if (m < n) xlfail("number of rows less than number of columns");
-
- xlsave1(result);
- result = mklist(4, NIL);
- temp = result;
-
- mode = data_mode(data);
- if (mode == IN) mode = RE;
- if (mode == CX) xlfail("complex SVD not available yet");
-
- mat = data_to_matrix(data, mode);
- w = (Vector) rvector(n);
- v = (Matrix) rmatrix(n, n);
- /* casts added JKL */
- converged = svdcmp((RMatrix)mat, m, n, (RVector)w, (RMatrix)v);
- rplaca(temp, matrix_to_data(mat, m, n, mode)); temp = cdr(temp);
- rplaca(temp, vector_to_data(w, n, mode, FALSE)); temp = cdr(temp);
- rplaca(temp, matrix_to_data(v, n, n, mode)); temp = cdr(temp);
- rplaca(temp, (converged) ? s_true : NIL);
-
- free_matrix(mat, m);
- free_matrix(v, n);
- free_vector(w);
- xlpop();
- return(result);
- }
-
- LVAL xsqr_decomp()
- {
- LVAL data, result, temp;
- Matrix mat, v;
- Vector jpvt;
- int n, m, mode, pivot;
-
- data = xlgetarg();
- pivot = (moreargs()) ? (xlgetarg() != NIL) : FALSE;
- xllastarg();
-
- if (! matrixp(data)) badmatrix(data);
- m = numrows(data);
- n = numcols(data);
- if (n <= 0 || m <= 0) baddata(data);
- if (m < n) xlfail("number of rows less than number of columns");
-
- xlsave1(result);
- result = mklist((pivot) ? 3 : 2, NIL);
- temp = result;
-
- mode = data_mode(data);
- if (mode == IN) mode = RE;
- if (mode == CX) xlfail("complex QR decomposition not available yet");
-
- mat = data_to_matrix(data, mode);
- v = (Matrix) rmatrix(n, n);
- jpvt = (Vector) ivector(n);
- /* casts added JKL */
- qrdecomp((RMatrix)mat, m, n, (RMatrix)v, (IVector)jpvt, pivot);
- rplaca(temp, matrix_to_data(mat, m, n, mode)); temp = cdr(temp);
- rplaca(temp, matrix_to_data(v, n, n, mode)); temp = cdr(temp);
- if (pivot) rplaca(temp, vector_to_data((Vector)jpvt, n, IN, TRUE));
-
- free_matrix((Matrix)mat, m);/* casts added JKL */
- free_matrix((Matrix)v, n);
- free_vector((Vector)jpvt);
-
- xlpop();
- return(result);
- }
-
- LVAL xschol_decomp()
- {
- LVAL data, result;
- Matrix mat;
- int n, m, mode;
- double maxadd, maxoffl;
-
- data = xlgetarg();
- if (moreargs()) maxoffl = makedouble(xlgetarg());
- else maxoffl = 0.0;
- xllastarg();
-
- if (! matrixp(data)) badmatrix(data);
- m = numrows(data);
- n = numcols(data);
- if (n != m || n <= 0 || m <= 0) badsquarematrix(data);
-
- mode = data_mode(data);
- if (mode == IN) mode = RE;
- if (mode == CX) xlfail("complex Cholesky not available yet");
-
- mat = data_to_matrix(data, mode);
-
- choldecomp((RMatrix)mat, n, maxoffl, &maxadd);/* cast added JKL */
- result = mklist(2, NIL);
- rplaca(result, matrix_to_data(mat, n, n, mode));
- rplaca(cdr(result), cvflonum((FLOTYPE) maxadd));
-
- free_matrix(mat, m);
- return(result);
- }
-
- LVAL xsrcondest()
- {
- LVAL data, result;
- Matrix mat;
- int n, m, mode;
- double est;
-
- data = xlgetarg();
- xllastarg();
-
- if (! matrixp(data)) badmatrix(data);
- m = numrows(data);
- n = numcols(data);
- if (n != m || n <= 0 || m <= 0) badsquarematrix(data);
-
- mode = data_mode(data);
- if (mode == IN) mode = RE;
- if (mode == CX) xlfail("complex condition estimate not available yet");
-
- mat = data_to_matrix(data, mode);
-
- est = rcondest((RMatrix)mat, n);/* cast added JKL */
- result = cvflonum((FLOTYPE) est);
-
- free_matrix(mat, m);
- return(result);
- }
-
- LVAL xsmake_rotation()
- {
- LVAL s1, s2, result;
- Vector x, y;
- Matrix rot;
- double alpha;
- int n, use_alpha = FALSE;
-
- s1 = xsgetsequence();
- s2 = xsgetsequence();
- if (moreargs()) {
- use_alpha = TRUE;
- alpha = makedouble(xlgetarg());
- }
- xllastarg();
-
- n = seqlen(s1);
- if (seqlen(s2) != n) xlfail("sequences not the same length");
-
- if (data_mode(s1) == CX || data_mode(s2) == CX)
- xlfail("complex data not supported yet");
-
- x = data_to_vector(s1, RE);
- y = data_to_vector(s2, RE);
-
- rot = (Matrix) rmatrix(n,n);/* casts added JKL */
- make_rotation(n, (RMatrix)rot, (RVector)x, (RVector)y, use_alpha, alpha);
- result = matrix_to_data(rot, n, n, RE);
-
- free_vector(x);
- free_vector(y);
- free_matrix(rot, n);
- return(result);
- }
-
- #define NS_DEFAULT 30
-
- static void get_smoother_data(px, py, pn, pxs, pys, pns, is_reg)
- Vector *px, *py, *pxs, *pys;
- int *pn, *pns, is_reg;
- {
- LVAL s1, s2, arg, sk_xvals = xlenter(":XVALS");
- int n, ns, i, supplied;
- double xmin, xmax, *x, *xs;
-
- s1 = xsgetsequence();
- if (is_reg) s2 = xsgetsequence();
-
- if (xlgetkeyarg(sk_xvals, &arg)) {
- if (! sequencep(arg) && ! fixp(arg)) xlbadtype(arg);
- }
- else arg = NIL;
-
- ns = (fixp(arg)) ? getfixnum(arg) : seqlen(arg);
- if (ns < 2) ns = NS_DEFAULT;
- supplied = (sequencep(arg) && arg != NIL) ? TRUE : FALSE;
-
- n = seqlen(s1);
- if (n <= 0) xlfail("sequence too short");
- if (is_reg && seqlen(s2) != n) xlfail("sequences not the same length");
- if (supplied && data_mode(arg) == CX) xlfail("data must be real");
- if (data_mode(s1) == CX || (is_reg && data_mode(s2) == CX))
- xlfail("data must be real");
-
- *px = data_to_vector(s1, RE);
- *py = (is_reg) ? data_to_vector(s2, RE) : nil;
- *pxs = (supplied) ? data_to_vector(arg, RE) : (Vector) rvector(ns);
- *pys = (Vector) rvector(ns);
- *pn = n;
- *pns = ns;
-
- if (! supplied) {
- x = (double *) *px;
- xs = (double *) *pxs;
- for (xmax = xmin = x[0], i = 1; i < *pn; i++) {
- if (x[i] > xmax) xmax = x[i];
- if (x[i] < xmin) xmin = x[i];
- }
- for (i = 0; i < *pns; i++)
- xs[i] = xmin + (xmax - xmin) * ((double) i) / ((double) (*pns - 1));
- }
- }
-
- LVAL xsspline()
- {
- LVAL result;
- Vector x, y, work, xs, ys;
- int n, ns, error;
-
- get_smoother_data(&x, &y, &n, &xs, &ys, &ns, TRUE);
-
- work = (Vector) rvector(2 * n);
- /* casts added JKL */
- error = fit_spline(n, (RVector)x, (RVector)y, ns, (RVector)xs,
- (RVector)ys, (RVector)work);
- xlsave1(result);
- result = mklist(2, NIL);
- rplaca(result, vector_to_data(xs, ns, RE, TRUE));
- rplaca(cdr(result), vector_to_data(ys, ns, RE, TRUE));
- xlpop();
-
- free_vector(x);
- free_vector(y);
- free_vector(xs);
- free_vector(ys);
- free_vector(work);
-
- if (error) xlfail("bad data for splines");
- return(result);
- }
-
- static LVAL kernel(is_reg)
- int is_reg;
- {
- LVAL warg, targ, result;
- Vector x, y, xs, ys/*, wts, wds*/;
- int n, ns, error, ktype;
- double width;
-
- get_smoother_data(&x, &y, &n, &xs, &ys, &ns, is_reg);
- if (! xlgetkeyarg(sk_width, &warg)) warg = NIL;
- if (! xlgetkeyarg(sk_type, &targ)) targ = NIL;
-
- width = (fixp(warg) || floatp(warg)) ? makedouble(warg) : -1.0;
- /*wts = (Vector) nil;
- wds = (Vector) nil; not used JKL */
- if (targ == xlenter("U")) ktype = 'U';
- else if (targ == xlenter("T")) ktype = 'T';
- else if (targ == xlenter("G")) ktype = 'G';
- else ktype = 'B';
- /* casts added JKL */
- error = kernel_smooth((RVector)x, (RVector)y, n, width, nil, nil,
- (RVector)xs, (RVector)ys, ns, ktype);
- xlsave1(result); /* redundant equation of result to NIL in macro JKL */
- result = mklist(2, NIL);
- rplaca(result, vector_to_data(xs, ns, RE, TRUE));
- rplaca(cdr(result), vector_to_data(ys, ns, RE, TRUE));
- xlpop();
-
- free_vector(x);
- free_vector(y);
- free_vector(xs);
- free_vector(ys);
-
- if (error) xlfail("bad data for splines");
- return(result);
- }
-
- LVAL xskernel_smooth() { return(kernel(TRUE)); }
- LVAL xskernel_dens() { return(kernel(FALSE)); }
-
- LVAL xsbase_lowess()
- {
- LVAL s1, s2, result;
- int n, nsteps, error;
- double f, delta;
- Vector x, y, ys, rw, res;
-
- s1 = xsgetsequence();
- s2 = xsgetsequence();
- f = makedouble(xlgetarg());
- nsteps = getfixnum(xlgafixnum());
- delta = makedouble(xlgetarg());
- xllastarg();
-
- n = seqlen(s1);
- if (n <= 0) xlfail("sequence too short");
- if (seqlen(s2) != n) xlfail("sequences not the same length");
- if (data_mode(s1) == CX || data_mode(s2) == CX) xlfail("data must be real");
- x = data_to_vector(s1, RE);
- y = data_to_vector(s2, RE);
- ys = (Vector) rvector(n);
- rw = (Vector) rvector(n);
- res = (Vector) rvector(n);
- /* casts added JKL */
- error = lowess((RVector)x, (RVector)y, n, f, nsteps, delta, (RVector)ys,
- (RVector)rw, (RVector)res);
- result = vector_to_data(ys, n, RE, TRUE);
-
- free_vector(x);
- free_vector(y);
- free_vector(ys);
- free_vector(rw);
- free_vector(res);
-
- if (error) xlfail("bad data for splines");
- return(result);
- }
-
- static LVAL add_contour_point(i, j, k, l, x, y, z, v, result)
- int i, j, k, l;
- RVector x, y;
- RMatrix z;
- double v;
- LVAL result;
- {
- LVAL pt;
- double p, q;
-
- if ((z[i][j] <= v && v < z[k][l]) || (z[k][l] <= v && v < z[i][j])) {
- xlsave(pt);
- pt = mklist(2, NIL);
- p = (v - z[i][j]) / (z[k][l] - z[i][j]);
- q = 1.0 - p;
- rplaca(pt, cvflonum((FLOTYPE) (q * x[i] + p * x[k])));
- rplaca(cdr(pt), cvflonum((FLOTYPE) (q * y[j] + p * y[l])));
- result = cons(pt, result);
- xlpop();
- }
- return(result);
- }
-
- LVAL xssurface_contour()
- {
- LVAL s1, s2, mat, result;
- RVector x, y;
- RMatrix z;
- double v;
- int i, j, n, m;
-
- s1 = xsgetsequence();
- s2 = xsgetsequence();
- mat = xsgetmatrix();
- v = makedouble(xlgetarg());
- xllastarg();
-
- n = seqlen(s1); m = seqlen(s2);
- if (n != numrows(mat) || m != numcols(mat)) xlfail("dimensions do not match");
- if (data_mode(s1) == CX || data_mode(s2) == CX || data_mode(mat) == CX)
- xlfail("data must be real");
-
- x = (RVector) data_to_vector(s1, RE);
- y = (RVector) data_to_vector(s2, RE);
- z = (RMatrix) data_to_matrix(mat, RE);
-
- xlsave1(result);
- result = NIL;
- for (i = 0; i < n - 1; i++) {
- for (j = 0; j < m - 1; j++) {
- result = add_contour_point(i, j, i, j+1, x, y, z, v, result);
- result = add_contour_point(i, j+1, i+1, j+1, x, y, z, v, result);
- result = add_contour_point(i+1, j+1, i+1, j, x, y, z, v, result);
- result = add_contour_point(i+1, j, i, j, x, y, z, v, result);
- }
- }
- xlpop();
-
- free_vector((Vector)x);/* casts added JKL */
- free_vector((Vector)y);
- free_matrix((Matrix)z, n);
-
- return(result);
- }
-
- LVAL xsfft()
- {
- LVAL data, result;
- CVector x;
- RVector work;
- int n, isign, as_list;
-
- data = xsgetsequence();
- isign = (moreargs() && xlgetarg() != NIL) ? -1.0 : 1.0;
- xllastarg();
-
- /* check and convert the data */
- n = seqlen(data);
- if (n <= 0) xlfail("not enough data");
- data_mode(data); /* checks that data are numbers */
- as_list = (listp(data)) ? TRUE : FALSE;
- x = (CVector) data_to_vector(data, CX);
- work = rvector(4 * n + 15);
-
- cfft(n, (double *)x, (double *)work, isign); /* casts added JKL */
-
- /* free internal data and return result */
- result = vector_to_data((Vector)x, n, CX, as_list);/* casts added JKL */
- free_vector((Vector)x);
- free_vector((Vector)work);
-
- return(result);
- }
-