Esempio n. 1
0
main()
{
	int mat[7][6]= {
		{	10, 0, 0, 0, -2, 0},
		{	3, 9, 0, 0, 0, 3},
		{	0, 7, 8, 7, 0, 0},
		{	3, 0, 8, 7, 5, 0},
		{	0, 8, 0, 9, 9, 13},
		{	0, 4, 0, 0, 2, -1},
		{	3, 7, 0, 9, 2, 0}
	};

	struct sba_crsm sm;
	int idx1, idx2, k, pyramidLevel;
	int vidxs[7], /* max(6, 7) */
	jidxs[6], iidxs[7];

	sba_crsm_build(&sm, mat[0], 7, 6);
	sba_crsm_print(&sm, stdout);

	for(idx1=0; idx1<7; ++idx1) {
		for(idx2=0; idx2<6; ++idx2)
		printf("%3d ", ((k=sba_crsm_elmidx(&sm, idx1, idx2))!=-1)? sm.val[k] : 0);
		printf("\n");
	}

	for(idx1=0; idx1<7; ++idx1) {
		k=sba_crsm_row_elmidxs(&sm, idx1, vidxs, jidxs);
		printf("row %d\n", idx1);
		for(pyramidLevel=0; pyramidLevel<k; ++pyramidLevel) {
			idx2=jidxs[pyramidLevel];
			printf("%d %d  ", idx2, sm.val[vidxs[pyramidLevel]]);
		}
		printf("\n");
	}

	for(idx2=0; idx2<6; ++idx2) {
		k=sba_crsm_col_elmidxs(&sm, idx2, vidxs, iidxs);
		printf("col %d\n", idx2);
		for(pyramidLevel=0; pyramidLevel<k; ++pyramidLevel) {
			idx1=iidxs[pyramidLevel];
			printf("%d %d  ", idx1, sm.val[vidxs[pyramidLevel]]);
		}
		printf("\n");
	}

	sba_crsm_free(&sm);
}
Esempio n. 2
0
/* Given a parameter vector p made up of the 3D coordinates of n points, compute in
 * jac the jacobian of the predicted measurements, i.e. the jacobian of the projections of 3D points in the m images.
 * The jacobian is approximated with the aid of finite differences and is returned in the order
 * (B_11, ..., B_1m, ..., B_n1, ..., B_nm), where B_ij=dx_ij/db_i (see HZ).
 * Notice that depending on idxij, some of the B_ij might be missing
 *
 * Problem-specific information is assumed to be stored in a structure pointed to by "dat".
 *
 * NOTE: This function is provided mainly for illustration purposes; in case that execution time is a concern,
 * the jacobian should be computed analytically
 */
