/* tour.c */ #include "stdlib.h" #include #ifdef USE_STRINGS_H #include #endif #include #include #include "vars.h" #include "externs.h" void zero_tau (vector_f tau, gint nd) { gint k; for (k=0; k tol) { ok = false; return(ok); } } for (j=0; j tol) { ok = false; return(ok); } } } return(ok); } /* checks columns of matrix are orthonormal */ gboolean checkequiv(gfloat **u0, gfloat **u1, gint nc, gint nd) { gint j; gfloat tol = 0.0001; gboolean ok = true; for (j=0; jd; gint nc = d->ncols;*/ gint j, k; for (j=0; jd; gint nc = d->ncols;*/ gint i, j, k, rank; gdouble tol = 0.0001; gdouble tmpd1 = 0.0, tmpd2 = 0.0, tmpd =0.0; gboolean doit = true; paird *pairs = (paird *) g_malloc (nd * sizeof (paird)); gfloat *e = (gfloat *) g_malloc (nd * sizeof (gfloat)); gint dI; /* dimension of intersection of base pair */ gfloat **ptinc = (gfloat **) g_malloc (2 * sizeof (gfloat *)); gfloat dv = *pdv; gint nsteps = *ns; gint stepcntr = *stcn; zero_tau(tau, nd); zero_tinc(tinc, nd); zero_lambda(lambda, nd); /* 2 is hard-wired because it relates to cos, sin and nothing else. */ for (i=0; i<2; i++) ptinc[i] = (gfloat *) g_malloc (nd * sizeof (gfloat)); /* Check that u0 and u1 are both orthonormal. */ if (!checkcolson(u0.vals, nc, nd)) { printf("Columns of u0 are not orthonormal"); doit = false; } if (!checkcolson(u1.vals, nc, nd)) { printf("Columns of u1 are not orthonormal"); doit = false; } /* Check that u0 and u1 are the same */ if (!checkequiv(u0.vals, u1.vals, nc, nd)) { doit = false; } /* Do SVD of u0'u1: span(u0,u1).*/ if (doit) { if (!matmult_utv(u0.vals, u1.vals, nc, nd, nc, nd, tv.vals)) printf("#cols != #rows in the two matrices"); dsvd(tv.vals, nd, nd, lambda.els, v1.vals); copy_mat(v0.vals, tv.vals, nd, nd); /* we want eigenvalues in order from largest to smallest, ie smallest angle to largest angle */ /* only do this if nd > 2 otherwise it is easy */ if (nd > 2) { /*-- obtain ranks to use in sorting eigenvals and eigenvec --*/ for (i=0; i lambda.els[0]) { e[0] = lambda.els[1]; lambda.els[1] = lambda.els[0]; lambda.els[0] = e[0]; for (j=0; j If dI=ndim we should stop here, and set Ft to be Fa but this is equivalent to setting the lambda's to be 1.0 at this stage.*/ dI = 0; for (i=0; i 1.0-tol) { dI++; lambda.els[i] = 1.0; } } /* Compute principal angles */ for (i=0; i dI) { copy_mat(tv.vals, v0.vals, nc, nd); if (!matmult_uv(u0.vals, tv.vals, nc, nd, nd, nd, v0.vals)) printf("Could not multiply u and v, cols!=rows \n"); copy_mat(tv.vals, v1.vals, nc, nd); if (!matmult_uv(u1.vals, tv.vals, nc, nd, nd, nd, v1.vals)) printf("Could not multiply u and v, cols!=rows \n"); /* Orthonormalize v1 on v0*/ matgram_schmidt(v0.vals, v1.vals, nc, nd); } else { copy_mat(v0.vals, u0.vals, nc, nd); copy_mat(v1.vals, u0.vals, nc, nd); for (i=0; id; gint nc = d->ncols;*/ gint i, j, k; gdouble tmpd1, tmpd2, tmpd; gfloat **ptinc = (gfloat **) g_malloc (2 * sizeof (gfloat *)); for (i=0; i<2; i++) ptinc[i] = (gfloat *) g_malloc (nd * sizeof (gfloat)); for (i=0; i tau.els[i]) { attheend = true; nsteps = stepcntr; } if (attheend || nsteps == 0 || nsteps == stepcntr) { for (i=0; icurrent_display; cpaneld *cpanel = &dsp->cpanel;*/ gfloat fracpath; gfloat step = *st; gfloat delta = *dlt; gint nsteps = *ns; gint stepcntr = *stcn; if (slidepos < 5) { step = 0.0; delta = 0.0; nsteps = 0; stepcntr = 0; } else { /* * To cause tour to speed up wildly at the right of the * scrollbar range. */ if (slidepos < 50) step = ((gfloat) slidepos - 5.) / 2000. ; else if ((slidepos >= 50) && (slidepos < 90)) step = (gfloat) pow((double)(slidepos-50)/100.,(gdouble)1.5) + 0.0225; else step = (gfloat) sqrt((double)(slidepos-50)) + 0.1868; delta = step*M_PI_2/10.0; if (nsteps > 0) fracpath = stepcntr/nsteps; else fracpath = 1.0; nsteps = (gint) floor((gdouble)(dv/delta))+1; stepcntr = (gint) floor(fracpath*nsteps); } /* printf("slidepos: %d; nsteps: %d; stepcntr: %d; delta: %f; dv: %f\n",slidepos,nsteps,stepcntr, delta,dv);*/ *st = step; *dlt = delta; *ns = nsteps; *stcn = stepcntr; } void gt_basis (array_f u1, gint nvars, vector_i vars, gint nc, gint nd) /* * Generate d random p dimensional vectors to form new ending basis */ { gint i, j, k, check = 1, nvals = nvars*nd, ntimes; gdouble frunif[2]; gdouble r, fac, frnorm[2]; gboolean oddno; if ((nvals % 2) == 1) oddno = true; else oddno=false; if (oddno) ntimes = nvals/2+1; else ntimes = nvals/2; /* * Method suggested by Press, Flannery, Teukolsky, and Vetterling (1986) * "Numerical Recipes" p.202-3, for generating random normal variates . */ /* Zero out u1 before filling; this might fix a bug we are encountering with returning from a receive tour. */ for (j=0; j nd) { for (j=0; j 1) { for (k=0; k