示例#1
0
文件: phitest.c 项目: cran/phitest
long double zbrent(long double (func)(long double, long double, long double, 
      long double, int), long double par1, long double par2, long double es, 
      int n,long double x1, long double x2, long double tol)
{
  int iter;
  long double a=x1,b=x2,c=x2,d,e,min1,min2;
  long double fa=(func)(a,par1,par2,es,n);
  long double fb=(func)(b,par1,par2,es,n),fc,p,q,r,s,tol1,xm;

  if ((fa > 0.0 && fb > 0.0) || (fa < 0.0 && fb < 0.0)){
    return -1.0;
  }
  fc=fb;
  for (iter=1;iter<=ITMAX;iter++) {
    if ((fb > 0.0 && fc > 0.0) || (fb < 0.0 && fc < 0.0)) {
      c=a;                           
      fc=fa;                       
      e=d=b-a;
    }
    if (fabsl(fc) < fabsl(fb)) {
      a=b;
      b=c;
      c=a;
      fa=fb;
      fb=fc;
      fc=fa;
    }
    tol1=2.0*EPS*fabsl(b)+0.5*tol;     
    xm=0.5*(c-b);

    if (fabsl(xm) <= tol1 || fb == 0.0) { 
      return b;
    }
    if (fabsl(e) >= tol1 && fabsl(fa) > fabsl(fb)) {
      s=fb/fa;                 
      if (a == c) {
	p=2.0*xm*s;
	q=1.0-s;
      } else {
	q=fa/fc;
	r=fb/fc;
	p=s*(2.0*xm*q*(q-r)-(b-a)*(r-1.0));
	q=(q-1.0)*(r-1.0)*(s-1.0);
      }
      if (p > 0.0) q = -q;      
      p=fabsl(p);
      min1=3.0*xm*q-fabsl(tol1*q);
      min2=fabsl(e*q);

      if (2.0*p < (min1 < min2 ? min1 : min2)) {
	e=d;                      
	d=p/q;
      } else {
	d=xm;                     
	e=d;
      }
    }
    else {
      d=xm;                 
      e=d;
    }
    a=b;                   
    fa=fb;
    if (fabsl(d) > tol1)      
      b += d;
    else 
      b += SIGN(tol1,xm);
    fb=(*func)(b,par1,par2,es,n);
  }
  nrerror("Maximum number of iterations exceeded in zbrent");										    
  return 0.0;            
}
示例#2
0
TSIL_REAL BrentMin (TSIL_REAL ax,
		    TSIL_REAL bx,
		    TSIL_REAL cx,
		    TSIL_REAL (*f)(TSIL_REAL),
		    TSIL_REAL tol,
		    TSIL_REAL *xmin)
{
  int iter;
  TSIL_REAL a,b,d,etemp,fu,fv,fw,fx,p,q,r,tol1,tol2,u,v,w,x,xm;
  TSIL_REAL e = 0.0;

  a = (ax < cx ? ax : cx);
  b = (ax > cx ? ax : cx);

  x = w = v = bx;
  fw = fv = fx = (*f)(x);
  for (iter=1; iter<=ITMAX; iter++) {
    xm = 0.5L*(a + b);
    tol2 = 2.0L*(tol1 = tol*TSIL_FABS(x) + ZEPS);
    if (TSIL_FABS(x - xm) <= (tol2 - 0.5*(b-a))) {
      *xmin = x;
/*       printf("Brent: %d evaluations\n", iter); */
      return fx;
    }
    if (TSIL_FABS(e) > tol1) {
      r = (x - w)*(fx - fv);
      q = (x - v)*(fx - fw);
      p = (x - v)*q - (x - w)*r;
      q = 2.0L*(q - r);
      if (q > 0.0) p = -p;
      q = TSIL_FABS(q);
      etemp = e;
      e = d;
      if (TSIL_FABS(p) >= TSIL_FABS(0.5L*q*etemp) ||
	  p <= q*(a - x) ||
	  p >= q*(b - x))
	d = CGOLD*(e = (x >= xm ? a-x : b-x));
      else {
	d = p/q;
	u = x + d;
	if (u-a < tol2 || b-u < tol2)
	  d = SIGN(tol1, xm-x);
      }
    }
    else {
      d = CGOLD*(e = (x >= xm ? a-x: b-x));
    }
    u = (TSIL_FABS(d) >= tol1 ? x+d : x + SIGN(tol1,d));
    fu = (*f)(u);
    if (fu <= fx) {
      if (u >= x) a = x; else b = x;
      SHFT(v,w,x,u) ;
      SHFT(fv,fw,fx,fu) ;
    }
    else {
      if (u < x) a = u; else b = u;
      if (fu <= fw || w == x) {
	v = w;
	w = u;
	fv = fw;
	fw = fu;
      }
      else if (fu <= fv || v == x || v == w) {
	v = u;
	fv = fu;
      }
    }
  }
  TSIL_Error ("Brent", "Too many iterations", 42);
  *xmin = x;
  return fx;
}
示例#3
0
double zbrent_err(double (*func)(double x, void *para, size_t N), double x1, double x2, double tol, void *para, size_t N)
//	Using Brent’s method, find the root of a function func known to lie between x1 and x2. The root, returned as zbrent, will be refined until its accuracy is tol.
{
	//struct my_params *fp=(struct my_params *)para;
	//printf ("zbrent_err: %lf %lf\n", fp->a, fp->b);
	int iter;
	double a=x1,b=x2,c=x2,d,e,min1,min2;
	double fa=(*func)(a, para, N),fb=(*func)(b, para, N),fc,p,q,r,s,tol1,xm;

	if ((fa > 0.0 && fb > 0.0) || (fa < 0.0 && fb < 0.0))
		puts ("Root must be bracketed in zbrent\n");

	fc=fb;
	for (iter=1;iter<=ITMAX;iter++) 
	{
		if ((fb > 0.0 && fc > 0.0) || (fb < 0.0 && fc < 0.0)) 
		{
			c=a;   // Rename a, b, c and adjust bounding interval d.
			fc=fa;
			e=d=b-a;
		}
		if (fabs(fc) < fabs(fb)) 
		{
			a=b;
			b=c;
			c=a;
			fa=fb;
			fb=fc;
			fc=fa;
		}

		tol1=2.0*EPS*fabs(b)+0.5*tol;   // Convergence check.
		xm=0.5*(c-b);

		if (fabs(xm) <= tol1 || fb == 0.0) return b;
		if (fabs(e) >= tol1 && fabs(fa) > fabs(fb)) 
		{
			s=fb/fa;  // Attempt inverse quadratic interpolation.

			if (a == c) 
			{
				p=2.0*xm*s;
				q=1.0-s;
			} 
			else 
			{
				q=fa/fc;
				r=fb/fc;
				p=s*(2.0*xm*q*(q-r)-(b-a)*(r-1.0));
				q=(q-1.0)*(r-1.0)*(s-1.0);
			}
			if (p > 0.0) q = -q;  // Check whether in bounds.

			p=fabs(p);
			min1=3.0*xm*q-fabs(tol1*q);
			min2=fabs(e*q);

			if (2.0*p < (min1 < min2 ? min1 : min2)) 
			{
				e=d;  // Accept interpolation.
				d=p/q;
			} 
			else 
			{
				d=xm; // Interpolation failed, use bisection.
				e=d;
			}
		} 
		else  // Bounds decreasing too slowly, use bisection.
		{
			d=xm;
			e=d;
		}
		a=b;  //  Move last best guess to a.
		fa=fb;
		if (fabs(d) > tol1)     //  Evaluate new trial root.
			b += d;
		else
			b += SIGN(tol1,xm);

		fb=(*func)(b, para, N);
	}

	puts ("Maximum number of iterations exceeded in zbrent\n");

	return 0.0;
}
示例#4
0
int main(int argc, char *argv[])
{
	unsigned long p = 0xAA0000AA;
	unsigned long q = 0x00550055;
	unsigned long r = 0x00570057;

	char buf[0x1000];
	char *pre1, *pre2, *pre3, *res;
	int pos, cpos, cmp, ccmp;

	cp_bit_sequence *a = cp_bit_sequence_create(7, (unsigned char *) &p);
	cp_bit_sequence *b = cp_bit_sequence_create(23, (unsigned char *) &q);
	cp_bit_sequence *c = cp_bit_sequence_create(23, (unsigned char *) &r);

	pre1 = cp_bit_sequence_to_string(a);
	pre2 = cp_bit_sequence_to_string(b);
	pre3 = cp_bit_sequence_to_string(c);
	
	printf("comparing sequences b [%s] and c [%s]\n", pre2, pre3);
	for (pos = 0; pos < c->length; pos++)
		if (pre2[pos] != pre3[pos]) break;
	cmp = pre2[pos] - pre3[pos];
	printf("expected: b %c c, difference at bit %d\n", cmp > 0 ? '>' : '<', pos + 1);
	
	ccmp = cp_bit_sequence_cmp(b, c, &cpos);
#define SIGN(p) ((p) > 0 ? 1 : -1)
	printf("actual: b %c c, difference at bit %d - %s\n", cmp > 0 ? '>' : '<', cpos + 1, 
		(cpos == pos && SIGN(cmp) == SIGN(ccmp) ? "success" : "error"));

	cp_bit_sequence_destroy(c);
	free(pre3);

	strcpy(buf, pre1);
	strcat(buf, pre2);
	cp_bit_sequence_cat(a, b);
	res = cp_bit_sequence_to_string(a);
	printf("testing [%s] + [%s]\n", pre1, pre2);
	printf("expected: [%s]\n", buf);
	printf("actual  : [%s] - %s\n", res, (strcmp(res, buf) == 0) ? "success" : "error");
	free(pre1); free(pre2); free(res);

	cp_bit_sequence_cat(b, a);

	pre1 = cp_bit_sequence_to_string(b);
	pre2 = cp_bit_sequence_to_string(a);
	strcpy(buf, pre1);
	strcat(buf, pre2);
	cp_bit_sequence_cat(b, a);
	res = cp_bit_sequence_to_string(b);
	printf("testing [%s] + [%s]\n", pre1, pre2);
	printf("expected: [%s]\n", buf);
	printf("actual  : [%s] - %s\n", res, (strcmp(res, buf) == 0) ? "success" : "error");

	free(pre1); free(pre2); 
	cp_bit_sequence_destroy(a);

	printf("\ntesting shift left\n");
	pre1 = res;
	while (1)
	{
		pos = (b->length / 2) - 1;
		if (pos <= 0) break;
		a = cp_bit_sequence_dup(b);
		cp_bit_sequence_shift_left(a, pos);
		pre2 = cp_bit_sequence_to_string(a);
		printf("testing [%s] << %d\n", pre1, pos);
		pre1 = &pre1[pos];
		printf("expected [%s]\n", pre1);
		printf("actual   [%s] - %s\n", pre2, (strcmp(pre1, pre2) == 0) ? "success" : "error");
		cp_bit_sequence_destroy(b);
		free(pre2);
		b = a;
	} 
		
	free(res);
	cp_bit_sequence_destroy(b);

	printf("\ntesting initialization from string\n");
	pre1 = "10101010101010101000111010101011101000011100101010101010101111000111000110001";
	a = cstr_to_bit_sequence(pre1);
	pre2 = cp_bit_sequence_to_string(a);
	printf("testing  [%s]\n", pre1);
	printf("expected [%s]\n", pre1);
	printf("actual   [%s] - %s\n", pre2, (strcmp(pre1, pre2) == 0) ? "success" : "error");
	free(pre2);

	pre2 = "101";
	b = cstr_to_bit_sequence(pre2);
	printf("testing compare: [%s], [%s]\n", pre1, pre2);
	cmp = cp_bit_sequence_cmp(a, b, &pos);
	printf("expected: a > b , pos 3\n");
	printf("actual: cmp %s 0, pos %d - %s\n", cmp > 0 ? ">" : cmp < 0 ? "<" : "==", pos, (cmp > 0 && pos == 3) ? "success" : "error");
	cp_bit_sequence_destroy(b);

	pre2 = "100";
	b = cstr_to_bit_sequence(pre2);
	printf("testing compare: [%s], [%s]\n", pre2, pre1);
	cmp = cp_bit_sequence_cmp(a, b, &pos);
	printf("expected: cmp > 0, pos 2\n");
	printf("actual: cmp %s 0, pos %d - %s\n", cmp > 0 ? ">" : cmp < 0 ? "<" : "==", pos, (cmp > 0 && pos == 2) ? "success" : "error");

	cp_bit_sequence_destroy(a);
	cp_bit_sequence_destroy(b);

	test_short_strings();

	return 0;
}
示例#5
0
int svdcmp(float **a, int m, int n, float w[], float **v)
{// return 0 if result bad
	float pythag(float a, float b);
	int flag,i,its,j,jj,k,l,nm;
	float anorm,c,f,g,h,s,scale,x,y,z,*rv1;
 	int res = 1;

	float volatile temp;

	rv1=vector(1,n);
	g=scale=anorm=0.0;
	for (i=1;i<=n;i++) {
		l=i+1;
		rv1[i]=scale*g;
		g=s=scale=0.0;
		if (i <= m) {
			for (k=i;k<=m;k++) scale += fabs(a[k][i]);
			if (scale) {
				for (k=i;k<=m;k++) {
					a[k][i] /= scale;
					s += a[k][i]*a[k][i];
				}
				f=a[i][i];
				g = -SIGN(sqrt(s),f);
				h=f*g-s;
				a[i][i]=f-g;
				for (j=l;j<=n;j++) {
					for (s=0.0,k=i;k<=m;k++) s += a[k][i]*a[k][j];
					f=s/h;
					for (k=i;k<=m;k++) a[k][j] += f*a[k][i];
				}
				for (k=i;k<=m;k++) a[k][i] *= scale;
			}
		}
		w[i]=scale *g;
		g=s=scale=0.0;
		if (i <= m && i != n) {
			for (k=l;k<=n;k++) scale += fabs(a[i][k]);
			if (scale) {
				for (k=l;k<=n;k++) {
					a[i][k] /= scale;
					s += a[i][k]*a[i][k];
				}
				f=a[i][l];
				g = -SIGN(sqrt(s),f);
				h=f*g-s;
				a[i][l]=f-g;
				for (k=l;k<=n;k++) rv1[k]=a[i][k]/h;
				for (j=l;j<=m;j++) {
					for (s=0.0,k=l;k<=n;k++) s += a[j][k]*a[i][k];
					for (k=l;k<=n;k++) a[j][k] += s*rv1[k];
				}
				for (k=l;k<=n;k++) a[i][k] *= scale;
			}
		}
		anorm=FMAX(anorm,(fabs(w[i])+fabs(rv1[i])));
	}
	for (i=n;i>=1;i--) {
		if (i < n) {
			if (g) {
				for (j=l;j<=n;j++)
					v[j][i]=(a[i][j]/a[i][l])/g;
				for (j=l;j<=n;j++) {
					for (s=0.0,k=l;k<=n;k++) s += a[i][k]*v[k][j];
					for (k=l;k<=n;k++) v[k][j] += s*v[k][i];
				}
			}
			for (j=l;j<=n;j++) v[i][j]=v[j][i]=0.0;
		}
		v[i][i]=1.0;
		g=rv1[i];
		l=i;
	}
	for (i=IMIN(m,n);i>=1;i--) {
		l=i+1;
		g=w[i];
		for (j=l;j<=n;j++) a[i][j]=0.0;
		if (g) {
			g=1.0/g;
			for (j=l;j<=n;j++) {
				for (s=0.0,k=l;k<=m;k++) s += a[k][i]*a[k][j];
				f=(s/a[i][i])*g;
				for (k=i;k<=m;k++) a[k][j] += f*a[k][i];
			}
			for (j=i;j<=m;j++) a[j][i] *= g;
		} else for (j=i;j<=m;j++) a[j][i]=0.0;
		++a[i][i];
	}
	for (k=n;k>=1;k--) {
		for (its=1;its<=30;its++) {
			flag=1;
			for (l=k;l>=1;l--) {
				nm=l-1;
				temp= (fabs(rv1[l])+anorm);
				if (temp == anorm) {
					flag=0;
					break;
				}
				temp= (fabs(w[nm])+anorm);
				if (temp == anorm) break;
			}
			if (flag) {
				c=0.0;
				s=1.0;
				for (i=l;i<=k;i++) {
					f=s*rv1[i];
					rv1[i]=c*rv1[i];
					temp= (fabs(f)+anorm);
					if (temp == anorm) break;
					g=w[i];
					h=pythag(f,g);
					w[i]=h;
					h=1.0/h;
					c=g*h;
					s = -f*h;
					for (j=1;j<=m;j++) {
						y=a[j][nm];
						z=a[j][i];
						a[j][nm]=y*c+z*s;
						a[j][i]=z*c-y*s;
					}
				}
			}
			z=w[k];
			if (l == k) {
				if (z < 0.0) {
					w[k] = -z;
					for (j=1;j<=n;j++) v[j][k] = -v[j][k];
				}
				break;
			}
			if (its == 40) {
			   cout<<"\nSVDCMP():no convergence in 40 svdcmp iterations"<<endl;
			   nrerror("no convergence in 40 svdcmp iterations",0);
			   //for (j=1;j<=m;j++) //by XDR
			     //for (jj=1;jj<i=n;jj++)
			     //	v[j][jj]=0; 
			   // free_vector(rv1,1,n);
			   //return 0;  // result bad
			  res = 0;
			}
			x=w[l];
			nm=k-1;
			y=w[nm];
			g=rv1[nm];
			h=rv1[k];
			f=((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y);
			g=pythag(f,1.0);
			f=((x-z)*(x+z)+h*((y/(f+SIGN(g,f)))-h))/x;
			c=s=1.0;
			for (j=l;j<=nm;j++) {
				i=j+1;
				g=rv1[i];
				y=w[i];
				h=s*g;
				g=c*g;
				z=pythag(f,h);
				rv1[j]=z;
				c=f/z;
				s=h/z;
				f=x*c+g*s;
				g = g*c-x*s;
				h=y*s;
				y *= c;
				for (jj=1;jj<=n;jj++) {
					x=v[jj][j];
					z=v[jj][i];
					v[jj][j]=x*c+z*s;
					v[jj][i]=z*c-x*s;
				}
				z=pythag(f,h);
				w[j]=z;
				if (z) {
					z=1.0/z;
					c=f*z;
					s=h*z;
				}
				f=c*g+s*y;
				x=c*y-s*g;
				for (jj=1;jj<=m;jj++) {
					y=a[jj][j];
					z=a[jj][i];
					a[jj][j]=y*c+z*s;
					a[jj][i]=z*c-y*s;
				}
			}
			rv1[l]=0.0;
			rv1[k]=f;
			w[k]=x;
		}
	}
	free_vector(rv1,1,n);
	return res; // good defined result when res = 1
}
示例#6
0
cholmod_sparse *CHOLMOD(copy)
(
    /* ---- input ---- */
    cholmod_sparse *A,	/* matrix to copy */
    int stype,		/* requested stype of C */
    int mode,		/* >0: numerical, 0: pattern, <0: pattern (no diag) */
    /* --------------- */
    cholmod_common *Common
)
{
    cholmod_sparse *C ;
    Int nrow, ncol, up, lo, values, diag, astype ;

    /* ---------------------------------------------------------------------- */
    /* check inputs */
    /* ---------------------------------------------------------------------- */

    RETURN_IF_NULL_COMMON (NULL) ;
    RETURN_IF_NULL (A, NULL) ;
    values = (mode > 0) && (A->xtype != CHOLMOD_PATTERN) ;
    RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN,
	    values ? CHOLMOD_REAL : CHOLMOD_ZOMPLEX, NULL) ;
    nrow = A->nrow ;
    ncol = A->ncol ;
    if ((stype || A->stype) && nrow != ncol)
    {
	/* inputs invalid */
	ERROR (CHOLMOD_INVALID, "matrix invalid") ;
	return (NULL) ;
    }
    Common->status = CHOLMOD_OK ;

    /* ---------------------------------------------------------------------- */
    /* allocate workspace */
    /* ---------------------------------------------------------------------- */

    CHOLMOD(allocate_work) (0, MAX (nrow,ncol), 0, Common) ;
    if (Common->status < CHOLMOD_OK)
    {
	/* out of memory */
	return (NULL) ;
    }

    /* ---------------------------------------------------------------------- */
    /* get inputs */
    /* ---------------------------------------------------------------------- */

    diag = (mode >= 0) ;
    astype = SIGN (A->stype) ;
    stype = SIGN (stype) ;
    up = (astype > 0) ;
    lo = (astype < 0) ;

    /* ---------------------------------------------------------------------- */
    /* copy the matrix */
    /* ---------------------------------------------------------------------- */

    if (astype == stype)
    {

	/* ------------------------------------------------------------------ */
	/* symmetry of A and C are the same */
	/* ------------------------------------------------------------------ */

	/* copy A into C, keeping the same symmetry.  If A is symmetric
	 * entries in the ignored part of A are not copied into C */
	C = CHOLMOD(band) (A, -nrow, ncol, mode, Common) ;

    }
    else if (!astype)
    {

	/* ------------------------------------------------------------------ */
	/* convert unsymmetric matrix A into a symmetric matrix C */
	/* ------------------------------------------------------------------ */

	if (stype > 0)
	{
	    /* C = triu (A) */
	    C = CHOLMOD(band) (A, 0, ncol, mode, Common) ;
	}
	else
	{
	    /* C = tril (A) */
	    C = CHOLMOD(band) (A, -nrow, 0, mode, Common) ;
	}
	if (Common->status < CHOLMOD_OK)
	{
	    /* out of memory */
	    return (NULL) ;
	}
	C->stype = stype ;

    }
    else if (astype == -stype)
    {

	/* ------------------------------------------------------------------ */
	/* transpose a symmetric matrix */
	/* ------------------------------------------------------------------ */

	/* converting upper to lower or lower to upper */
	/* workspace: Iwork (nrow) */
	C = CHOLMOD(transpose) (A, values, Common) ;
	if (!diag)
	{
	    /* remove diagonal, if requested */
	    CHOLMOD(band_inplace) (-nrow, ncol, -1, C, Common) ;
	}

    }
    else
    {

	/* ------------------------------------------------------------------ */
	/* create an unsymmetric copy of a symmetric matrix */
	/* ------------------------------------------------------------------ */

	C = copy_sym_to_unsym (A, mode, Common) ;
    }

    /* ---------------------------------------------------------------------- */
    /* return if error */
    /* ---------------------------------------------------------------------- */

    if (Common->status < CHOLMOD_OK)
    {
	/* out of memory */
	return (NULL) ;
    }

    /* ---------------------------------------------------------------------- */
    /* return the result */
    /* ---------------------------------------------------------------------- */

    DEBUG (diag = CHOLMOD(dump_sparse) (C, "copy", Common)) ;
    PRINT1 (("mode %d nnzdiag "ID"\n", mode, diag)) ;
    ASSERT (IMPLIES (mode < 0, diag == 0)) ;
    return (C) ;
}
示例#7
0
void svdcmp(double** a, int m, int n, double* w, double** v)
{
  int flag,i,its,j,jj,k,l,nm;
  double c,f,h,s,x,y,z;
  double anorm=0.0,g=0.0,scale=0.0;
  double *rv1;
  void nrerror();

  if (m < n) ntrerror("SVDCMP: You must augment A with extra zero rows");
  rv1=allocVect(n);
  for (i=1;i<=n;i++) {
    l=i+1;
    rv1[i]=scale*g;
    g=s=scale=0.0;
    if (i <= m) {
      for (k=i;k<=m;k++) scale += fabs(a[k][i]);
      if (scale) {
	for (k=i;k<=m;k++) {
	  a[k][i] /= scale;
	  s += a[k][i]*a[k][i];
	}
	f=a[i][i];
	g = -SIGN(sqrt(s),f);
	h=f*g-s;
	a[i][i]=f-g;
	if (i != n) {
	  for (j=l;j<=n;j++) {
	    for (s=0.0,k=i;k<=m;k++) s += a[k][i]*a[k][j];
	    f=s/h;
	    for (k=i;k<=m;k++) a[k][j] += f*a[k][i];
	  }
	}
	for (k=i;k<=m;k++) a[k][i] *= scale;
      }
    }
    w[i]=scale*g;
    g=s=scale=0.0;
    if (i <= m && i != n) {
      for (k=l;k<=n;k++) scale += fabs(a[i][k]);
      if (scale) {
	for (k=l;k<=n;k++) {
	  a[i][k] /= scale;
	  s += a[i][k]*a[i][k];
	}
	f=a[i][l];
	g = -SIGN(sqrt(s),f);
	h=f*g-s;
	a[i][l]=f-g;
	for (k=l;k<=n;k++) rv1[k]=a[i][k]/h;
	if (i != m) {
	  for (j=l;j<=m;j++) {
	    for (s=0.0,k=l;k<=n;k++) s += a[j][k]*a[i][k];
	    for (k=l;k<=n;k++) a[j][k] += s*rv1[k];
	  }
	}
	for (k=l;k<=n;k++) a[i][k] *= scale;
      }
    }
    anorm=MAX(anorm,(fabs(w[i])+fabs(rv1[i])));
  }
  for (i=n;i>=1;i--) {
    if (i < n) {
      if (g) {
	for (j=l;j<=n;j++)
	  v[j][i]=(a[i][j]/a[i][l])/g;
	for (j=l;j<=n;j++) {
	  for (s=0.0,k=l;k<=n;k++) s += a[i][k]*v[k][j];
	  for (k=l;k<=n;k++) v[k][j] += s*v[k][i];
	}
      }
      for (j=l;j<=n;j++) v[i][j]=v[j][i]=0.0;
    }
    v[i][i]=1.0;
    g=rv1[i];
    l=i;
  }
  for (i=n;i>=1;i--) {
    l=i+1;
    g=w[i];
    if (i < n)
      for (j=l;j<=n;j++) a[i][j]=0.0;
    if (g) {
      g=1.0/g;
      if (i != n) {
	for (j=l;j<=n;j++) {
	  for (s=0.0,k=l;k<=m;k++) s += a[k][i]*a[k][j];
	  f=(s/a[i][i])*g;
	  for (k=i;k<=m;k++) a[k][j] += f*a[k][i];
	}
      }
      for (j=i;j<=m;j++) a[j][i] *= g;
    } else {
      for (j=i;j<=m;j++) a[j][i]=0.0;
    }
    ++a[i][i];
  }
  for (k=n;k>=1;k--) {
    for (its=1;its<=30;its++) {
      flag=1;
      for (l=k;l>=1;l--) {
	nm=l-1;
	if (fabs(rv1[l])+anorm == anorm) {
	  flag=0;
	  break;
	}
	if (fabs(w[nm])+anorm == anorm) break;
      }
      if (flag) {
	c=0.0;
	s=1.0;
	for (i=l;i<=k;i++) {
	  f=s*rv1[i];
	  if (fabs(f)+anorm != anorm) {
	    g=w[i];
	    h=PYTHAG(f,g);
	    w[i]=h;
	    h=1.0/h;
	    c=g*h;
	    s=(-f*h);
	    for (j=1;j<=m;j++) {
	      y=a[j][nm];
	      z=a[j][i];
	      a[j][nm]=y*c+z*s;
	      a[j][i]=z*c-y*s;
	    }
	  }
	}
      }
      z=w[k];
      if (l == k) {
	if (z < 0.0) {
	  w[k] = -z;
	  for (j=1;j<=n;j++) v[j][k]=(-v[j][k]);
	}
	break;
      }
      if (its == 30) ntrerror("No convergence in 30 SVDCMP iterations");
      x=w[l];
      nm=k-1;
      y=w[nm];
      g=rv1[nm];
      h=rv1[k];
      f=((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y);
      g=PYTHAG(f,1.0);
      f=((x-z)*(x+z)+h*((y/(f+SIGN(g,f)))-h))/x;
      c=s=1.0;
      for (j=l;j<=nm;j++) {
	i=j+1;
	g=rv1[i];
	y=w[i];
	h=s*g;
	g=c*g;
	z=PYTHAG(f,h);
	rv1[j]=z;
	c=f/z;
	s=h/z;
	f=x*c+g*s;
	g=g*c-x*s;
	h=y*s;
	y=y*c;
	for (jj=1;jj<=n;jj++) {
	  x=v[jj][j];
	  z=v[jj][i];
	  v[jj][j]=x*c+z*s;
	  v[jj][i]=z*c-x*s;
	}
	z=PYTHAG(f,h);
	w[j]=z;
	if (z) {
	  z=1.0/z;
	  c=f*z;
	  s=h*z;
	}
	f=(c*g)+(s*y);
	x=(c*y)-(s*g);
	for (jj=1;jj<=m;jj++) {
	  y=a[jj][j];
	  z=a[jj][i];
	  a[jj][j]=y*c+z*s;
	  a[jj][i]=z*c-y*s;
	}
      }
      rv1[l]=0.0;
      rv1[k]=f;
      w[k]=x;
    }
  }
  freeVect(rv1);
}
示例#8
0
void getlsampthresh(int N, double *t, double *mag, double *sig, double period, int harm_specsigflag, FILE *signalfile, int Nsubharm, int Nharm, double minPer, double thresh, double *ampthresh_scale, double *amp, int use_orig_ls)
{
  /* This routine takes a light curve and a period, it fits a fourier series to the light curve to determine the signal, which is subtracted from the light curve, it then scales the signal and adds it back to the light curve and calculates the lomb-scargle probability at the specified period. It repeats, adjusting the scale until the LS probability is above the thresh-hold at which point the threshhold scaling factor will be returned. If the original light curve does not pass the signal, a negative factor will be returned.

Embedded in this routine is the zbrent algorithm (see Numerical Recipes in C) to find the zero of LS-Prob = thresh.
*/
  double getlsampthresh_func(double amp_scale, int N, double *t, double *mag_orig, double *sig, double *mag_signal, double *mag_tmp, double period, int Nsubharm, int Nharm, double *subharmA, double *subharmB, double *harmA, double *harmB, double fundA, double fundB, double minPer, double thresh, int use_orig_ls);
  int i;
  double *subharmA, *subharmB, *harmA, *harmB, fundA, fundB, meanval, dum1, dum2;
  double *t_tmp, *mag_tmp, *sig_tmp, *mag_signal, *mag_orig, val0, val1;
  int iter;
  double a, b, c, d, e, min1, min2, fa, fb, fc, p, q, r, s, tol1, xm, tol;
  char *line;
  size_t line_size = MAXLEN;
  
  if((t_tmp = (double *) malloc(N * sizeof(double))) == NULL ||
     (mag_tmp = (double *) malloc(N * sizeof(double))) == NULL ||
     (sig_tmp = (double *) malloc(N * sizeof(double))) == NULL ||
     (mag_signal = (double *) malloc(N * sizeof(double))) == NULL ||
     (mag_orig = (double *) malloc(N * sizeof(double))) == NULL ||
     (subharmA = (double *) malloc((Nsubharm + 1) * sizeof(double))) == NULL ||
     (subharmB = (double *) malloc((Nsubharm + 1) * sizeof(double))) == NULL ||
     (harmA = (double *) malloc((Nharm + 1) * sizeof(double))) == NULL ||
     (harmB = (double *) malloc((Nharm + 1) * sizeof(double))) == NULL)
    error(ERR_MEMALLOC);

  /* First Get the signal */
  /* Read the signal in from the file if we're doing that */
  if(harm_specsigflag)
    {
      line = malloc(line_size);
      rewind(signalfile);
      val0 = 0.;
      for(i=0;i<N;i++)
	{
	  gnu_getline(&line,&line_size,signalfile);
	  sscanf(line,"%lf %lf %lf",&dum1,&dum2,&mag_signal[i]);
	  val0 += mag[i];
	}
      val0 = val0 / (double) N;
      for(i=0;i<N;i++)
	{
	  mag_signal[i] -= val0;
	  mag_orig[i] = mag[i] - mag_signal[i];
	}

      fclose(signalfile);
      free(line);
    }
  /* Otherwise fit a fourier series at the period to compute the signal */
  else
    {
      for(i=0;i<N;i++)
	{
	  t_tmp[i] = t[i]; mag_tmp[i] = mag[i]; sig_tmp[i] = sig[i];
	}
      dokillharms(N, t_tmp, mag_tmp, sig_tmp, 1, &period, Nsubharm, Nharm, &subharmA, &subharmB, &harmA, &harmB, &fundA, &fundB, &meanval, 0, NULL, amp, 0, KILLHARM_OUTTYPE_DEFAULT, -1.);
      for(i=0;i<N;i++)
	{
	  mag_signal[i] = mag[i] - mag_tmp[i];
	  mag_orig[i] = mag_tmp[i];
	}
    }

  /* Check to see if no signal still lies above the threshhold, or if the original signal lies below the threshhold */
  val0 = getlsampthresh_func(0., N, t, mag_orig, sig, mag_signal, mag_tmp, period, Nsubharm, Nharm, subharmA, subharmB, harmA, harmB, fundA, fundB, minPer, thresh, use_orig_ls);
  val1 = getlsampthresh_func(1., N, t, mag_orig, sig, mag_signal, mag_tmp, period, Nsubharm, Nharm, subharmA, subharmB, harmA, harmB, fundA, fundB, minPer, thresh, use_orig_ls);
  if(val0 < 0)
    {
      *ampthresh_scale = 0.;
      *amp = (*amp)*(*ampthresh_scale);
      free(t_tmp);
      free(mag_tmp);
      free(sig_tmp);
      free(mag_signal);
      free(mag_orig);
      free(subharmA);
      free(subharmB);
      free(harmA);
      free(harmB);
      return;
    }
  if(val1 > 0)
    {
      *ampthresh_scale = -1.;
      *amp = (*amp)*(*ampthresh_scale);
      free(t_tmp);
      free(mag_tmp);
      free(sig_tmp);
      free(mag_signal);
      free(mag_orig);
      free(subharmA);
      free(subharmB);
      free(harmA);
      free(harmB);
      return;
    }
  a = 0.;
  b = 1.;
  tol = 1.0e-5;

  /* Now start the zbrent loop */
  fa = val0; fb = val1;
  fc = fb;
  for (iter=1; iter<=ITMAX; iter++) {
    if ((fb > 0.0 && fc > 0.0) || (fb < 0.0 && fc < 0.0)) {
      c = a;
      fc = fa;
      e=d=b-a;
    }
    if(fabs(fc) < fabs(fb)) {
      a = b; b = c; c = a; fa = fb; fb = fc; fc = fa;
    }
    tol1 = 2.0*EPS*fabs(b)+0.5*tol;
    xm=0.5*(c-b);
    if (fabs(xm) <= tol1 || fb == 0.0)
      {
	*ampthresh_scale = b;
	*amp = (*amp)*(*ampthresh_scale);
	free(t_tmp);
	free(mag_tmp);
	free(sig_tmp);
	free(mag_signal);
	free(mag_orig);
	free(subharmA);
	free(subharmB);
	free(harmA);
	free(harmB);
	return;
      }
    if (fabs(e) >= tol1 && fabs(fa) > fabs(fb)) {
      s = fb/fa;
      if (a == c) {
	p = 2.0*xm*s;
	q = 1.0 - s;
      } else {
	q = fa/fc;
	r = fb/fc;
	p = s*(2.0*xm*q*(q-r)-(b-a)*(r-1.0));
	q = (q-1.0)*(r-1.0)*(s-1.0);
      }
      if (p > 0.0) q = -q;
      p = fabs(p);
      min1 = 3.0*xm*q - fabs(tol1*q);
      min2 = fabs(e*q);
      if (2.0*p < (min1 < min2 ? min1 : min2)) {
	e=d;
	d=p/q;
      } else {
	d=xm;
	e=d;
      }
    } else {
      d=xm;
      e=d;
    }
    a=b;
    fa=fb;
    if (fabs(d) > tol1)
      b += d;
    else
      b += SIGN(tol1,xm);
    fb = getlsampthresh_func(b, N, t, mag_orig, sig, mag_signal, mag_tmp, period, Nsubharm, Nharm, subharmA, subharmB, harmA, harmB, fundA, fundB, minPer, thresh, use_orig_ls);
  }
  /* Too many iterations - set ampthresh_scale to -2. */
  *ampthresh_scale = -2.;
  *amp = (*amp)*(*ampthresh_scale);
  free(t_tmp);
  free(mag_tmp);
  free(sig_tmp);
  free(mag_signal);
  free(mag_orig);
  free(subharmA);
  free(subharmB);
  free(harmA);
  free(harmB);
  return;
}
示例#9
0
static void
underflow (mpfr_exp_t e)
{
  mpfr_t x, y, z1, z2;
  mpfr_exp_t emin;
  int i, k;
  int prec;
  int rnd;
  int div;
  int inex1, inex2;
  unsigned int flags1, flags2;

  /* Test mul_2si(x, e - k), div_2si(x, k - e) and div_2ui(x, k - e)
   * with emin = e, x = 1 + i/16, i in { -1, 0, 1 }, and k = 1 to 4,
   * by comparing the result with the one of a simple division.
   */
  emin = mpfr_get_emin ();
  set_emin (e);
  mpfr_inits2 (8, x, y, (mpfr_ptr) 0);
  for (i = 15; i <= 17; i++)
    {
      inex1 = mpfr_set_ui_2exp (x, i, -4, MPFR_RNDN);
      MPFR_ASSERTN (inex1 == 0);
      for (prec = 6; prec >= 3; prec -= 3)
        {
          mpfr_inits2 (prec, z1, z2, (mpfr_ptr) 0);
          RND_LOOP (rnd)
            for (k = 1; k <= 4; k++)
              {
                /* The following one is assumed to be correct. */
                inex1 = mpfr_mul_2si (y, x, e, MPFR_RNDN);
                MPFR_ASSERTN (inex1 == 0);
                inex1 = mpfr_set_ui (z1, 1 << k, MPFR_RNDN);
                MPFR_ASSERTN (inex1 == 0);
                mpfr_clear_flags ();
                /* Do not use mpfr_div_ui to avoid the optimization
                   by mpfr_div_2si. */
                inex1 = mpfr_div (z1, y, z1, (mpfr_rnd_t) rnd);
                flags1 = __gmpfr_flags;

              for (div = 0; div <= 2; div++)
                {
                  mpfr_clear_flags ();
                  inex2 = div == 0 ?
                    mpfr_mul_2si (z2, x, e - k, (mpfr_rnd_t) rnd) : div == 1 ?
                    mpfr_div_2si (z2, x, k - e, (mpfr_rnd_t) rnd) :
                    mpfr_div_2ui (z2, x, k - e, (mpfr_rnd_t) rnd);
                  flags2 = __gmpfr_flags;
                  if (flags1 == flags2 && SAME_SIGN (inex1, inex2) &&
                      mpfr_equal_p (z1, z2))
                    continue;
                  printf ("Error in underflow(");
                  if (e == MPFR_EMIN_MIN)
                    printf ("MPFR_EMIN_MIN");
                  else if (e == emin)
                    printf ("default emin");
                  else if (e >= LONG_MIN)
                    printf ("%ld", (long) e);
                  else
                    printf ("<LONG_MIN");
                  printf (") with mpfr_%s,\nx = %d/16, prec = %d, k = %d, "
                          "%s\n", div == 0 ? "mul_2si" : div == 1 ?
                          "div_2si" : "div_2ui", i, prec, k,
                          mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
                  printf ("Expected ");
                  mpfr_out_str (stdout, 16, 0, z1, MPFR_RNDN);
                  printf (", inex = %d, flags = %u\n", SIGN (inex1), flags1);
                  printf ("Got      ");
                  mpfr_out_str (stdout, 16, 0, z2, MPFR_RNDN);
                  printf (", inex = %d, flags = %u\n", SIGN (inex2), flags2);
                  exit (1);
                }  /* div */
              }  /* k */
          mpfr_clears (z1, z2, (mpfr_ptr) 0);
        }  /* prec */
    }  /* i */
  mpfr_clears (x, y, (mpfr_ptr) 0);
  set_emin (emin);
}
示例#10
0
文件: rnlms.c 项目: muravjov/rnlms
/*
Обрабатывает один отсчёт сигнала:
1) расчитывает выход фильтра
2) адаптирует коэффициенты фильтра
*/
NUM rnlms_func(rnlms_data_hnd f, NUM far_, NUM near_, NUM *err, NUM *output)
{
    //  size_t i;
    NUM Psi;
    NUM mediana;


    f->norma += SQR(near_) - SQR(CB_get_first_elem(f->sig)) ;//  f->norma == X*X'

    CB_push_elem(f->sig, near_);

    *output = convolution_CB_and_vector(f->sig, f->coeff); //выход фильтра
    *err = far_ - *output;

    if (f->opt & OPT_INHIBIT_ADAPTATION)
        return *err;


    //CB_push_elem(f->err_buf, *err);
    MediatorInsert(f->err_buf, *err);



    //  NUM mediana = CB_mediana(f->err_buf);
    mediana = MediatorMedian(f->err_buf);

    //  {
    //    NUM tmp[3];
    //    memcpy(tmp, f->err_buf->data, sizeof(NUM)*f->param.ERR_BUF_LEN);
    //    qsort(tmp, f->param.ERR_BUF_LEN, sizeof(NUM), compare_NUM);
    //    fprintf(stderr, "%f %f\n", *err,  mediana);
    //  }


    if (3 * NUM_abs(mediana) > *err) //FIXME почему 3 ???
        Psi = *err * (f->param.ALPHA);
    else
        Psi = 0.5f * mediana * (f->param.ALPHA) * SIGN(*err);


//  NUM tmp = Psi/(f->param.BETTA+f->norma);

    CB_multiple_and_add(f->sig, Psi/(f->param.BETTA+f->norma), &(f->coeff));

    /* for (i =0; i<f->param.len; ++i) */
    /*   { */
    /*     NUM x_i = CB_get_elem(f->sig, i); */
    /*     f->coeff[i] += Psi*(x_i/(f->param.BETTA+f->norma)); */
    /*   } */

    //  f->DELTA = f->MEMORY_FACTOR * f->DELTA + (1 - (f->MEMORY_FACTOR)) * MIN(SQR(*err)/(f->BETTA + f->norma), f->DELTA);

    if (!(f->opt & OPT_DISABLE_NONLINEAR_PROCESSING))
    {
        //      CB_push_elem(f->err_signal, SQR(*err/65535));
        CB_push_elem(f->err_signal, SQR(*err));
        double pwr = convolution_CB_and_vector(f->err_signal, level_measurement_filter_coeff);
        double level = (+10 * log10(pwr/LEVEL_MEASUREMENT_FILTER_LEN) - 83.11858286715683);
        fprintf(stderr, "level : %g\n", level);
        if (level < f->param.NLP_thresold)
            *err=0;
    }


    return *err;
}
示例#11
0
/*-----------------------------------------------------------------*/
int LoadSuesTable(char *fname, int col1, int log10flag,
                  int **pplutindex, double **pplog10p) {
    FSENV *fsenv;
    char tmpstr[2000], tmpstr2[2000], segname[2000], hemi[3];
    FILE *fp;
    int nitems, segindex;
    char *item;
    double v;

    memset(hemi,'\0',3);

    fsenv = FSENVgetenv();
    fp = fopen(fname,"r");
    if (fp == NULL) {
        printf("ERROR: could not open%s\n",fname);
        exit(1);
    }

    // Count the number of items
    nitems = 0;
    while (1) {
        if (fgets(tmpstr,2000-1,fp) == NULL) break;
        nitems++;
    }
    fclose(fp);
    printf("nitems %d\n",nitems);

    *pplutindex =    (int *) calloc(nitems,sizeof(int));
    *pplog10p   = (double *) calloc(nitems,sizeof(double));

    fp = fopen(fname,"r");
    nitems = 0;
    while (1) {
        if (fgets(tmpstr,2000-1,fp) == NULL) break;
        memset(tmpstr2,'\0',2000);
        sscanf(tmpstr,"%s",tmpstr2);
        memcpy(hemi,tmpstr2,2);
        sprintf(segname,"ctx-%2s-%s",hemi,&(tmpstr2[3]));
        CTABfindName(fsenv->ctab, segname, &segindex);
        if (segindex < 0) {
            printf("ERROR: reading %s, cannot find %s in color table\n",
                   fname,segname);
            printf("%s",tmpstr);
            exit(1);
        }
        item = gdfGetNthItemFromString(tmpstr,col1-1);
        if (item == NULL) {
            printf("ERROR: reading col %d from %s\n",col1,fname);
            exit(1);
        }
        sscanf(item,"%lf",&v);
        if (log10flag) v = -SIGN(v)*log10(fabs(v));
        printf("%2d %4d %20s %6.4lf\n",nitems+1,segindex,segname,v);
        (*pplutindex)[nitems] = segindex;
        (*pplog10p)[nitems] = v;
        nitems++;
        free(item);
    }
    fclose(fp);

    FSENVfree(&fsenv);
    return(nitems);
}
示例#12
0
void latlon2_(double *alat1, double *alon1, double *delta, double *azi, double *alat2, double *alon2) {
	double alat, alatr, alon, b, c, coslat, dlon;
	double r13, sinlat, x1, x2, x3;

	/* changed for ellipticity of earth
	 * changed use of *alat1 and *alat2
	 */

	double esq, alat3;
	esq=(1.0-1.0/298.25)*(1.0-1.0/298.25);
	alat3=atan(tan(*alat1*DEG_TO_RAD)*esq)*RAD_TO_DEG;

	/* Convert a geographical location to geocentric cartesian 
	 * coordinates, assuming a spherical earth
	 */

	alat = 90.0 - *delta;
	alon = 180.0 - *azi;
	r13  = cos(DEG_TO_RAD*alat);

	/* x1:	Axis 1 intersects equator at  0 deg longitude  
	 * x2:	Axis 2 intersects equator at 90 deg longitude  
	 * x3:	Axis 3 intersects north pole
	 */

	x1 = r13*sin(DEG_TO_RAD*alon);
	x2 = sin(DEG_TO_RAD*alat);
	x3 = r13*cos(DEG_TO_RAD*alon);

	/* Rotate in cartesian coordinates.  The cartesian coordinate system 
	 * is most easily described in geographic terms.  The origin is at 
	 * the Earth's center.  Rotation by alat1 degrees southward, about 
	 * the 1-axis.
	 */

	alatr  = (90.0-alat3)/RAD_TO_DEG;
	sinlat = sin(alatr);
	coslat = cos(alatr);
	b      = x2;
	c      = x3;
	x2     = b*coslat - c*sinlat;
	x3     = b*sinlat + c*coslat;

	/* Convert geocentric cartesian coordinates to a geographical 
	 * location, assuming a spherical earth
	 */

	r13    = sqrt(x3*x3 + x1*x1);
	dlon   = RAD_TO_DEG*atan2(x1, x3);

	/*  changed for ellipticity of earth
	 *   *alat2 = RAD_TO_DEG*atan2(x2, r13);
	 */

	alat3= atan2(x2, r13);
	*alat2=RAD_TO_DEG * atan(tan(alat3)/esq);

	*alon2 = *alon1 + dlon;
	if (fabs(*alon2) > 180.0)
		*alon2 = SIGN((360.0-fabs(*alon2)), *alon2);
}
示例#13
0
void AkFrac::setNumDen(qint64 num, qint64 den)
{
    bool changed = false;

    if (!den) {
        if (this->d->m_num != 0) {
            this->d->m_num = 0;
            changed = true;

            emit this->numChanged();
        }

        if (this->d->m_den != 0) {
            this->d->m_den = 0;
            changed = true;

            emit this->denChanged();
        }

        if (this->d->m_isValid != false) {
            this->d->m_isValid = false;
            changed = true;

            emit this->isValidChanged();
        }

        if (changed) {
            emit this->valueChanged();
            emit this->stringChanged();
        }

        return;
    }

    num = SIGN(den) * num;
    den = qAbs(den);
    AkFracPrivate::reduce(&num, &den);

    if (this->d->m_num != num) {
        this->d->m_num = num;
        changed = true;

        emit this->numChanged();
    }

    if (this->d->m_den != den) {
        this->d->m_den = den;
        changed = true;

        emit this->denChanged();
    }

    if (this->d->m_isValid != true) {
        this->d->m_isValid = true;
        changed = true;

        emit this->isValidChanged();
    }

    if (changed) {
        emit this->valueChanged();
        emit this->stringChanged();
    }
}
    std::vector<double> FrameToVec7(const cv::Mat frame)
    {
        // [0]-[2]: translation xyz
        // [3]-[6]: quaternion wxyz
        std::vector<double> pose(7, 0.0);

        double r11 = frame.at<double>(0,0);
        double r12 = frame.at<double>(0,1);
        double r13 = frame.at<double>(0,2);
        double r21 = frame.at<double>(1,0);
        double r22 = frame.at<double>(1,1);
        double r23 = frame.at<double>(1,2);
        double r31 = frame.at<double>(2,0);
        double r32 = frame.at<double>(2,1);
        double r33 = frame.at<double>(2,2);

        double qw = ( r11 + r22 + r33 + 1.0) / 4.0;
        double qx = ( r11 - r22 - r33 + 1.0) / 4.0;
        double qy = (-r11 + r22 - r33 + 1.0) / 4.0;
        double qz = (-r11 - r22 + r33 + 1.0) / 4.0;
        if(qw < 0.0f) qw = 0.0;
        if(qx < 0.0f) qx = 0.0;
        if(qy < 0.0f) qy = 0.0;
        if(qz < 0.0f) qz = 0.0;
        qw = std::sqrt(qw);
        qx = std::sqrt(qx);
        qy = std::sqrt(qy);
        qz = std::sqrt(qz);
        if(qw >= qx && qw >= qy && qw >= qz)
        {
            qw *= +1.0;
            qx *= SIGN(r32 - r23);
            qy *= SIGN(r13 - r31);
            qz *= SIGN(r21 - r12);
        }
        else if(qx >= qw && qx >= qy && qx >= qz)
        {
            qw *= SIGN(r32 - r23);
            qx *= +1.0;
            qy *= SIGN(r21 + r12);
            qz *= SIGN(r13 + r31);
        }
        else if(qy >= qw && qy >= qx && qy >= qz)
        {
            qw *= SIGN(r13 - r31);
            qx *= SIGN(r21 + r12);
            qy *= +1.0;
            qz *= SIGN(r32 + r23);
        }
        else if(qz >= qw && qz >= qx && qz >= qy)
        {
            qw *= SIGN(r21 - r12);
            qx *= SIGN(r31 + r13);
            qy *= SIGN(r32 + r23);
            qz *= +1.0;
        }
        else
        {
            printf("coding error\n");
        }
        double r = std::sqrt(qw*qw + qx*qx + qy*qy + qz*qz);
        qw /= r;
        qx /= r;
        qy /= r;
        qz /= r;

        pose[3] = qw;
        pose[4] = qx;
        pose[5] = qy;
        pose[6] = qz;

        // Translation
        pose[0] = frame.at<double>(0,3);
        pose[1] = frame.at<double>(1,3);
        pose[2] = frame.at<double>(2,3);
        return pose;
    }
void CCCatmullRomSprite::updateAtlas() {
    // populate points
    populatePoints(m_controlPoints, m_points);
    
    // clear
	m_atlas->removeAllQuads();
    m_segmentQuadIndices.clear();
    
    // basic check, at least we need two points
    int pc = m_points.getCount();
    if(pc < 2)
        return;
    
    // append a point to avoid losting last segment
    CCPoint pLast0 = m_points.getPointAt(pc - 1);
    CCPoint pLast1 = m_points.getPointAt(pc - 2);
    CCPoint pAppend = ccpAdd(pLast0, ccpSub(pLast0, pLast1));
    m_points.addPoint(pAppend);
    pc++;
    
    // first two points
    CCPoint p0 = m_points.getPointAt(0);
    CCPoint p1 = m_points.getPointAt(1);
    
    // half width of pattern
    float halfWidth = m_patternWidth / 2;

    // bl and br of first quad
    CCPoint bl, tl;
    {
        CCPoint v01 = ccpSub(p1, p0);
        float r01 = ccpToAngle(v01);
        bl.x = p0.x + halfWidth * sinf(r01);
        bl.y = p0.y - halfWidth * cosf(r01);
        tl.x = p0.x - halfWidth * sinf(r01);
        tl.y = p0.y + halfWidth * cosf(r01);
    }
    
    // current length
    float texStartP = 0;
	float texEndP;
	float headPos = 0;
    
    // populate quads
    int segIndex = 0;
    for(int i = 2; i < pc; i++) {
        // save quad index
        if(m_segmentPointIndices[segIndex] == i - 2) {
            m_segmentQuadIndices.push_back(m_atlas->getTotalQuads());
            segIndex++;
        }
        
        // third point
        CCPoint p2 = m_points.getPointAt(i);
        
        // 3 vectors, from 0 to 1, from 1 to 2, from 1 to 0
        CCPoint v01 = ccpSub(p1, p0);
        CCPoint v12 = ccpSub(p2, p1);
        CCPoint v10 = ccpSub(p0, p1);
        
        // angle in center of v01 and v12, then rotate 90 degrees
        float r = (ccpToAngle(v01) + ccpToAngle(v12)) / 2 - M_PI_2;
        
        // the vector of center divider
        CCPoint m = ccp(cosf(r), sinf(r));
        
        // angle between center and v10
        float rm01 = ccpToAngle(m) - ccpToAngle(v10);
        
        // the actual base width of joint
        // but we must prevent the base width to be too large
        float s = sinf(rm01);
        float w = MAX_FLOAT;
        if(s != 0)
            w = fabsf(halfWidth / s);
        w = MIN(halfWidth * 2, w);
        
        // a corner situation when v01 is in third quadrant and v12 is in fourth quadrant
        if(v01.x < 0 && SIGN(v01.x) == SIGN(v12.x) && SIGN(v01.y) != SIGN(v12.y)) {
            r = M_PI + r;
        }
		
		// populate tl and tr
		CCPoint br, tr;
        br.x = p1.x + w * cosf(r);
        br.y = p1.y + w * sinf(r);
        tr.x = p1.x - w * cosf(r);
        tr.y = p1.y - w * sinf(r);

        // calculate texcoords pencentage
        float segLen = ccpLength(v01);
		float remainLen = segLen;
        float initVerP = 0;
        float stepVerP = m_patternLength / segLen;
        while(remainLen > m_patternLength) {
            texEndP = texStartP;
            float p = (1 - texStartP) / (1 - texStartP + texEndP);
            populateQuad(bl, br, tl, tr, texStartP, 1, initVerP, initVerP + stepVerP * p);
            populateQuad(bl, br, tl, tr, 0, texEndP, initVerP + stepVerP * p, initVerP + stepVerP);
            initVerP += stepVerP;
            
            // cut pattern length
            remainLen -= m_patternLength;
        }
        
        // remaining length
		headPos += segLen;
		headPos = fmodf(headPos, m_patternLength);
        texEndP = headPos / m_patternLength;
        stepVerP = remainLen / segLen;
        if(texEndP <= texStartP) {
            float p = (1 - texStartP) / (1 - texStartP + texEndP);
            populateQuad(bl, br, tl, tr, texStartP, 1, initVerP, initVerP + stepVerP * p);
            populateQuad(bl, br, tl, tr, 0, texEndP, initVerP + stepVerP * p, initVerP + stepVerP);
        } else {
            populateQuad(bl, br, tl, tr, texStartP, texEndP, initVerP, 1);
        }
        
        // move forward
        p0 = p1;
        p1 = p2;
        bl = br;
        tl = tr;
        texStartP = texEndP;
    }
}
示例#16
0
//
// Do single unary node folding
//
// Returns a new node representing the result.
//
TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) const
{
    // First, size the result, which is mostly the same as the argument's size,
    // but not always, and classify what is componentwise.
    // Also, eliminate cases that can't be compile-time constant.
    int resultSize;
    bool componentWise = true;

    int objectSize = getType().computeNumComponents();
    switch (op) {
    case EOpDeterminant:
    case EOpAny:
    case EOpAll:
    case EOpLength:
        componentWise = false;
        resultSize = 1;
        break;

    case EOpEmitStreamVertex:
    case EOpEndStreamPrimitive:
        // These don't actually fold
        return 0;

    case EOpPackSnorm2x16:
    case EOpPackUnorm2x16:
    case EOpPackHalf2x16:
        componentWise = false;
        resultSize = 1;
        break;

    case EOpUnpackSnorm2x16:
    case EOpUnpackUnorm2x16:
    case EOpUnpackHalf2x16:
        componentWise = false;
        resultSize = 2;
        break;

    case EOpNormalize:
        componentWise = false;
        resultSize = objectSize;
        break;

    default:
        resultSize = objectSize;
        break;
    }

    // Set up for processing
    TConstUnionArray newConstArray(resultSize);
    const TConstUnionArray& unionArray = getConstArray();

    // Process non-component-wise operations
    switch (op) {
    case EOpLength:
    case EOpNormalize:
    {
        double sum = 0;
        for (int i = 0; i < objectSize; i++)
            sum += unionArray[i].getDConst() * unionArray[i].getDConst();
        double length = sqrt(sum);
        if (op == EOpLength)
            newConstArray[0].setDConst(length);
        else {
            for (int i = 0; i < objectSize; i++)
                newConstArray[i].setDConst(unionArray[i].getDConst() / length);
        }
        break;
    }

    // TODO: 3.0 Functionality: unary constant folding: the rest of the ops have to be fleshed out

    case EOpPackSnorm2x16:
    case EOpPackUnorm2x16:
    case EOpPackHalf2x16:

    case EOpUnpackSnorm2x16:
    case EOpUnpackUnorm2x16:
    case EOpUnpackHalf2x16:

    case EOpDeterminant:
    case EOpMatrixInverse:
    case EOpTranspose:

    case EOpAny:
    case EOpAll:
        return 0;
    
    default:
        assert(componentWise);
        break;
    }

    // Turn off the componentwise loop
    if (! componentWise)
        objectSize = 0;

    // Process component-wise operations
    for (int i = 0; i < objectSize; i++) {
        switch (op) {
        case EOpNegative:
            switch (getType().getBasicType()) {
            case EbtDouble:
            case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break;
            case EbtInt:   newConstArray[i].setIConst(-unionArray[i].getIConst()); break;
            case EbtUint:  newConstArray[i].setUConst(static_cast<unsigned int>(-static_cast<int>(unionArray[i].getUConst())));  break;
            default:
                return 0;
            }
            break;
        case EOpLogicalNot:
        case EOpVectorLogicalNot:
            switch (getType().getBasicType()) {
            case EbtBool:  newConstArray[i].setBConst(!unionArray[i].getBConst()); break;
            default:
                return 0;
            }
            break;
        case EOpBitwiseNot:
            newConstArray[i] = ~unionArray[i];
            break;
        case EOpRadians:
            newConstArray[i].setDConst(unionArray[i].getDConst() * pi / 180.0);
            break;
        case EOpDegrees:
            newConstArray[i].setDConst(unionArray[i].getDConst() * 180.0 / pi);
            break;
        case EOpSin:
            newConstArray[i].setDConst(sin(unionArray[i].getDConst()));
            break;
        case EOpCos:
            newConstArray[i].setDConst(cos(unionArray[i].getDConst()));
            break;
        case EOpTan:
            newConstArray[i].setDConst(tan(unionArray[i].getDConst()));
            break;
        case EOpAsin:
            newConstArray[i].setDConst(asin(unionArray[i].getDConst()));
            break;
        case EOpAcos:
            newConstArray[i].setDConst(acos(unionArray[i].getDConst()));
            break;
        case EOpAtan:
            newConstArray[i].setDConst(atan(unionArray[i].getDConst()));
            break;

        case EOpDPdx:
        case EOpDPdy:
        case EOpFwidth:
        case EOpDPdxFine:
        case EOpDPdyFine:
        case EOpFwidthFine:
        case EOpDPdxCoarse:
        case EOpDPdyCoarse:
        case EOpFwidthCoarse:
            // The derivatives are all mandated to create a constant 0.
            newConstArray[i].setDConst(0.0);
            break;

        case EOpExp:
            newConstArray[i].setDConst(exp(unionArray[i].getDConst()));
            break;
        case EOpLog:
            newConstArray[i].setDConst(log(unionArray[i].getDConst()));
            break;
        case EOpExp2:
            {
                const double inv_log2_e = 0.69314718055994530941723212145818;
                newConstArray[i].setDConst(exp(unionArray[i].getDConst() * inv_log2_e));
                break;
            }
        case EOpLog2:
            {
                const double log2_e = 1.4426950408889634073599246810019;
                newConstArray[i].setDConst(log2_e * log(unionArray[i].getDConst()));
                break;
            }
        case EOpSqrt:
            newConstArray[i].setDConst(sqrt(unionArray[i].getDConst()));
            break;
        case EOpInverseSqrt:
            newConstArray[i].setDConst(1.0 / sqrt(unionArray[i].getDConst()));
            break;

        case EOpAbs:
            if (unionArray[i].getType() == EbtDouble)
                newConstArray[i].setDConst(fabs(unionArray[i].getDConst()));
            else if (unionArray[i].getType() == EbtInt)
                newConstArray[i].setIConst(abs(unionArray[i].getIConst()));
            else
                newConstArray[i] = unionArray[i];
            break;
        case EOpSign:
            #define SIGN(X) (X == 0 ? 0 : (X < 0 ? -1 : 1))
            if (unionArray[i].getType() == EbtDouble)
                newConstArray[i].setDConst(SIGN(unionArray[i].getDConst()));
            else
                newConstArray[i].setIConst(SIGN(unionArray[i].getIConst()));
            break;
        case EOpFloor:
            newConstArray[i].setDConst(floor(unionArray[i].getDConst()));
            break;
        case EOpTrunc:
            if (unionArray[i].getDConst() > 0)
                newConstArray[i].setDConst(floor(unionArray[i].getDConst()));
            else
                newConstArray[i].setDConst(ceil(unionArray[i].getDConst()));
            break;
        case EOpRound:
            newConstArray[i].setDConst(floor(0.5 + unionArray[i].getDConst()));
            break;
        case EOpRoundEven:
        {
            double flr = floor(unionArray[i].getDConst());
            bool even = flr / 2.0 == floor(flr / 2.0);
            double rounded = even ? ceil(unionArray[i].getDConst() - 0.5) : floor(unionArray[i].getDConst() + 0.5);
            newConstArray[i].setDConst(rounded);
            break;
        }
        case EOpCeil:
            newConstArray[i].setDConst(ceil(unionArray[i].getDConst()));
            break;
        case EOpFract:
        {
            double x = unionArray[i].getDConst();
            newConstArray[i].setDConst(x - floor(x));
            break;
        }

        case EOpIsNan:
        {
            newConstArray[i].setBConst(isNan(unionArray[i].getDConst()));
            break;
        }
        case EOpIsInf:
        {
            newConstArray[i].setBConst(isInf(unionArray[i].getDConst()));
            break;
        }

        // TODO: 3.0 Functionality: unary constant folding: the rest of the ops have to be fleshed out

        case EOpSinh:
        case EOpCosh:
        case EOpTanh:
        case EOpAsinh:
        case EOpAcosh:
        case EOpAtanh:

        case EOpFloatBitsToInt:
        case EOpFloatBitsToUint:
        case EOpIntBitsToFloat:
        case EOpUintBitsToFloat:

        default:
            return 0;
        }
    }

    TIntermConstantUnion *newNode = new TIntermConstantUnion(newConstArray, returnType);
    newNode->getWritableType().getQualifier().storage = EvqConst;
    newNode->setLoc(getLoc());

    return newNode;
}
示例#17
0
文件: Plane.hpp 项目: KasumiL5x/hadan
static void tqli( float d[3], float e[3], float z[3][3] ) {
  int        m,l,iter,i,k;
  float    s,r,p,g,f,dd,c,b;

  for(i=2;i<=3;i++)
    e[i-2]=e[i-1];    /* convenient to renumber the elements of e */
  e[2]=0.0;
  for(l=1;l<=3;l++)
    {
    iter=0;
    do
        {
        for(m=l;m<=2;m++)
            {
            /*
            **    Look for a single small subdiagonal element
            **    to split the matrix.
            */
            dd=fabs(d[m-1])+fabs(d[m]);
            if(fabs(e[m-1])+dd == dd)
                break;
            }
        if(m!=l)
            {
            if(iter++ == 30)
                {
                printf("\nToo many iterations in TQLI");
                }
            g=(d[l]-d[l-1])/(2.0f*e[l-1]); /* form shift */
            r=sqrt((g*g)+1.0f);
            g=d[m-1]-d[l-1]+e[l-1]/(g+SIGN(r,g)); /* this is dm-ks */
            s=c=1.0;
            p=0.0;
            for(i=m-1;i>=l;i--)
                {
                /*
                **    A plane rotation as in the original
                **    QL, followed by Givens rotations to
                **    restore tridiagonal form.
                */
                f=s*e[i-1];
                b=c*e[i-1];
                if(fabs(f) >= fabs(g))
                    {
                    c=g/f;
                    r=sqrt((c*c)+1.0f);
                    e[i]=f*r;
                    c*=(s=1.0f/r);
                    }
                else
                    {
                    s=f/g;
                    r=sqrt((s*s)+1.0f);
                    e[i]=g*r;
                    s*=(c=1.0f/r);
                    }
                g=d[i]-p;
                r=(d[i-1]-g)*s+2.0f*c*b;
                p=s*r;
                d[i]=g+p;
                g=c*r-b;
                for(k=1;k<=3;k++)
                    {
                    /*
                    **    Form eigenvectors
                    */
                    f=z[k-1][i];
                    z[k-1][i]=s*z[k-1][i-1]+c*f;
                    z[k-1][i-1]=c*z[k-1][i-1]-s*f;
                    }
                }
            d[l-1]=d[l-1]-p;
            e[l-1]=g;
            e[m-1]=0.0f;
            }
        }while(m != l);
    }
}
示例#18
0
void Grnn::Trainer::bracket(Grnn& grnn, double& a, double& b, double& c)
{
    double fa = error(grnn, a);
    double fb = error(grnn, b);
    if (fb > fa)
    {
        SWP(a, b);
        SWP(fa, fb);
    }
    c = b + GOLD*(b - a);
    double fc = error(grnn, c);
    double fu;
    while (fb > fc)
    {
        double r = (b - a)*(fb - fc);
        double q = (b - c)*(fb - fa);
        double u = b - (q*(b - c) - r*(b - a))/
            (2.0*SIGN(FMAX(fabs(q - r), TINY), q - r));
        double ulim = b + GLIMIT*(c - b);
        if(a > 5.0 && b > 5.0 && c > 5.0)
        {
                a = b;
                b = u;
                fa = fb;
                fb = fu;
                return;
        }
        if ((b - u)*(u - c) > 0.0)
        {
            fu = error(grnn, u);
            if (fu < fc)
            {
                a = b;
                b = u;
                fa = fb;
                fb = fu;
                return;
            } 
            else if (fu > fb)
            {
                c = u;
                fc = fu;
                return;
            }
            u = c + GOLD*(c - b);
            fu = error(grnn, u);
        }
        else if ((c - u)*(u - ulim) > 0.0) 
        {
            fu = error(grnn, u);
            if (fu < fc)
            {
                double temp;
                temp = c + GOLD*(c - b);
                SHFT(b, c, u, temp);
                temp = error(grnn, u);
                SHFT(fb, fc, fu, temp);
            }
        }
        else if ((u - ulim)*(ulim - c) >= 0.0)
        {
            u = ulim;
            fu = error(grnn, u);
        } 
        else 
        {
            u = c + GOLD*(c - b);
            fu = error(grnn, u);
        }
        SHFT(a, b, c, u);
        SHFT(fa, fb, fc, fu);
    }
}
示例#19
0
static cholmod_sparse *copy_sym_to_unsym
(
    /* ---- input ---- */
    cholmod_sparse *A,	/* matrix to copy */
    int mode,		/* >0: numerical, 0: pattern, <0: pattern (no diag)
			 * -2: pattern only, no diagonal, add 50% + n extra
			 * space to C */
    /* --------------- */
    cholmod_common *Common
)
{
    double aij ;
    double *Ax, *Cx ;
    Int *Ap, *Ai, *Anz, *Cp, *Ci, *Wj, *Iwork ;
    cholmod_sparse *C ;
    Int nrow, ncol, nz, packed, j, p, pend, i, pc, up, lo, values, diag,
	astype, extra ;

    /* ---------------------------------------------------------------------- */
    /* get inputs */
    /* ---------------------------------------------------------------------- */

    nrow = A->nrow ;
    ncol = A->ncol ;
    Ap  = A->p ;
    Anz = A->nz ;
    Ai  = A->i ;
    Ax  = A->x ;
    packed = A->packed ;
    values = (mode > 0) && (A->xtype != CHOLMOD_PATTERN) ;
    diag = (mode >= 0) ;

    astype = SIGN (A->stype) ;
    up = (astype > 0) ;
    lo = (astype < 0) ;
    ASSERT (astype != 0) ;

    /* ---------------------------------------------------------------------- */
    /* create an unsymmetric copy of a symmetric matrix */
    /* ---------------------------------------------------------------------- */

    Iwork = Common->Iwork ;
    Wj = Iwork ;		    /* size ncol (i/i/l) */

    /* In MATLAB notation, for converting a symmetric/upper matrix:
     *	U = triu (A) ;
     *	L = tril (U',-1) ;
     *	C = L + U ;
     *
     * For converting a symmetric/lower matrix to unsymmetric:
     *	L = tril (A) ;
     *	U = triu (L',1) ;
     *	C = L + U ;
     */
    ASSERT (up || lo) ;
    PRINT1 (("copy: convert symmetric to unsym\n")) ;

    /* count the number of entries in each column of C */
    for (j = 0 ; j < ncol ; j++)
    {
	Wj [j] = 0 ;
    }
    for (j = 0 ; j < ncol ; j++)
    {
	p = Ap [j] ;
	pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ;
	for ( ; p < pend ; p++)
	{
	    i = Ai [p] ;
	    if (i == j)
	    {
		/* the diagonal entry A(i,i) will appear just once
		 * (unless it is excluded with mode < 0) */
		if (diag)
		{
		    Wj [j]++ ;
		}
	    }
	    else if ((up && i < j) || (lo && i > j))
	    {
		/* upper case:  A(i,j) is in the strictly upper part;
		 * A(j,i) will be added to the strictly lower part of C.
		 * lower case is the opposite. */
		Wj [j]++ ;
		Wj [i]++ ;
	    }
	}
    }
    nz = 0 ;
    for (j = 0 ; j < ncol ; j++)
    {
	nz += Wj [j] ;
    }

    extra = (mode == -2) ? (nz/2 + ncol) : 0 ;

    /* allocate C.  C is sorted if and only if A is sorted */
    C = CHOLMOD(allocate_sparse) (nrow, ncol, nz + extra, A->sorted, TRUE, 0,
	    values ? A->xtype : CHOLMOD_PATTERN, Common) ;
    if (Common->status < CHOLMOD_OK)
    {
	return (NULL) ;
    }

    Cp = C->p ;
    Ci = C->i ;
    Cx = C->x ;

    /* construct the column pointers for C */
    p = 0 ;
    for (j = 0 ; j < ncol ; j++)
    {
	Cp [j] = p ;
	p += Wj [j] ;
    }
    Cp [ncol] = p ;
    for (j = 0 ; j < ncol ; j++)
    {
	Wj [j] = Cp [j] ;
    }

    /* construct C */
    if (values)
    {

	/* pattern and values */
	ASSERT (diag) ;
	for (j = 0 ; j < ncol ; j++)
	{
	    p = Ap [j] ;
	    pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ;
	    for ( ; p < pend ; p++)
	    {
		i = Ai [p] ;
		aij = Ax [p] ;
		if (i == j)
		{
		    /* add diagonal entry A(i,i) to column i */
		    pc = Wj [i]++ ;
		    Ci [pc] = i ;
		    Cx [pc] = aij ;
		}
		else if ((up && i < j) || (lo && i > j))
		{
		    /* add A(i,j) to column j */
		    pc = Wj [j]++ ;
		    Ci [pc] = i ;
		    Cx [pc] = aij ;
		    /* add A(j,i) to column i */
		    pc = Wj [i]++ ;
		    Ci [pc] = j ;
		    Cx [pc] = aij ;
		}
	    }
	}

    }
    else
    {

	/* pattern only, possibly excluding the diagonal */
	for (j = 0 ; j < ncol ; j++)
	{
	    p = Ap [j] ;
	    pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ;
	    for ( ; p < pend ; p++)
	    {
		i = Ai [p] ;
		if (i == j)
		{
		    /* add diagonal entry A(i,i) to column i
		     * (unless it is excluded with mode < 0) */
		    if (diag)
		    {
			Ci [Wj [i]++] = i ;
		    }
		}
		else if ((up && i < j) || (lo && i > j))
		{
		    /* add A(i,j) to column j */
		    Ci [Wj [j]++] = i ;
		    /* add A(j,i) to column i */
		    Ci [Wj [i]++] = j ;
		}
	    }
	}
    }

    /* ---------------------------------------------------------------------- */
    /* return the result */
    /* ---------------------------------------------------------------------- */

    DEBUG (i = CHOLMOD(dump_sparse) (C, "copy_sym_to_unsym", Common)) ;
    PRINT1 (("mode %d nnzdiag "ID"\n", mode, i)) ;
    ASSERT (IMPLIES (mode < 0, i == 0)) ;
    return (C) ;
}
示例#20
0
void Grnn::Trainer::trainBrent(Grnn& grnn)
{
    double a = tolerance();
    double b = grnn.bandwidth();
    double x = 0.5*(a + b);
    bracket(grnn, a, b, x);
       
    if (a > b)
        SWP(a, b);
        
    double fx = error(grnn, x);
    double w = x, fw = fx;
    double v = x, fv = fx;
    
    double d = 0.0, u, e = 0.0;
    for(unsigned iter = 1; iter <= maxIter(); ++iter) 
    {
        double xm = 0.5*(a + b);
        double tol1 = tolerance()*fabs(x) + ZEPS;
        double tol2 = 2.0*(tol1);
        if (fabs(x - xm) <= (tol2 - 0.5*(b - a))) 
            break;
        if (fabs(e) > tol1)
        {
            double p = (x-v)*(x-v)*(fx-fw) - (x-w)*(x-w)*(fx-fv);
            double q = 2.0*((x-v)*(fx-fw) - (x-w)*(fx-fv));
            
            if (q > 0.0) 
                p = -p;
            q = fabs(q);
            
            double etemp = e;
            e = d;
            if (fabs(p) >= fabs(0.5*q*etemp) || 
                p <= q*(a - x) || 
                p >= q*(b - x))
            {
                if (x >= xm) 
                    e = a - x; 
                else 
                    e = b - x;
                d = CGOLD*(e);
            }   
            else
            {
                d = p/q;
                u = x + d;
                if (u - a < tol2 || b - u < tol2)
                    d = SIGN(tol1, xm - x);
            }
        } 
        else 
        {
            if (x >= xm) 
                    e = a - x; 
                else 
                    e = b - x;
            d = CGOLD *(e);
        }
        
        double u;
        if(fabs(d) >= tol1)
            u = x + d;
        else
            u = x + SIGN(tol1, d);
        double fu = error(grnn, u);
        if (fu <= fx) 
        {
            if (u >= x) 
                a = x; 
            else 
                b = x;
            SHFT(v, w, x, u);
            SHFT(fv, fw, fx, fu);
        } 
        else 
        {
            if (u < x) 
                a = u; 
            else
                b = u;
            if (fu <= fw || w == x)
            {
                v = w;
                w = u;
                fv = fw;
                fw = fu;
            } 
            else if (fu <= fv || v == x || v == w) 
            {
                v = u;
                fv = fu;
            }
        }
    }
    grnn.setBandwidth(x);
}
示例#21
0
int
DCtrCurv(CKTcircuit *ckt, int restart) 
                
                /* forced restart flag */
{
    TRCV *job = (TRCV *) ckt->CKTcurJob;

    int i;
    double *temp;
    int converged;
    int rcode;     
    int vcode;
    int icode;
    int j;
    int error;
    IFuid varUid;
    IFuid *nameList;
    int numNames;
    int firstTime=1;
    static runDesc *plot = NULL;

#ifdef WANT_SENSE2
    long save;
#ifdef SENSDEBUG
    if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode&DCSEN) ){
        printf("\nDC Sensitivity Results\n\n");
        CKTsenPrint(ckt);
    }