static void sba_str_Qs_fdjac(
    double *p,                /* I: current parameter estimate, (n*pnp)x1 */
    struct sba_crsm *idxij,   /* I: sparse matrix containing the location of x_ij in hx */
    int    *rcidxs,           /* work array for the indexes of nonzero elements of a single sparse matrix row/column */
    int    *rcsubs,           /* work array for the subscripts of nonzero elements in a single sparse matrix row/column */
    double *jac,              /* O: array for storing the approximated jacobian */
    void   *dat)              /* I: points to a "wrap_str_data_" structure */
{
  register int i, j, ii, jj;
  double *pbi;
  register double *pB;
  //int m;
  int n, nnz, Bsz;

  double tmp;
  register double d, d1;

  struct wrap_str_data_ *fdjd;
  void (*proj)(int j, int i, double *bi, double *xij, void *adata);
  double *hxij, *hxxij;
  int pnp, mnp;
  void *adata;

  /* retrieve problem-specific information passed in *dat */
  fdjd=(struct wrap_str_data_ *)dat;
  proj=fdjd->proj;
  pnp=fdjd->pnp; mnp=fdjd->mnp;
  adata=fdjd->adata;

  n=idxij->nr;
  //m=idxij->nc;
  Bsz=mnp*pnp;

  /* allocate memory for hxij, hxxij */
  if((hxij=malloc(2*mnp*sizeof(double)))==NULL){
    fprintf(stderr, "memory allocation request failed in sba_str_Qs_fdjac()!\n");
    exit(1);
  }
  hxxij=hxij+mnp;

  /* compute B_ij */
  for(i=0; i<n; ++i){
    pbi=p+i*pnp; // i-th point parameters

    nnz=sba_crsm_row_elmidxs(idxij, i, rcidxs, rcsubs); /* find nonzero B_ij, j=0...m-1 */
    for(jj=0; jj<pnp; ++jj){
      /* determine d=max(SBA_DELTA_SCALE*|pbi[jj]|, SBA_MIN_DELTA), see HZ */
      d=(double)(SBA_DELTA_SCALE)*pbi[jj]; // force evaluation
      d=FABS(d);
      if(d<SBA_MIN_DELTA) d=SBA_MIN_DELTA;
      d1=1.0/d; /* invert so that divisions can be carried out faster as multiplications */

      for(j=0; j<nnz; ++j){
        (*proj)(rcsubs[j], i, pbi, hxij, adata); // evaluate supplied function on current solution

        tmp=pbi[jj];
        pbi[jj]+=d;
        (*proj)(rcsubs[j], i, pbi, hxxij, adata);
        pbi[jj]=tmp; /* restore */

        pB=jac + idxij->val[rcidxs[j]]*Bsz; // set pB to point to B_ij
        for(ii=0; ii<mnp; ++ii)
          pB[ii*pnp+jj]=(hxxij[ii]-hxij[ii])*d1;
      }
    }
  }

  free(hxij);
}
Esempio n. 3
0
void sba_motstr_chkjac_x(
    void (*func)(double *p, struct sba_crsm *idxij, int *rcidxs, int *rcsubs, double *hx, void *adata),
    void (*jacf)(double *p, struct sba_crsm *idxij, int *rcidxs, int *rcsubs, double *jac, void *adata),
    double *p, struct sba_crsm *idxij, int *rcidxs, int *rcsubs, int ncon, int mcon, int cnp, int pnp, int mnp, void *func_adata, void *jac_adata)
{
const double factor=100.0, one=1.0, zero=0.0;
double *fvec, *fjac, *pp, *fvecp, *buf, *err;

int nvars, nobs, m, n, Asz, Bsz, ABsz, nnz;
register int i, j, ii, jj;
double eps, epsf, temp, epsmch, epslog;
register double *ptr1, *ptr2, *pab;
double *pa, *pb;
int fvec_sz, pp_sz, fvecp_sz, numerr=0;

  nobs=idxij->nnz*mnp;
  n=idxij->nr; m=idxij->nc;
  nvars=m*cnp + n*pnp;
  epsmch=DBL_EPSILON;
  eps=sqrt(epsmch);

  Asz=mnp*cnp; Bsz=mnp*pnp; ABsz=Asz+Bsz;
  fjac=(double *)emalloc(idxij->nnz*ABsz*sizeof(double));

  fvec_sz=fvecp_sz=nobs;
  pp_sz=nvars;
  buf=(double *)emalloc((fvec_sz + pp_sz + fvecp_sz)*sizeof(double));
  fvec=buf;
  pp=fvec+fvec_sz;
  fvecp=pp+pp_sz;

  err=(double *)emalloc(nobs*sizeof(double));

  /* compute fvec=func(p) */
  (*func)(p, idxij, rcidxs, rcsubs, fvec, func_adata);

  /* compute the jacobian at p */
  (*jacf)(p, idxij, rcidxs, rcsubs, fjac, jac_adata);

  /* compute pp */
  for(j=0; j<nvars; ++j){
    temp=eps*FABS(p[j]);
    if(temp==zero) temp=eps;
    pp[j]=p[j]+temp;
  }

  /* compute fvecp=func(pp) */
  (*func)(pp, idxij, rcidxs, rcsubs, fvecp, func_adata);

  epsf=factor*epsmch;
  epslog=log10(eps);

  for(i=0; i<nobs; ++i)
    err[i]=zero;

  pa=p;
  pb=p + m*cnp;
  for(i=0; i<n; ++i){
    nnz=sba_crsm_row_elmidxs(idxij, i, rcidxs, rcsubs); /* find nonzero A_ij, B_ij, j=0...m-1, actual column numbers in rcsubs */
    for(j=0; j<nnz; ++j){
      ptr2=err + idxij->val[rcidxs[j]]*mnp; // set ptr2 to point into err

      if(cnp && rcsubs[j]>=mcon){ // A_ij is nonzero
        ptr1=fjac + idxij->val[rcidxs[j]]*ABsz; // set ptr1 to point to A_ij
        pab=pa + rcsubs[j]*cnp;
        for(jj=0; jj<cnp; ++jj){
          temp=FABS(pab[jj]);
          if(temp==zero) temp=one;

          for(ii=0; ii<mnp; ++ii)
            ptr2[ii]+=temp*ptr1[ii*cnp+jj];
        }
      }

      if(pnp && i>=ncon){ // B_ij is nonzero
        ptr1=fjac + idxij->val[rcidxs[j]]*ABsz + Asz; // set ptr1 to point to B_ij
        pab=pb + i*pnp;
        for(jj=0; jj<pnp; ++jj){
          temp=FABS(pab[jj]);
          if(temp==zero) temp=one;

          for(ii=0; ii<mnp; ++ii)
            ptr2[ii]+=temp*ptr1[ii*pnp+jj];
        }
      }
    }
  }

  for(i=0; i<nobs; ++i){
    temp=one;
    if(fvec[i]!=zero && fvecp[i]!=zero && FABS(fvecp[i]-fvec[i])>=epsf*FABS(fvec[i]))
        temp=eps*FABS((fvecp[i]-fvec[i])/eps - err[i])/(FABS(fvec[i])+FABS(fvecp[i]));
    err[i]=one;
    if(temp>epsmch && temp<eps)
        err[i]=(log10(temp) - epslog)/epslog;
    if(temp>=eps) err[i]=zero;
  }

  free(fjac);
  free(buf);

  for(i=0; i<n; ++i){
    nnz=sba_crsm_row_elmidxs(idxij, i, rcidxs, rcsubs); /* find nonzero err_ij, j=0...m-1 */
    for(j=0; j<nnz; ++j){
      if(i<ncon && rcsubs[j]<mcon) continue; // corresponding gradients are taken to be zero

      ptr1=err + idxij->val[rcidxs[j]]*mnp; // set ptr1 to point into err
      for(ii=0; ii<mnp; ++ii)
        if(ptr1[ii]<=0.5){
          fprintf(stderr, "SBA: gradient %d (corresponding to element %d of the projection of point %d on camera %d) is %s (err=%g)\n",
                  idxij->val[rcidxs[j]]*mnp+ii, ii, i, rcsubs[j], (ptr1[ii]==0.0)? "wrong" : "probably wrong", ptr1[ii]);
          ++numerr;
        }
    }
  }
  if(numerr) fprintf(stderr, "SBA: found %d suspicious gradients out of %d\n\n", numerr, nobs);

  free(err);

  return;
}