#endif /* SENSDEBUG */
#endif


    rcode = CKTtypelook("Resistor");
    vcode = CKTtypelook("Vsource");
    icode = CKTtypelook("Isource");
    if (!restart && job->TRCVnestState >= 0) {
        /* continuing */
        i = job->TRCVnestState;
        /* resume to work? saj*/
        error = SPfrontEnd->OUTpBeginPlot (NULL, NULL,
                                           NULL,
                                           NULL, 0,
                                           666, NULL, 666,
                                           &plot);
        goto resume;
    }
    ckt->CKTtime = 0;
    ckt->CKTdelta = job->TRCVvStep[0];
    ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCTRANCURVE | MODEINITJCT ;
    ckt->CKTorder=1;

    
    /* Save the state of the circuit */
    for(i=0;i<7;i++) {
        ckt->CKTdeltaOld[i]=ckt->CKTdelta;
    }
    
    for (i = 0; i <= job->TRCVnestLevel; i++) {
        if(rcode >= 0) {
            /* resistances are in this version, so use them */
            RESinstance *here;
            RESmodel *model;

            for(model = (RESmodel *)ckt->CKThead[rcode];model != NULL;
               model=model->RESnextModel){
                for(here=model->RESinstances;here!=NULL;
                   here=here->RESnextInstance) {
                    if (here->RESname == job->TRCVvName[i]) {
                        job->TRCVvElt[i]  = (GENinstance *)here;
                        job->TRCVvSave[i] = here->RESresist;
                        job->TRCVgSave[i] = here->RESresGiven;
                        job->TRCVvType[i] = rcode;
                        here->RESresist   = job->TRCVvStart[i];
                        here->RESresGiven = 1;
                        CKTtemp(ckt);
                        goto found;
                    }
                }
            }
        }
        if(vcode >= 0) {
            /* voltage sources are in this version, so use them */
            VSRCinstance *here;
            VSRCmodel *model;

            for(model = (VSRCmodel *)ckt->CKThead[vcode];model != NULL;
                    model=model->VSRCnextModel){
                for(here=model->VSRCinstances;here!=NULL;
                        here=here->VSRCnextInstance) {
                    if (here->VSRCname == job->TRCVvName[i]) {
                        job->TRCVvElt[i]  = (GENinstance *)here;
                        job->TRCVvSave[i] = here->VSRCdcValue;
                        job->TRCVgSave[i] = here->VSRCdcGiven;
                        job->TRCVvType[i] = vcode;
                        here->VSRCdcValue = job->TRCVvStart[i];
                        here->VSRCdcGiven = 1;
                        goto found;
                    }
                }
            }
        }
        if(icode >= 0 ) {
            /* current sources are in this version, so use them */
            ISRCinstance *here;
            ISRCmodel *model;

            for(model= (ISRCmodel *)ckt->CKThead[icode];model != NULL;
                    model=model->ISRCnextModel){
                for(here=model->ISRCinstances;here!=NULL;
                        here=here->ISRCnextInstance) {
                    if(here->ISRCname == job->TRCVvName[i]) {
                        job->TRCVvElt[i]  = (GENinstance *)here;
                        job->TRCVvSave[i] = here->ISRCdcValue;
                        job->TRCVgSave[i] = here->ISRCdcGiven;
                        job->TRCVvType[i] = icode;
                        here->ISRCdcValue = job->TRCVvStart[i];
                        here->ISRCdcGiven = 1;
                        goto found;
                    }
                }
            }
        }
   
        if (!strcmp(job->TRCVvName[i], "temp"))
        {
            job->TRCVvSave[i] = ckt->CKTtemp; /* Saves the old circuit temperature */
            job->TRCVvType[i] = TEMP_CODE;    /* Set the sweep type code */
            ckt->CKTtemp = job->TRCVvStart[i] + CONSTCtoK; /* Set the new circuit temp */
            CKTtemp(ckt);
            if (expr_w_temper)
                inp_evaluate_temper();
            goto found;
        }

        SPfrontEnd->IFerror (ERR_FATAL,
                "DCtrCurv: source / resistor %s not in circuit", &(job->TRCVvName[i]));
        return(E_NODEV);

found:;
    }

#ifdef HAS_PROGREP
    actval = job->TRCVvStart[job->TRCVnestLevel];
    actdiff = job->TRCVvStart[job->TRCVnestLevel] - job->TRCVvStop[job->TRCVnestLevel];
#endif

#ifdef XSPICE
/* gtri - add - wbk - 12/19/90 - Add IPC stuff and anal_init and anal_type */

    /* Tell the beginPlot routine what mode we're in */
    g_ipc.anal_type = IPC_ANAL_DCTRCURVE;

    /* Tell the code models what mode we're in */
    g_mif_info.circuit.anal_type = MIF_DC;

    g_mif_info.circuit.anal_init = MIF_TRUE;

/* gtri - end - wbk */
#endif

    i--; /* PN: This seems to do nothing ??? */ 
    
    error = CKTnames(ckt,&numNames,&nameList);
    if(error) return(error);
    
    
    if (job->TRCVvType[i] == vcode)
         SPfrontEnd->IFnewUid (ckt, &varUid, NULL, "v-sweep", UID_OTHER, NULL);
        
    else {
        if (job->TRCVvType[i] == icode)
            SPfrontEnd->IFnewUid (ckt, &varUid, NULL, "i-sweep", UID_OTHER, NULL);
                     
        else {
            if (job->TRCVvType[i] == TEMP_CODE)
                SPfrontEnd->IFnewUid (ckt, &varUid, NULL, "temp-sweep", UID_OTHER, NULL);
       
            else {
                if (job->TRCVvType[i] == rcode)
                    SPfrontEnd->IFnewUid (ckt, &varUid, NULL, "res-sweep", UID_OTHER, NULL);
                                
                else
                    SPfrontEnd->IFnewUid (ckt, &varUid, NULL, "?-sweep", UID_OTHER, NULL);
            } /* icode */
        } /* TEMP_CODE */
    } /* rcode*/
    
    error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
                                       ckt->CKTcurJob->JOBname,
                                       varUid, IF_REAL,
                                       numNames, nameList, IF_REAL,
                                       &plot);
    tfree(nameList);
    
    if(error) return(error);

    /* initialize CKTsoaCheck `warn' counters */
    if (ckt->CKTsoaCheck)
        error = CKTsoaInit();

    /* now have finished the initialization - can start doing hard part */
    
    i = 0;

resume:
    
    for(;;) {

        if (job->TRCVvType[i] == vcode) { /* voltage source */
            if((((VSRCinstance*)(job->TRCVvElt[i]))->VSRCdcValue) *
                  SIGN(1.0, job->TRCVvStep[i]) -
                  SIGN(1.0, job->TRCVvStep[i]) * job->TRCVvStop[i] >
                  DBL_EPSILON*1e+03)
            { 
                i++ ; 
                firstTime=1;
                ckt->CKTmode = (ckt->CKTmode & MODEUIC) | 
                        MODEDCTRANCURVE | MODEINITJCT ;
                if (i > job->TRCVnestLevel) break;
                goto nextstep;
            }
        } else if (job->TRCVvType[i] == icode) { /* current source */
            if((((ISRCinstance*)(job->TRCVvElt[i]))->ISRCdcValue) *
                    SIGN(1.0, job->TRCVvStep[i]) -
                    SIGN(1.0, job->TRCVvStep[i]) * job->TRCVvStop[i] >
                    DBL_EPSILON*1e+03)
            { 
                i++ ; 
                firstTime=1;
                ckt->CKTmode = (ckt->CKTmode & MODEUIC) | 
                       MODEDCTRANCURVE | MODEINITJCT ;
                if (i > job->TRCVnestLevel) break;
                goto nextstep;
            } 
      
        } else if (job->TRCVvType[i] == rcode) { /* resistance */
            if((((RESinstance*)(job->TRCVvElt[i]))->RESresist) *
                    SIGN(1.0, job->TRCVvStep[i]) -
                    SIGN(1.0, job->TRCVvStep[i]) * job->TRCVvStop[i]
                    > DBL_EPSILON*1e+03)
            { 
                i++ ; 
                firstTime=1;
                ckt->CKTmode = (ckt->CKTmode & MODEUIC) | 
                        MODEDCTRANCURVE | MODEINITJCT ;
                if (i > job->TRCVnestLevel) break;
                goto nextstep;
            } 
        } else if (job->TRCVvType[i] == TEMP_CODE) { /* temp sweep */
            if(((ckt->CKTtemp) - CONSTCtoK) * SIGN(1.0, job->TRCVvStep[i]) -
               SIGN(1.0, job->TRCVvStep[i]) * job->TRCVvStop[i] >
               DBL_EPSILON*1e+03)
            {
                i++ ;
                firstTime=1;
                ckt->CKTmode = (ckt->CKTmode & MODEUIC) |
                   MODEDCTRANCURVE | MODEINITJCT ;
                if (i > job->TRCVnestLevel) break;
                goto nextstep;
        
            }
      
        } /* else  not possible */
        while (i > 0) { 
            /* init(i); */
            i--; 
            if (job->TRCVvType[i] == vcode) { /* voltage source */
                ((VSRCinstance *)(job->TRCVvElt[i]))->VSRCdcValue =
                        job->TRCVvStart[i];
         
            } else if (job->TRCVvType[i] == icode) { /* current source */
                ((ISRCinstance *)(job->TRCVvElt[i]))->ISRCdcValue =
                        job->TRCVvStart[i];
         
            } else if (job->TRCVvType[i] == TEMP_CODE) {
                ckt->CKTtemp = job->TRCVvStart[i] + CONSTCtoK;
                CKTtemp(ckt); 
                if (expr_w_temper)
                    inp_evaluate_temper();
       
            } else if (job->TRCVvType[i] == rcode) {
                ((RESinstance *)(job->TRCVvElt[i]))->RESresist =
                        job->TRCVvStart[i];
                ((RESinstance *)(job->TRCVvElt[i]))->RESconduct =
                         1/(((RESinstance *)(job->TRCVvElt[i]))->RESresist);
                         /* Note: changing the resistance does nothing */
                         /* changing the conductance 1/r instead */
                DEVices[rcode]->DEVload(job->TRCVvElt[i]->GENmodPtr, ckt);
      
      /*
       * RESload(job->TRCVvElt[i]->GENmodPtr, ckt);
       */
        
        
            } /* else not possible */
        }

        /* Rotate state vectors. */
        temp = ckt->CKTstates[ckt->CKTmaxOrder+1];
        for(j=ckt->CKTmaxOrder;j>=0;j--) {
            ckt->CKTstates[j+1] = ckt->CKTstates[j];
        }
        ckt->CKTstate0 = temp;

        /* do operation */
#ifdef XSPICE
/* gtri - begin - wbk - Do EVTop if event instances exist */
        if(ckt->evt->counts.num_insts == 0) {
        /* If no event-driven instances, do what SPICE normally does */
#endif
            converged = NIiter(ckt,ckt->CKTdcTrcvMaxIter);
            if(converged != 0) {
                converged = CKTop(ckt,
                   (ckt->CKTmode&MODEUIC)|MODEDCTRANCURVE | MODEINITJCT,
                   (ckt->CKTmode&MODEUIC)|MODEDCTRANCURVE | MODEINITFLOAT,
                   ckt->CKTdcMaxIter);
                if(converged != 0) {
                    return(converged);
                }
            }
#ifdef XSPICE
        }
        else {
        /* else do new algorithm */

        /* first get the current step in the analysis */
            if (job->TRCVvType[0] == vcode) {
                g_mif_info.circuit.evt_step =
                    ((VSRCinstance *)(job->TRCVvElt[i]))->VSRCdcValue ;
            } else if (job->TRCVvType[0] == icode) {
                g_mif_info.circuit.evt_step =
                    ((ISRCinstance *)(job->TRCVvElt[i]))->ISRCdcValue ;
            } else if (job->TRCVvType[0] == rcode) {
                g_mif_info.circuit.evt_step =
                    ((RESinstance*)(job->TRCVvElt[i]->GENmodPtr))->RESresist;
            } else if (job->TRCVvType[0] == TEMP_CODE) {
                g_mif_info.circuit.evt_step =
                    ckt->CKTtemp - CONSTCtoK;
            }

            /* if first time through, call EVTop immediately and save event results */
            if(firstTime) {
                converged = EVTop(ckt,
                        (ckt->CKTmode & MODEUIC) | MODEDCTRANCURVE | MODEINITJCT,
                        (ckt->CKTmode & MODEUIC) | MODEDCTRANCURVE | MODEINITFLOAT,
                        ckt->CKTdcMaxIter,
                        MIF_TRUE);
                EVTdump(ckt, IPC_ANAL_DCOP, g_mif_info.circuit.evt_step);
                EVTop_save(ckt, MIF_FALSE, g_mif_info.circuit.evt_step);
                if(converged != 0)
                    return(converged);
            }
            /* else, call NIiter first with mode = MODEINITPRED */
            /* to attempt quick analog solution.  Then call all hybrids and call */
            /* EVTop only if event outputs have changed, or if non-converged */
            else {
                converged = NIiter(ckt,ckt->CKTdcTrcvMaxIter);
                EVTcall_hybrids(ckt);
                if((converged != 0) || (ckt->evt->queue.output.num_changed != 0)) {
                    converged = EVTop(ckt,
                            (ckt->CKTmode & MODEUIC) | MODEDCTRANCURVE | MODEINITJCT,
                            (ckt->CKTmode & MODEUIC) | MODEDCTRANCURVE | MODEINITFLOAT,
                            ckt->CKTdcMaxIter,
                            MIF_FALSE);
                    EVTdump(ckt, IPC_ANAL_DCTRCURVE, g_mif_info.circuit.evt_step);
                    EVTop_save(ckt, MIF_FALSE, g_mif_info.circuit.evt_step);
                    if(converged != 0)
                        return(converged);
                }
            }
        }
/* gtri - end - wbk - Do EVTop if event instances exist */
#endif

        ckt->CKTmode = (ckt->CKTmode&MODEUIC) | MODEDCTRANCURVE | MODEINITPRED ;
        if (job->TRCVvType[0] == vcode) {
            ckt->CKTtime = ((VSRCinstance *)(job->TRCVvElt[i]))->VSRCdcValue ;
        } else if (job->TRCVvType[0] == icode) {
            ckt->CKTtime = ((ISRCinstance *)(job->TRCVvElt[i]))->ISRCdcValue ;
        } else if (job->TRCVvType[0] == rcode) {
            ckt->CKTtime = ((RESinstance *)(job->TRCVvElt[i]))->RESresist;
        } 
        /* PN Temp sweep */
        else 
        {
            ckt->CKTtime = ckt->CKTtemp - CONSTCtoK ; 
        }

#ifdef XSPICE
/* gtri - add - wbk - 12/19/90 - Add IPC stuff */

        /* If first time through, call CKTdump to output Operating Point info */
        /* for Mspice compatibility */

        if(g_ipc.enabled && firstTime) {
            ipc_send_dcop_prefix();
            CKTdump(ckt, 0.0, plot);
            ipc_send_dcop_suffix();
        }

/* gtri - end - wbk */
#endif

#ifdef WANT_SENSE2
/*
        if(!ckt->CKTsenInfo) printf("sensitivity structure does not exist\n");
    */
        if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode&DCSEN) ){
       int senmode;

#ifdef SENSDEBUG
            if (job->TRCVvType[i] == vcode) { /* voltage source */
                printf("Voltage Source Value : %.5e V\n",
                        ((VSRCinstance*) (job->TRCVvElt[i]))->VSRCdcValue);
            }
            if (job->TRCVvType[i] == icode) { /* current source */
                printf("Current Source Value : %.5e A\n",
                        ((ISRCinstance*)(job->TRCVvElt[i]))->ISRCdcValue);
            }
       if (job->TRCVvType[i] == rcode) { /* resistance */
                printf("Current Resistance Value : %.5e Ohm\n",
                        ((RESinstance*)(job->TRCVvElt[i]->GENmodPtr))->RESresist);
            }
       if (job->TRCVvType[i] == TEMP_CODE) { /* Temperature */
                printf("Current Circuit Temperature : %.5e C\n",
                        ckt->CKTtemp - CONSTCtoK);
            }
       
#endif /* SENSDEBUG */

            senmode = ckt->CKTsenInfo->SENmode;
            save = ckt->CKTmode;
            ckt->CKTsenInfo->SENmode = DCSEN;
            error = CKTsenDCtran(ckt);
            if (error)
                return(error);

            ckt->CKTmode = save;
            ckt->CKTsenInfo->SENmode = senmode;

        }
#endif

#ifdef XSPICE
/* gtri - modify - wbk - 12/19/90 - Send IPC delimiters */

        if(g_ipc.enabled)
            ipc_send_data_prefix(ckt->CKTtime);
#endif

        CKTdump(ckt,ckt->CKTtime,plot);

        if (ckt->CKTsoaCheck)
            error = CKTsoaCheck(ckt);

#ifdef XSPICE
        if(g_ipc.enabled)
            ipc_send_data_suffix();

/* gtri - end - wbk */
#endif

        if(firstTime) {
            firstTime=0;
            bcopy(ckt->CKTstate0, ckt->CKTstate1,
                    (size_t) ckt->CKTnumStates * sizeof(double));
        }

nextstep:;

        if (job->TRCVvType[i] == vcode) { /* voltage source */
            ((VSRCinstance*)(job->TRCVvElt[i]))->VSRCdcValue +=
                    job->TRCVvStep[i];
        } else if (job->TRCVvType[i] == icode) { /* current source */
            ((ISRCinstance*)(job->TRCVvElt[i]))->ISRCdcValue +=
                    job->TRCVvStep[i];
        } else if (job->TRCVvType[i] == rcode) { /* resistance */
            ((RESinstance*)(job->TRCVvElt[i]))->RESresist +=
                    job->TRCVvStep[i];
            /* This code should update resistance and conductance */    
            ((RESinstance*)(job->TRCVvElt[i]))->RESconduct =
                1/(((RESinstance*)(job->TRCVvElt[i]))->RESresist);
            DEVices[rcode]->DEVload(job->TRCVvElt[i]->GENmodPtr, ckt);
            /*
        * RESload(job->TRCVvElt[i]->GENmodPtr, ckt);
        */ 
        }
        /* PN Temp Sweep - serban */
        else if (job->TRCVvType[i] == TEMP_CODE)
        {
            ckt->CKTtemp += job->TRCVvStep[i];
            CKTtemp(ckt);	    
            if (expr_w_temper)
                inp_evaluate_temper();
        } /* else not possible */
        
        if(SPfrontEnd->IFpauseTest()) {
            /* user asked us to pause, so save state */
            job->TRCVnestState = i;
            return(E_PAUSE);
        }
#ifdef HAS_PROGREP
        if (i == job->TRCVnestLevel) {
            actval += job->TRCVvStep[job->TRCVnestLevel];
            SetAnalyse( "dc", abs((int)(actval * 1000. / actdiff)));
        } 
#endif
    }

    /* all done, lets put everything back */

    for (i = 0; i <= job->TRCVnestLevel; i++) {
        if (job->TRCVvType[i] == vcode) {   /* voltage source */
            ((VSRCinstance*)(job->TRCVvElt[i]))->VSRCdcValue =
                    job->TRCVvSave[i];
            ((VSRCinstance*)(job->TRCVvElt[i]))->VSRCdcGiven = (job->TRCVgSave[i] != 0);
        } else  if (job->TRCVvType[i] == icode) /*current source */ {
            ((ISRCinstance*)(job->TRCVvElt[i]))->ISRCdcValue =
                    job->TRCVvSave[i];
            ((ISRCinstance*)(job->TRCVvElt[i]))->ISRCdcGiven = (job->TRCVgSave[i] != 0);
        } else  if (job->TRCVvType[i] == rcode) /* Resistance */ {
            ((RESinstance*)(job->TRCVvElt[i]))->RESresist =
                    job->TRCVvSave[i];
            /* We restore both resistance and conductance */
            ((RESinstance*)(job->TRCVvElt[i]))->RESconduct =
                1/(((RESinstance*)(job->TRCVvElt[i]))->RESresist);
       
            ((RESinstance*)(job->TRCVvElt[i]))->RESresGiven = (job->TRCVgSave[i] != 0);
            DEVices[rcode]->DEVload(job->TRCVvElt[i]->GENmodPtr, ckt);
       
       /*
        * RESload(job->TRCVvElt[i]->GENmodPtr, ckt);
        */ 
        }
        else if (job->TRCVvType[i] == TEMP_CODE) {
            ckt->CKTtemp = job->TRCVvSave[i];
            CKTtemp(ckt);
            if (expr_w_temper)
                inp_evaluate_temper();
        } /* else not possible */
    }
    SPfrontEnd->OUTendPlot (plot);

    return(OK);
}
示例#22
0
double ROOT_FIND(double x1, double x2, double (*func)(double), double tol){ 
    int iter;
    double a=x1,b=x2,c=x2,d,e,min1,min2;
    double fa=(*func)(a),fb=(*func)(b),fc,p,q,r,s,tol1,xm;
    
    if ((fa > 0.0 && fb > 0.0) || (fa < 0.0 && fb < 0.0))
	MATHERR("Root must be bracketed in ROOT_FIND", 00);
    fc=fb;
    for (iter=1;iter<=ITMAX;iter++){
	if ((fb > 0.0 && fc > 0.0) || (fb < 0.0 && fc < 0.0)){
	    c=a;
	    fc=fa;
	    e=d=b-a;
	}
	if (fabs(fc) < fabs(fb)) {
	    a=b;
	    b=c;
	    c=a;
	    fa=fb;
	    fb=fc;
	    fc=fa;
	}
	tol1=2.0*EPS*fabs(b)+0.5*tol;
	xm=0.5*(c-b);
	if (fabs(xm) <= tol1 || fb == 0.0) return b;
	if (fabs(e) >= tol1 && fabs(fa) > fabs(fb)) {
	    s=fb/fa;
	    if (a == c) {
		p=2.0*xm*s;
		q=1.0-s;
	    } else {
		q=fa/fc;
		r=fb/fc;
		p=s*(2.0*xm*q*(q-r)-(b-a)*(r-1.0));
		q=(q-1.0)*(r-1.0)*(s-1.0);
	    }
	    if (p > 0.0) q = -q;
	    p=fabs(p);
	    min1=3.0*xm*q-fabs(tol1*q);
	    min2=fabs(e*q);
	    if (2.0*p < (min1 < min2 ? min1 : min2)) {
		e=d;
		d=p/q;
	    } else {
		d=xm;
		e=d;
	    }
	} else {
	    d=xm;
	    e=d;
	}
	a=b;
	fa=fb;
	if (fabs(d) > tol1)
	    b += d;
	else
	    b += SIGN(tol1,xm);
	fb=(*func)(b);
    }
    MATHERR("Maximum number of iterations exceeded in zbrent", 00);
    return 0.0;
}
示例#23
0
int URKinematics::inverse(const double* T, double* q_sols, double q6_des) {
    int num_sols = 0;
    double T02 = -*T; T++; double T00 =  *T; T++; double T01 =  *T; T++; double T03 = -*T; T++;
    double T12 = -*T; T++; double T10 =  *T; T++; double T11 =  *T; T++; double T13 = -*T; T++;
    double T22 =  *T; T++; double T20 = -*T; T++; double T21 = -*T; T++; double T23 =  *T;
    
    ////////////////////////////// shoulder rotate joint (q1) //////////////////////////////
    double q1[2];
    {
        double A = d6*T12 - T13;
        double B = d6*T02 - T03;
        double R = A*A + B*B;
        if(fabs(A) < ZERO_THRESH) {
            double div;
            if(fabs(fabs(d4) - fabs(B)) < ZERO_THRESH)
                div = -SIGN(d4)*SIGN(B);
            else
                div = -d4/B;
            double arcsin = asin(div);
            if(fabs(arcsin) < ZERO_THRESH)
                arcsin = 0.0;
            if(arcsin < 0.0)
                q1[0] = arcsin + 2.0*PI;
            else
                q1[0] = arcsin;
            q1[1] = PI - arcsin;
        }
        else if(fabs(B) < ZERO_THRESH) {
            double div;
            if(fabs(fabs(d4) - fabs(A)) < ZERO_THRESH)
                div = SIGN(d4)*SIGN(A);
            else
                div = d4/A;
            double arccos = acos(div);
            q1[0] = arccos;
            q1[1] = 2.0*PI - arccos;
        }
        else if(d4*d4 > R) {
            return num_sols;
        }
        else {
            double arccos = acos(d4 / sqrt(R)) ;
            double arctan = atan2(-B, A);
            double pos = arccos + arctan;
            double neg = -arccos + arctan;
            if(fabs(pos) < ZERO_THRESH)
                pos = 0.0;
            if(fabs(neg) < ZERO_THRESH)
                neg = 0.0;
            if(neg >= 0.0)
                q1[1] = neg;
            else
                q1[1] = 2.0*PI + neg;
            if(pos >= 0.0)
                q1[0] = pos;
            else
                q1[0] = 2.0*PI + pos;

        }
    }
    ////////////////////////////////////////////////////////////////////////////////
    
    ////////////////////////////// wrist 2 joint (q5) //////////////////////////////
    double q5[2][2];
    {
        for(int i=0;i<2;i++) {
            double numer = (T03*sin(q1[i]) - T13*cos(q1[i])-d4);
            double div;
            if(fabs(fabs(numer) - fabs(d6)) < ZERO_THRESH)
                div = SIGN(numer) * SIGN(d6);
            else
                div = numer / d6;
            double arccos = acos(div);
            q5[i][0] = arccos;
            q5[i][1] = 2.0*PI - arccos;
        }
    }
    ////////////////////////////////////////////////////////////////////////////////
    
    {
        for(int i=0;i<2;i++) {
            for(int j=0;j<2;j++) {
                double c1 = cos(q1[i]), s1 = sin(q1[i]);
                double c5 = cos(q5[i][j]), s5 = sin(q5[i][j]);
                double q6;
                ////////////////////////////// wrist 3 joint (q6) //////////////////////////////
                if(fabs(s5) < ZERO_THRESH)
                    q6 = q6_des;
                else {
                    q6 = atan2(SIGN(s5)*-(T01*s1 - T11*c1),
                               SIGN(s5)*(T00*s1 - T10*c1));
                    if(fabs(q6) < ZERO_THRESH)
                        q6 = 0.0;
                    if(q6 < 0.0)
                        q6 += 2.0*PI;
                }
                ////////////////////////////////////////////////////////////////////////////////
                
                double q2[2], q3[2], q4[2];
                ///////////////////////////// RRR joints (q2,q3,q4) ////////////////////////////
                double c6 = cos(q6), s6 = sin(q6);
                double x04x = -s5*(T02*c1 + T12*s1) - c5*(s6*(T01*c1 + T11*s1) - c6*(T00*c1 + T10*s1));
                double x04y = c5*(T20*c6 - T21*s6) - T22*s5;
                double p13x = d5*(s6*(T00*c1 + T10*s1) + c6*(T01*c1 + T11*s1)) - d6*(T02*c1 + T12*s1) +
                T03*c1 + T13*s1;
                double p13y = T23 - d1 - d6*T22 + d5*(T21*c6 + T20*s6);
                
                double c3 = (p13x*p13x + p13y*p13y - a2*a2 - a3*a3) / (2.0*a2*a3);
                if(fabs(fabs(c3) - 1.0) < ZERO_THRESH)
                    c3 = SIGN(c3);
                else if(fabs(c3) > 1.0) {
                    // TODO NO SOLUTION
                    continue;
                }
                double arccos = acos(c3);
                q3[0] = arccos;
                q3[1] = 2.0*PI - arccos;
                double denom = a2*a2 + a3*a3 + 2*a2*a3*c3;
                double s3 = sin(arccos);
                double A = (a2 + a3*c3), B = a3*s3;
                q2[0] = atan2((A*p13y - B*p13x) / denom, (A*p13x + B*p13y) / denom);
                q2[1] = atan2((A*p13y + B*p13x) / denom, (A*p13x - B*p13y) / denom);
                double c23_0 = cos(q2[0]+q3[0]);
                double s23_0 = sin(q2[0]+q3[0]);
                double c23_1 = cos(q2[1]+q3[1]);
                double s23_1 = sin(q2[1]+q3[1]);
                q4[0] = atan2(c23_0*x04y - s23_0*x04x, x04x*c23_0 + x04y*s23_0);
                q4[1] = atan2(c23_1*x04y - s23_1*x04x, x04x*c23_1 + x04y*s23_1);
                ////////////////////////////////////////////////////////////////////////////////
                for(int k=0;k<2;k++) {
                    if(fabs(q2[k]) < ZERO_THRESH)
                        q2[k] = 0.0;
                    else if(q2[k] < 0.0) q2[k] += 2.0*PI;
                    if(fabs(q4[k]) < ZERO_THRESH)
                        q4[k] = 0.0;
                    else if(q4[k] < 0.0) q4[k] += 2.0*PI;
                    q_sols[num_sols*6+0] = q1[i];    q_sols[num_sols*6+1] = q2[k];
                    q_sols[num_sols*6+2] = q3[k];    q_sols[num_sols*6+3] = q4[k];
                    q_sols[num_sols*6+4] = q5[i][j]; q_sols[num_sols*6+5] = q6;
                    num_sols++;
                }
                
            }
        }
    }
    return num_sols;
}
示例#24
0
/*
 Given matrix a[m][n], m>=n, using svd decomposition a = p d q' to get
 p[m][n], diag d[n] and q[n][n].
*/
void svd(int m, int n, double **a, double **p, double *d, double **q)
{
        int             flag, i, its, j, jj, k, l, nm, nm1 = n - 1, mm1 = m - 1;
        double          c, f, h, s, x, y, z;
        double          anorm = 0, g = 0, scale = 0;
        //double         *r = tvector_alloc(0, n, double);
		double			*r = (double*)malloc(sizeof(double)*n);

        for (i = 0; i < m; i++)
                for (j = 0; j < n; j++)
                        p[i][j] = a[i][j];
        //for (i = m; i < n; i++)
        //                p[i][j] = 0;

        /* Householder reduction to bidigonal form */
        for (i = 0; i < n; i++)
        {
                l = i + 1;
                r[i] = scale * g;
                g = s = scale = 0.0;
                if (i < m)
                {
                        for (k = i; k < m; k++)
                                scale += fabs(p[k][i]);
                        if (scale)
                        {
                                for (k = i; k < m; k++)
                                {
                                        p[k][i] /= scale;
                                        s += p[k][i] * p[k][i];
                                }
                                f = p[i][i];
                                g = -SIGN(sqrt(s), f);
                                h = f * g - s;
                                p[i][i] = f - g;
                                if (i != nm1)
                                {
                                        for (j = l; j < n; j++)
                                        {
                                                for (s = 0.0, k = i; k < m; k++)
                                                        s += p[k][i] * p[k][j];
                                                f = s / h;
                                                for (k = i; k < m; k++)
                                                        p[k][j] += f * p[k][i];
                                        }
                                }
                                for (k = i; k < m; k++)
                                        p[k][i] *= scale;
                        }
                }
                d[i] = scale * g;
                g = s = scale = 0.0;
                if (i < m && i != nm1)
                {
                        for (k = l; k < n; k++)
                                scale += fabs(p[i][k]);
                        if (scale)
                        {
                                for (k = l; k < n; k++)
                                {
                                        p[i][k] /= scale;
                                        s += p[i][k] * p[i][k];
                                }
                                f = p[i][l];
                                g = -SIGN(sqrt(s), f);
                                h = f * g - s;
                                p[i][l] = f - g;
                                for (k = l; k < n; k++)
                                        r[k] = p[i][k] / h;
                                if (i != mm1)
                                {
                                        for (j = l; j < m; j++)
                                        {
                                                for (s = 0.0, k = l; k < n; k++)
                                                        s += p[j][k] * p[i][k];
                                                for (k = l; k < n; k++)
                                                        p[j][k] += s * r[k];
                                        }
                                }
                                for (k = l; k < n; k++)
                                        p[i][k] *= scale;
                        }
                }
                anorm = MAX(anorm, fabs(d[i]) + fabs(r[i]));
        }

        /* Accumulation of right-hand transformations */
        for (i = n - 1; i >= 0; i--)
        {
                if (i < nm1)
                {
                        if (g)
                        {
                                for (j = l; j < n; j++)
                                        q[j][i] = (p[i][j] / p[i][l]) / g;
                                for (j = l; j < n; j++)
                                {
                                        for (s = 0.0, k = l; k < n; k++)
                                                s += p[i][k] * q[k][j];
                                        for (k = l; k < n; k++)
                                                q[k][j] += s * q[k][i];
                                }
                        }
                        for (j = l; j < n; j++)
                                q[i][j] = q[j][i] = 0.0;
                }
                q[i][i] = 1.0;
                g = r[i];
                l = i;
        }
        /* Accumulation of left-hand transformations */
        for (i = n - 1; i >= 0; i--)
        {
                l = i + 1;
                g = d[i];
                if (i < nm1)
                        for (j = l; j < n; j++)
                                p[i][j] = 0.0;
                if (g)
                {
                        g = 1.0 / g;
                        if (i != nm1)
                        {
                                for (j = l; j < n; j++)
                                {
                                        for (s = 0.0, k = l; k < m; k++)
                                                s += p[k][i] * p[k][j];
                                        f = (s / p[i][i]) * g;
                                        for (k = i; k < m; k++)
                                                p[k][j] += f * p[k][i];
                                }
                        }
                        for (j = i; j < m; j++)
                                p[j][i] *= g;
                } else
                        for (j = i; j < m; j++)
                                p[j][i] = 0.0;
                ++p[i][i];
        }
        /* diagonalization of the bidigonal form */
        for (k = n - 1; k >= 0; k--)
        {                       /* loop over singlar values */
                for (its = 0; its < 30; its++)
                {               /* loop over allowed iterations */
                        flag = 1;
                        for (l = k; l >= 0; l--)
                        {       /* test for splitting */
                                nm = l - 1;     /* note that r[l] is always
                                                 * zero */
                                if (fabs(r[l]) + anorm == anorm)
                                {
                                        flag = 0;
                                        break;
                                }
                                if (fabs(d[nm]) + anorm == anorm)
                                        break;
                        }
                        if (flag)
                        {
                                c = 0.0;        /* cancellation of r[l], if
                                                 * l>1 */
                                s = 1.0;
                                for (i = l; i <= k; i++)
                                {
                                        f = s * r[i];
                                        if (fabs(f) + anorm != anorm)
                                        {
                                                g = d[i];
                                                h = radius(f, g);
                                                d[i] = h;
                                                h = 1.0 / h;
                                                c = g * h;
                                                s = (-f * h);
                                                for (j = 0; j < m; j++)
                                                {
                                                        y = p[j][nm];
                                                        z = p[j][i];
                                                        p[j][nm] = y * c + z * s;
                                                        p[j][i] = z * c - y * s;
                                                }
                                        }
                                }
                        }
                        z = d[k];
                        if (l == k)
                        {       /* convergence */
                                if (z < 0.0)
                                {
                                        d[k] = -z;
                                        for (j = 0; j < n; j++)
                                                q[j][k] = (-q[j][k]);
                                }
                                break;
                        }
                        if (its == 30)
                        {
                                //error("svd: No convergence in 30 svd iterations", non_fatal);
                                return;
                        }
                        x = d[l];       /* shift from bottom 2-by-2 minor */
                        nm = k - 1;
                        y = d[nm];
                        g = r[nm];
                        h = r[k];
                        f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y);
                        g = radius(f, 1.0);
                        /* next QR transformation */
                        f = ((x - z) * (x + z) + h * ((y / (f + SIGN(g, f))) - h)) / x;
                        c = s = 1.0;
                        for (j = l; j <= nm; j++)
                        {
                                i = j + 1;
                                g = r[i];
                                y = d[i];
                                h = s * g;
                                g = c * g;
                                z = radius(f, h);
                                r[j] = z;
                                c = f / z;
                                s = h / z;
                                f = x * c + g * s;
                                g = g * c - x * s;
                                h = y * s;
                                y = y * c;
                                for (jj = 0; jj < n; jj++)
                                {
                                        x = q[jj][j];
                                        z = q[jj][i];
                                        q[jj][j] = x * c + z * s;
                                        q[jj][i] = z * c - x * s;
                                }
                                z = radius(f, h);
                                d[j] = z;       /* rotation can be arbitrary
                                                 * id z=0 */
                                if (z)
                                {
                                        z = 1.0 / z;
                                        c = f * z;
                                        s = h * z;
                                }
                                f = (c * g) + (s * y);
                                x = (c * y) - (s * g);
                                for (jj = 0; jj < m; jj++)
                                {
                                        y = p[jj][j];
                                        z = p[jj][i];
                                        p[jj][j] = y * c + z * s;
                                        p[jj][i] = z * c - y * s;
                                }
                        }
                        r[l] = 0.0;
                        r[k] = f;
                        d[k] = x;
                }
        }
        free(r);

		// dhli add: the original code does not sort the eigen value
		// should do that and change the eigen vector accordingly

}
示例#25
0
int32_t svdcmp_c(int32_t m, double* a, double* w, double* v) {
  // C port of PLINK stats.cpp svdcmp().
  // Note that this function is NOT thread-safe, due to the buffer allocated
  // from the workspace stack.  Pass in a preallocated buffer if that's not
  // okay.
  unsigned char* bigstack_mark = g_bigstack_base;
  int32_t n = m;
  int32_t flag;
  int32_t l = 0; // suppress compile warning
  int32_t i,its,j,jj,k,nm;
  double anorm,c,f,g,h,s,scale,x,y,z;
  double volatile temp;
  double* rv1;
  if (bigstack_alloc_d(m, &rv1)) {
    return -1;
  }

  g=scale=anorm=0.0;
  for (i=0;i<n;i++) {
    l=i+2;
    rv1[i]=scale*g;
    g=s=scale=0.0;
    if (i < m) {
      for (k=i;k<m;k++) scale += fabs(a[k * m + i]);
      if (scale != 0.0) {
	for (k=i;k<m;k++) {
	  a[k * m + i] /= scale;
	  s += a[k * m + i]*a[k * m + i];
	}
	f=a[i * m + i];
	g = -SIGN(sqrt(s),f);
	h=f*g-s;
	a[i * m + i]=f-g;
	for (j=l-1;j<n;j++) {
	  for (s=0.0,k=i;k<m;k++) s += a[k * m + i]*a[k * m + j];
	  f=s/h;
	  for (k=i;k<m;k++) a[k * m + j] += f*a[k * m + i];
	}
	for (k=i;k<m;k++) a[k * m + i] *= scale;
      }
    }
    w[i]=scale *g;
    g=s=scale=0.0;
    if (i+1 <= m && i+1 != n) {
      for (k=l-1;k<n;k++) scale += fabs(a[i * m + k]);
      if (scale != 0.0) {
	for (k=l-1;k<n;k++) {
	  a[i * m + k] /= scale;
	  s += a[i * m + k]*a[i * m + k];
	}
	f=a[i * m + l-1];
	g = -SIGN(sqrt(s),f);
	h=f*g-s;
	a[i * m + l-1]=f-g;
	for (k=l-1;k<n;k++) rv1[k]=a[i * m + k]/h;
	for (j=l-1;j<m;j++) {
	  for (s=0.0,k=l-1;k<n;k++) s += a[j * m + k]*a[i * m + k];
	  for (k=l-1;k<n;k++) a[j * m + k] += s*rv1[k];
	}
	for (k=l-1;k<n;k++) a[i * m + k] *= scale;
      }
    }
    anorm=MAXV(anorm,(fabs(w[i])+fabs(rv1[i])));
  }
  for (i=n-1;i>=0;i--) {
    if (i < n-1) {
      if (g != 0.0) {
	for (j=l;j<n;j++)
	  v[j * m + i]=(a[i * m + j]/a[i * m + l])/g;
	for (j=l;j<n;j++) {
	  for (s=0.0,k=l;k<n;k++) s += a[i * m + k]*v[k * m + j];
	  for (k=l;k<n;k++) v[k * m + j] += s*v[k * m + i];
	}
      }
      for (j=l;j<n;j++) v[i * m + j]=v[j * m + i]=0.0;
    }
    v[i * m + i]=1.0;
    g=rv1[i];
    l=i;
  }
  for (i=MINV(m,n)-1;i>=0;i--) {
    l=i+1;
    g=w[i];
    for (j=l;j<n;j++) a[i * m + j]=0.0;
    if (g != 0.0) {
      g=1.0/g;
      for (j=l;j<n;j++) {
	for (s=0.0,k=l;k<m;k++) s += a[k * m + i]*a[k * m + j];
	f=(s/a[i * m + i])*g;
	for (k=i;k<m;k++) a[k * m + j] += f*a[k * m + i];
      }
      for (j=i;j<m;j++) a[j * m + i] *= g;
    } else for (j=i;j<m;j++) a[j * m + i]=0.0;
    ++a[i * m + i];
  }
  for (k=n-1;k>=0;k--) {
    for (its=0;its<30;its++) {
      flag=1;
      for (l=k;l>=0;l--) {
	nm=l-1;
	temp=fabs(rv1[l])+anorm;
	if (temp == anorm) {
	  flag=0;
	  break;
	}
	temp=fabs(w[nm])+anorm;
	if (temp == anorm) break;
      }
      if (flag) {
	c=0.0;
	s=1.0;
	for (i=l;i<k+1;i++) {
	  f=s*rv1[i];
	  rv1[i]=c*rv1[i];
	  temp = fabs(f)+anorm;
	  if (temp == anorm) break;
	  g=w[i];
	  h=pythag(f,g);
	  w[i]=h;
	  h=1.0/h;
	  c=g*h;
	  s = -f*h;
	  for (j=0;j<m;j++) {
	    y=a[j * m + nm];
	    z=a[j * m + i];
	    a[j * m + nm]=y*c+z*s;
	    a[j * m + i]=z*c-y*s;
	  }
	}
      }
      z=w[k];
      if (l == k) {
	if (z < 0.0) {
	  w[k] = -z;
	  for (j=0;j<n;j++) v[j * m + k] = -v[j * m + k];
	}
	break;
      }
      if (its == 29) 
	return 0; // cannot converge: multi-collinearity?
      x=w[l];
      nm=k-1;
      y=w[nm];
      g=rv1[nm];
      h=rv1[k];
      f=((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y);
      g=pythag(f,1.0);
      f=((x-z)*(x+z)+h*((y/(f+SIGN(g,f)))-h))/x;
      c=s=1.0;
      for (j=l;j<=nm;j++) {
	i=j+1;
	g=rv1[i];
	y=w[i];
	h=s*g;
	g=c*g;
	z=pythag(f,h);
	rv1[j]=z;
	c=f/z;
	s=h/z;
	f=x*c+g*s;
	g=g*c-x*s;
	h=y*s;
	y *= c;
	for (jj=0;jj<n;jj++) {
	  x=v[jj * m + j];
	  z=v[jj * m + i];
	  v[jj * m + j]=x*c+z*s;
	  v[jj * m + i]=z*c-x*s;
	}
	z=pythag(f,h);
	w[j]=z;
	if (z) {
	  z=1.0/z;
	  c=f*z;
	  s=h*z;
	}
	f=c*g+s*y;
	x=c*y-s*g;
	for (jj=0;jj<m;jj++) {
	  y=a[jj * m + j];
	  z=a[jj * m + i];
	  a[jj * m + j]=y*c+z*s;
	  a[jj * m + i]=z*c-y*s;
	}
      }
      rv1[l]=0.0;
      rv1[k]=f;
      w[k]=x;
    }
  }
  bigstack_reset(bigstack_mark);
  return 1;
}
示例#26
0
/* Coefficients :  x^4 + C[0] x^3  + C[1] x^2 + C[2] x  + C[3] */
size_t quarticRoots( 
	double a, double b, double c, double d, double roots[4] )
{
	double h,h1,h2,H,   g,g1,g2,G, n, m, en, em, y;
	double cubic[3];	/* Cubic and quadratic coefficients */
	int i, nr;

	/* Find the a real root of a certain cubic */
	cubic[0] = -2.0*b;
	cubic[1] = b*b + a*c - 4*d;
	cubic[2] = c*c - a*b*c + a*a*d;
	nr = cubicRoots( cubic[0], cubic[1], cubic[2], roots );

	if( nr == 1 ) {
		y = PolishRoot( 3, cubic[0], cubic[1], cubic[2], 0.0, roots[0] );
	} else {
		if( b < 0 && d < 0 ) {
			y = PolishRoot( 3, cubic[0], cubic[1], cubic[2], 0.0, roots[2] );
		} else {
			y = PolishRoot( 3, cubic[0], cubic[1], cubic[2], 0.0, roots[0] );
		}
	}

	g1 = a/2.0;
	h1 = (b-y)/2.0;
	if( y < 0 ) {
		n = a*a - 4*y;
		if( n <= 0 ) {
			return 0;
		}
		g2 = sqrt(n);
		if( g2 == 0 ) {
			return 0;
		}
		h2 = (a*((b-y)/2.0) - c) / g2;
		g2 /= 2.0;
	} else if( y > 0 && d > 0 && b < 0 ) {
		m = (b-y)*(b-y) - 4*d;
		if( m <= 0 ) {
			return 0;
		}
		h2 = sqrt(m);
		if( h2 == 0 ) {
			return 0;
		}
		g2 = (a*h1 - c) / h2;
		h2 /= 2.0;
	} else {
		n = a*a - 4*y;
		m = (b-y)*(b-y) - 4*d;
		en = b*b + 2.*fabs(b*y) + y*y + 4*fabs(d);
		em = a*a + 4.*fabs(y);
		if( m*en > n*em ) {		/* use m */
			if( m <= 0 ) { 
				return 0; 
			}
			h2 = sqrt(m);
			if( h2 == 0 ) { 
				return 0; 
			}
			g2 = (a*h1 - c) / h2;
			h2 /= 2.0;
		} else {			/* use n */
			if (n <= 0) {
				return 0;
			}
			g2 = sqrt(n);
			if (g2 == 0) { 
				return 0; 
			}
			h2 = (a*( (b-y)/2.0) - c) / g2;
			g2 /= 2.0;
		}
	}

	if( SIGN(g1) == SIGN(g2) ) {
		G = g1 + g2;
		g = (G==0) ? g1-g2  : y/G;
	} else {
		g = g1 - g2;
		G = (g == 0) ?  g1+g2 : y/g;
	}
	if( SIGN(h1) == SIGN(h2) ) {
		H = h1+h2;
		h = (H == 0) ? h1-h2  : d/H;
	} else {
		h = h1 - h2;
		H = (h == 0) ? h1+h2  : d/h;
	}

	nr = quadraticRoots( 1.0, G, H, roots );
	nr += quadraticRoots( 1.0, g, h, roots+nr );

	for( i=0; i < nr; ++i ) {
		roots[i] = PolishRoot( 4, a, b, c, d, roots[i] );
	}

	/* remove non-roots */
	//      fprintf(stderr,"REMOVE NONROOTS %d\n",nr);
	for ( i=0; i < nr; i++ ) {
		double r;
		r = (((roots[i]+a)*roots[i]+b)*roots[i]+c)*roots[i]+d;
		//              fprintf(stderr,"root %d is %g\n",i,r);
		if ( fabs(r)>1e-4 ) {
			roots[i] = roots[nr-1];
			nr--; i--;
		}
	}

	return nr;
}
示例#27
0
int svdcmp( double **a, int m,int n, double *w,double **v)
{
    int flag,i,its,j,jj,k,ii=0,nm=0;
    SVD_FLOAT c,f,h,s,x,y,z;
    SVD_FLOAT anorm=0.0,g=0.0,scale=0.0;

    if (m < n) return -1;	// must augment A with extra zero rows

	assert(n==3);
	SVD_FLOAT rv1[3];		// was: rv1=G_alloc_vector(n);

    n--;
    m--;

    for (i=0;i<=n;i++) {
        ii=i+1;
        rv1[i]=scale*g;
        g=s=scale=0.0;
        if (i <= m) {
            for (k=i;k<=m;k++) scale += (SVD_FLOAT)fabs(a[k][i]);
            if (scale) {
                for (k=i;k<=m;k++) {
                    a[k][i] /= (SVD_FLOAT)(scale);
                    s += a[k][i]*a[k][i];
                }
                f=a[i][i];
                g = -SIGN(sqrt(s),f);
                h=f*g-s;
                a[i][i]=(SVD_FLOAT)(f-g);
                if (i != n) {
                    for (j=ii;j<=n;j++) {
                        for (s=0.0,k=i;k<=m;k++) s += a[k][i]*a[k][j];
                        f=s/h;
                        for (k=i;k<=m;k++) a[k][j] += (SVD_FLOAT)(f)*a[k][i];
                    }
                }
                for (k=i;k<=m;k++) a[k][i] *= (SVD_FLOAT)(scale);
            }
        }
        w[i]=scale*g;
        g=s=scale=0.0;
        if (i <= m && i != n) {
            for (k=ii;k<=n;k++) scale += fabs(a[i][k]);
            if (scale) {
                for (k=ii;k<=n;k++) {
                    a[i][k] /= scale;
                    s += a[i][k]*a[i][k];
                }
                f=a[i][ii];
                g = -SIGN(sqrt(s),f);
                h=f*g-s;
                a[i][ii]=f-g;
                for (k=ii;k<=n;k++) rv1[k]=a[i][k]/h;
                if (i != m) {
                    for (j=ii;j<=m;j++) {
                        for (s=0.0,k=ii;k<=n;k++) s += a[j][k]*a[i][k];
                        for (k=ii;k<=n;k++) a[j][k] += s*rv1[k];
                    }
                }
                for (k=ii;k<=n;k++) a[i][k] *= scale;
            }
        }
        anorm=MAX(anorm,(fabs(w[i])+fabs(rv1[i])));
    }
    for (i=n;i>=0;i--) {
        if (i < n) {
            if (g) {
                for (j=ii;j<=n;j++)
                    v[j][i]=(a[i][j]/a[i][ii])/g;
                for (j=ii;j<=n;j++) {
                    for (s=0.0,k=ii;k<=n;k++) s += a[i][k]*v[k][j];
                    for (k=ii;k<=n;k++) v[k][j] += s*v[k][i];
                }
            }
            for (j=ii;j<=n;j++) v[i][j]=v[j][i]=0.0;
        }
        v[i][i]=1.0;
        g=rv1[i];
        ii=i;
    }
    for (i=n;i>=0;i--) {
        ii=i+1;
        g=w[i];
        if (i < n)
            for (j=ii;j<=n;j++) a[i][j]=0.0;
        if (g) {
            g=SVD_FLOAT(1.0)/g;
            if (i != n) {
                for (j=ii;j<=n;j++) {
                    for (s=0.0,k=ii;k<=m;k++) s += a[k][i]*a[k][j];
                    f=(s/a[i][i])*g;
                    for (k=i;k<=m;k++) a[k][j] += f*a[k][i];
                }
            }
            for (j=i;j<=m;j++) a[j][i] *= g;
        } else {
            for (j=i;j<=m;j++) a[j][i]=0.0;
        }
        ++a[i][i];
    }
    for (k=n;k>=0;k--) {
        for (its=1;its<=30;its++) {
            flag=1;
            for (ii=k;ii>=0;ii--) {
                nm=ii-1;
                if (fabs(rv1[ii])+anorm == anorm) {
                    flag=0;
                    break;
                }
                if (fabs(w[nm])+anorm == anorm) break;
            }
            if (flag) {
                c=0.0;
                s=1.0;
                for (i=ii;i<=k;i++) {
                    f=s*rv1[i];
                    if (fabs(f)+anorm != anorm) {
                        g=w[i];
                        h=PYTHAG(f,g);
                        w[i]=h;
                        h=SVD_FLOAT(1.0)/h;
                        c=g*h;
                        s=(-f*h);
                        for (j=0;j<=m;j++) {
                            y=a[j][nm];
                            z=a[j][i];
                            a[j][nm]=y*c+z*s;
                            a[j][i]=z*c-y*s;
                        }
                    }
                }
            }
            z=w[k];
            if (ii == k) {
                if (z < 0.0) {
                    w[k] = -z;
                    for (j=0;j<=n;j++) v[j][k]=(-v[j][k]);
                }
                break;
            }
            if (its == 30) return -2; /*No convergence in 30 SVDCMP iterations*/
            x=w[ii];
            nm=k-1;
            y=w[nm];
            g=rv1[nm];
            h=rv1[k];
            f=((y-z)*(y+z)+(g-h)*(g+h))/(SVD_FLOAT(2.0)*h*y);
            g=PYTHAG(f,SVD_FLOAT(1.0));
            f=((x-z)*(x+z)+h*((y/(f+SIGN(g,f)))-h))/x;
            c=s=SVD_FLOAT(1.0);
            for (j=ii;j<=nm;j++) {
                i=j+1;
                g=rv1[i];
                y=w[i];
                h=s*g;
                g=c*g;
                z=PYTHAG(f,h);
                rv1[j]=z;
                c=f/z;
                s=h/z;
                f=x*c+g*s;
                g=g*c-x*s;
                h=y*s;
                y=y*c;
                for (jj=0;jj<=n;jj++) {
                    x=v[jj][j];
                    z=v[jj][i];
                    v[jj][j]=x*c+z*s;
                    v[jj][i]=z*c-x*s;
                }
                z=PYTHAG(f,h);
                w[j]=z;
                if (z) {
                    z=SVD_FLOAT(1.0)/z;
                    c=f*z;
                    s=h*z;
                }
                f=(c*g)+(s*y);
                x=(c*y)-(s*g);
                for (jj=0;jj<=m;jj++) {
                    y=a[jj][j];
                    z=a[jj][i];
                    a[jj][j]=y*c+z*s;
                    a[jj][i]=z*c-y*s;
                }
            }
            rv1[ii]=SVD_FLOAT(0.0);
            rv1[k]=f;
            w[k]=x;
        }
    }

    //G_free_vector(rv1);		// no longer used, rv1 is now on stack

    return 0;
}
示例#28
0
Real NewtonSolver::line_search(Real tol,
                               Real last_residual,
                               Real &current_residual,
                               NumericVector<Number> &newton_iterate,
                               const NumericVector<Number> &linear_solution)
{
  // Take a full step if we got a residual reduction or if we
  // aren't substepping
  if ((current_residual < last_residual) ||
      (!require_residual_reduction &&
       (!require_finite_residual || !libmesh_isnan(current_residual))))
    return 1.;

  // The residual vector
  NumericVector<Number> &rhs = *(_system.rhs);

  Real ax = 0.;  // First abscissa, don't take negative steps
  Real cx = 1.;  // Second abscissa, don't extrapolate steps

  // Find bx, a step length that gives lower residual than ax or cx
  Real bx = 1.;

  while (libmesh_isnan(current_residual) ||
         (current_residual > last_residual &&
          require_residual_reduction))
    {
      // Reduce step size to 1/2, 1/4, etc.
      Real substepdivision;
      if (brent_line_search && !libmesh_isnan(current_residual))
        {
          substepdivision = std::min(0.5, last_residual/current_residual);
          substepdivision = std::max(substepdivision, tol*2.);
        }
      else
        substepdivision = 0.5;

      newton_iterate.add (bx * (1.-substepdivision),
                          linear_solution);
      newton_iterate.close();
      bx *= substepdivision;
      if (verbose)
        libMesh::out << "  Shrinking Newton step to "
                  << bx << std::endl;

      // Check residual with fractional Newton step
      _system.assembly (true, false);

      rhs.close();
      current_residual = rhs.l2_norm();
      if (verbose)
        libMesh::out << "  Current Residual: "
                  << current_residual << std::endl;

      if (bx/2. < minsteplength &&
          (libmesh_isnan(current_residual) ||
           (current_residual > last_residual)))
        {
          libMesh::out << "Inexact Newton step FAILED at step "
                    << _outer_iterations << std::endl;

          if (!continue_after_backtrack_failure)
            {
              libmesh_convergence_failure();
            }
          else
            {
              libMesh::out << "Continuing anyway ..." << std::endl;
              _solve_result = DiffSolver::DIVERGED_BACKTRACKING_FAILURE;
              return bx;
            }
        }
    } // end while (current_residual > last_residual)

  // Now return that reduced-residual step, or  use Brent's method to
  // find a more optimal step.

  if (!brent_line_search)
    return bx;

  // Brent's method adapted from Numerical Recipes in C, ch. 10.2
  Real e = 0.;

  Real x = bx, w = bx, v = bx;

  // Residuals at bx
  Real fx = current_residual,
       fw = current_residual,
       fv = current_residual;

  // Max iterations for Brent's method loop
  const unsigned int max_i = 20;

  // for golden ratio steps
  const Real golden_ratio = 1.-(std::sqrt(5.)-1.)/2.;

  for (unsigned int i=1; i <= max_i; i++)
    {
      Real xm = (ax+cx)*0.5;
      Real tol1 = tol * std::abs(x) + tol*tol;
      Real tol2 = 2.0 * tol1;

      // Test if we're done
      if (std::abs(x-xm) <= (tol2 - 0.5 * (cx - ax)))
        return x;

      Real d;

      // Construct a parabolic fit
      if (std::abs(e) > tol1)
        {
          Real r = (x-w)*(fx-fv);
          Real q = (x-v)*(fx-fw);
          Real p = (x-v)*q-(x-w)*r;
          q = 2. * (q-r);
          if (q > 0.)
            p = -p;
          else
            q = std::abs(q);
          if (std::abs(p) >= std::abs(0.5*q*e) ||
              p <= q * (ax-x) ||
              p >= q * (cx-x))
            {
              // Take a golden section step
              e = x >= xm ? ax-x : cx-x;
              d = golden_ratio * e;
            }
          else
            {
              // Take a parabolic fit step
              d = p/q;
              if (x+d-ax < tol2 || cx-(x+d) < tol2)
                d = SIGN(tol1, xm - x);
            }
        }
      else
        {
          // Take a golden section step
          e = x >= xm ? ax-x : cx-x;
          d = golden_ratio * e;
        }

      Real u = std::abs(d) >= tol1 ? x+d : x + SIGN(tol1,d);

      // Assemble the residual at the new steplength u
      newton_iterate.add (bx - u, linear_solution);
      newton_iterate.close();
      bx = u;
      if (verbose)
        libMesh::out << "  Shrinking Newton step to "
                      << bx << std::endl;

      _system.assembly (true, false);

      rhs.close();
      Real fu = current_residual = rhs.l2_norm();
      if (verbose)
        libMesh::out << "  Current Residual: "
                      << fu << std::endl;

      if (fu <= fx)
        {
          if (u >= x)
            ax = x;
          else
            cx = x;
          v = w;   w = x;   x = u;
          fv = fw; fw = fx; fx = fu;
        }
      else
        {
          if (u < x)
            ax = u;
          else
            cx = u;
          if (fu <= fw || w == x)
            {
              v = w;   w = u;
              fv = fw; fw = fu;
            }
          else if (fu <= fv || v == x || v == w)
            {
              v = u;
              fv = fu;
            }
        }
    }

  if (!quiet)
    libMesh::out << "Warning!  Too many iterations used in Brent line search!"
                 << std::endl;
  return bx;
}
示例#29
0
int dbt_cmp_val(dbt_val_p _vp, db_val_t* _v)
{
	int _l, _n;
	if(!_vp && !_v)
		return 0;
	if(!_v)
		return 1;
	if(!_vp)
		return -1;
	if(_vp->nul && _v->nul)
		return 0;
	if(_v->nul)
		return 1;
	if(_vp->nul)
		return -1;
	
	switch(VAL_TYPE(_v))
	{
		case DB1_INT:
			return (_vp->val.int_val<_v->val.int_val)?-1:
					(_vp->val.int_val>_v->val.int_val)?1:0;

		case DB1_BIGINT:
			LM_ERR("BIGINT not supported\n");
			return -1;

		case DB1_DOUBLE:
			return (_vp->val.double_val<_v->val.double_val)?-1:
					(_vp->val.double_val>_v->val.double_val)?1:0;
		case DB1_DATETIME:
			return (_vp->val.int_val<_v->val.time_val)?-1:
					(_vp->val.int_val>_v->val.time_val)?1:0;
		case DB1_STRING:
			_l = strlen(_v->val.string_val);
			_l = (_l>_vp->val.str_val.len)?_vp->val.str_val.len:_l;
			_n = strncasecmp(_vp->val.str_val.s, _v->val.string_val, _l);
			if(_n)
				return SIGN(_n);
			if(_vp->val.str_val.len == strlen(_v->val.string_val))
				return 0;
			if(_l==_vp->val.str_val.len)
				return -1;
			return 1;
		case DB1_STR:
			_l = _v->val.str_val.len;
			_l = (_l>_vp->val.str_val.len)?_vp->val.str_val.len:_l;
			_n = strncasecmp(_vp->val.str_val.s, _v->val.str_val.s, _l);
			if(_n)
				return SIGN(_n);
			if(_vp->val.str_val.len == _v->val.str_val.len)
				return 0;
			if(_l==_vp->val.str_val.len)
				return -1;
			return 1;
		case DB1_BLOB:
			_l = _v->val.blob_val.len;
			_l = (_l>_vp->val.str_val.len)?_vp->val.str_val.len:_l;
			_n = strncasecmp(_vp->val.str_val.s, _v->val.blob_val.s, _l);
			if(_n)
				return SIGN(_n);
			if(_vp->val.str_val.len == _v->val.blob_val.len)
				return 0;
			if(_l==_vp->val.str_val.len)
				return -1;
			return 1;
		case DB1_BITMAP:
			return (_vp->val.int_val<_v->val.bitmap_val)?-1:
				(_vp->val.int_val>_v->val.bitmap_val)?1:0;
		default:
			LM_ERR("invalid datatype %d\n", VAL_TYPE(_v));
			return -2;
	}
	return -2;
}
示例#30
0
void draw_line( int x1, int y1, int x2, int y2, char value ) {
#if 0
	if ( x1 == x2 ) {
		//Draw vertical line
		unsigned char i;
		for ( i = y1; i <= y2; i++ ) {
			draw_char( x1, i, value );
		}
	}
	else if ( y1 == y2 ) {
		//Draw horizontal line
		unsigned char i;
		for ( i = x1; i <= x2; i++ ) {
			draw_char( i, y1, value );
		}
	}
	else {
		// Figure out octant
		unsigned int oct;
		float g = ( (float)y2 - y1 ) / ( (float)x2 - x1 );

		if ( x2 > x1 ) {
			if ( g > 1 ) {
				oct = 1;
			}
			else if ( g <= 1 && g > 0 ) {
				oct = 0;
			}
			else if ( g <= 0 && g > -1 ) {
				oct = 7;
			}
			else {
				oct = 6;
			}
		}
		else {
			if ( g > 1 ) {
				oct = 5;
			}
			else if ( g <= 1 && g > 0 ) {
				oct = 4;
			}
			else if ( g <= 0 && g > -1 ) {
				oct = 3;
			}
			else {
				oct = 2;
			}
		}

		// Translate octants to settings
		unsigned int useX;
		switch ( oct ) {
		case 0:
		case 3:
		case 4:
		case 7:
			useX = 1;
			break;
		case 1:
		case 2:
		case 5:
		case 6:
			useX = 0;
			break;

		}

		unsigned int i1, i, i2, c;
		float dx = (float)x2 - x1, dy = (float)y2 - y1, m;

		if ( useX ) {
			m = dy / dx;
			c = y1; i1 = x1; i2 = x2;
		}
		else {
			m = dx / dy;
			c = x1; i1 = y1; i2 = y2;
		}

		int flipM;

		switch ( oct ) {
		case 0:
		case 1:
		case 2:
		case 7:
			flipM = 1;
			break;
		case 3:
		case 4:
		case 5:
		case 6:
			flipM = -1;
			break;
		}

		// Perform the actual loop
		float err = 0.0;

		for ( i = i1; ( i2 > i1 ) ? i <= i2 : i >= i2; ( i2 > i1 ) ? i++ : i-- ) {
			( useX ) ? draw_char( i, c, value ) : draw_char( c, i, value );
			err += ABS( m );

			if ( err > 0.5f ) {
				( SIGN( m*flipM ) > 0 ) ? c++ : c--;
				err -= 1.0f;
			}
		}
	}
#else
	if ( x1 == x2 ) {
		// Draw vertical line
		for ( int i = y1; ( y2 > y1 ) ? i <= y2 : i >= y2; ( y2 > y1 ) ? i++ : i-- ) {
			draw_char( x1, i, value );
		}
	}
	else if ( y1 == y2 ) {
		// Draw horizontal line
		for ( int i = x1; ( x2 > x1 ) ? i <= x2 : i >= x2; ( x2 > x1 ) ? i++ : i-- ) {
			draw_char( i, y1, value );
		}
	}
	else {
		// Get Bresenhaming...
		float dx = x2-x1;
		float dy = y2-y1;
		float err = 0.0;
		float derr = ABS( dy/dx );

		for ( int x = x1, y = y1; ( dx > 0 ) ? x <= x2 : x >= x2; ( dx > 0 ) ? x++ : x-- ) {
			draw_char( x, y, value );
			err += derr;
			while ( err >= 0.5 && ( ( dy > 0 ) ? y <= y2 : y >= y2 ) ) {
				draw_char( x, y, value );
				y += ( dy > 0 ) - ( dy < 0 );

				err -= 1.0;
			}
		}
	}
#endif
}