⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 snaphu_solver.c

📁 phase unwrapping algorithm for SAR interferometry
💻 C
📖 第 1 页 / 共 5 页
字号:
  /* return the number of nodes in the network */  return(nnodes);      }/* function: FindApex() * -------------------- * Given pointers to two nodes on a spanning tree, the function finds * and returns a pointer to their deepest common ancestor, the apex of * a cycle formed by joining the two nodes with an arc. */nodeT *FindApex(nodeT *from, nodeT *to){  if(from->level > to->level){    while(from->level != to->level){      from=from->pred;    }  }else{    while(from->level != to->level){      to=to->pred;    }  }  while(from != to){    from=from->pred;    to=to->pred;  }  return(from);}/* function: CandidateCompare() * ---------------------------- * Compares the violations of candidate arcs for sorting.  First checks * if either candidate has an arcdir magnitude greater than 1, denoting  * an augmenting cycle.  Augmenting candidates are always placed before  * non-augmenting candidates.  Otherwise, returns positive if the first   * candidate has a greater (less negative) violation than the second, 0  * if they are the same, and negative otherwise.   */int CandidateCompare(const void *c1, const void *c2){  if(labs(((candidateT *)c1)->arcdir) > 1){    if(labs(((candidateT *)c2)->arcdir) < 2){      return(-1);    }  }else if(labs(((candidateT *)c2)->arcdir) > 1){    return(1);  }  return(((candidateT *)c1)->violation - ((candidateT *)c2)->violation);  /*  if(((candidateT *)c1)->violation > ((candidateT *)c2)->violation){    return(1);  }else if(((candidateT *)c1)->violation < ((candidateT *)c2)->violation){    return(-1);  }else{    return(0);  }  */}/* function: NeighborNodeGrid() * ---------------------------- * Return the neighboring node of the given node corresponding to the * given arc number for a grid network with a ground node. */nodeT *NeighborNodeGrid(nodeT *node1, long arcnum, long *upperarcnumptr,			nodeT **nodes, nodeT *ground, long *arcrowptr, 			long *arccolptr, long *arcdirptr, long nrow, 			long ncol, nodesuppT **nodesupp){  long row, col;  row=node1->row;  col=node1->col;  switch(arcnum){  case -4:    *arcrowptr=row;    *arccolptr=col+1;    *arcdirptr=1;    if(col==ncol-2){      return(ground);    }else{      return(&nodes[row][col+1]);    }    break;  case -3:    *arcrowptr=nrow+row;    *arccolptr=col;    *arcdirptr=1;    if(row==nrow-2){      return(ground);    }else{      return(&nodes[row+1][col]);    }    break;  case -2:    *arcrowptr=row;    *arccolptr=col;    *arcdirptr=-1;    if(col==0){      return(ground);    }else{      return(&nodes[row][col-1]);    }    break;  case -1:    *arcrowptr=nrow-1+row;    *arccolptr=col;    *arcdirptr=-1;    if(row==0){      return(ground);    }else{      return(&nodes[row-1][col]);    }    break;  default:    if(arcnum<nrow-1){      *arcrowptr=arcnum;      *arccolptr=0;      *arcdirptr=1;      return(&nodes[*arcrowptr][0]);    }else if(arcnum<2*(nrow-1)){                 *arcrowptr=arcnum-(nrow-1);      *arccolptr=ncol-1;      *arcdirptr=-1;      return(&nodes[*arcrowptr][ncol-2]);    }else if(arcnum<2*(nrow-1)+ncol-3){         *arcrowptr=nrow-1;      *arccolptr=arcnum-2*(nrow-1)+1;          *arcdirptr=1;      return(&nodes[0][*arccolptr]);    }else{      *arcrowptr=2*nrow-2;      *arccolptr=arcnum-(2*(nrow-1)+ncol-3)+1;      *arcdirptr=-1;      return(&nodes[nrow-2][*arccolptr]);    }    break;  }}/* function: NeighborNodeNonGrid() * ------------------------------- * Return the neighboring node of the given node corresponding to the * given arc number for a nongrid network (ie, arbitrary topology). */nodeT *NeighborNodeNonGrid(nodeT *node1, long arcnum, long *upperarcnumptr,			   nodeT **nodes, nodeT *ground, long *arcrowptr, 			   long *arccolptr, long *arcdirptr, long nrow, 			   long ncol, nodesuppT **nodesupp){  long tilenum, nodenum;  scndryarcT *outarc;  /* set up */  tilenum=node1->row;  nodenum=node1->col;  *upperarcnumptr=nodesupp[tilenum][nodenum].noutarcs-5;    /* set the arc row (tilenumber) and column (arcnumber) */  outarc=nodesupp[tilenum][nodenum].outarcs[arcnum+4];  *arcrowptr=outarc->arcrow;  *arccolptr=outarc->arccol;  if(node1==outarc->from){    *arcdirptr=1;  }else{    *arcdirptr=-1;  }  /* return the neighbor node */  return(nodesupp[tilenum][nodenum].neighbornodes[arcnum+4]);}/* function: GetArcGrid() * ---------------------- * Given a from node and a to node, sets pointers for indices into * arc arrays, assuming primary (grid) network. */void GetArcGrid(nodeT *from, nodeT *to, long *arcrow, long *arccol, 		long *arcdir, long nrow, long ncol, nodesuppT **nodesupp){  long fromrow, fromcol, torow, tocol;  fromrow=from->row;  fromcol=from->col;  torow=to->row;  tocol=to->col;    if(fromcol==tocol-1){           /* normal arcs (neither endpoint ground) */    *arcrow=fromrow;    *arccol=fromcol+1;    *arcdir=1;  }else if(fromcol==tocol+1){    *arcrow=fromrow;    *arccol=fromcol;    *arcdir=-1;  }else if(fromrow==torow-1){    *arcrow=fromrow+1+nrow-1;    *arccol=fromcol;    *arcdir=1;  }else if(fromrow==torow+1){    *arcrow=fromrow+nrow-1;    *arccol=fromcol;    *arcdir=-1;  }else if(fromcol==0){           /* arcs to ground */    *arcrow=fromrow;    *arccol=0;    *arcdir=-1;  }else if(fromcol==ncol-2){    *arcrow=fromrow;    *arccol=ncol-1;    *arcdir=1;  }else if(fromrow==0){    *arcrow=nrow-1;    *arccol=fromcol;    *arcdir=-1;  }else if(fromrow==nrow-2){    *arcrow=2*(nrow-1);    *arccol=fromcol;    *arcdir=1;  }else if(tocol==0){             /* arcs from ground */    *arcrow=torow;    *arccol=0;    *arcdir=1;  }else if(tocol==ncol-2){    *arcrow=torow;    *arccol=ncol-1;    *arcdir=-1;  }else if(torow==0){    *arcrow=nrow-1;    *arccol=tocol;    *arcdir=1;  }else{    *arcrow=2*(nrow-1);    *arccol=tocol;    *arcdir=-1;  }}/* function: GetArcNonGrid() * ------------------------- * Given a from node and a to node, sets pointers for indices into * arc arrays, assuming secondary (arbitrary topology) network. */void GetArcNonGrid(nodeT *from, nodeT *to, long *arcrow, long *arccol, 		   long *arcdir, long nrow, long ncol, nodesuppT **nodesupp){  long tilenum, nodenum, arcnum;  scndryarcT *outarc;  /* get tile and node numbers for from node */  tilenum=from->row;  nodenum=from->col;  /* loop over all outgoing arcs of from node */  arcnum=0;  while(TRUE){    outarc=nodesupp[tilenum][nodenum].outarcs[arcnum++];    if(outarc->from==to){      *arcrow=outarc->arcrow;      *arccol=outarc->arccol;      *arcdir=-1;      return;    }else if(outarc->to==to){      *arcrow=outarc->arcrow;      *arccol=outarc->arccol;      *arcdir=1;      return;    }  }}/* Function: NonDegenUpdateChildren() * ---------------------------------- * Updates potentials and groups of all childredn along an augmenting path,  * until a stop node is hit. */void NonDegenUpdateChildren(nodeT *startnode, nodeT *lastnode, 			    nodeT *nextonpath, long dgroup, 			    long ngroundarcs, long nflow, nodeT **nodes,			    nodesuppT **nodesupp, nodeT *ground, 			    nodeT ***apexes, incrcostT **incrcosts, 			    long nrow, long ncol, paramT *params){  nodeT *node1, *node2;  long dincost, doutcost, arcnum, upperarcnum, startlevel;  long group1, pathgroup, arcrow, arccol, arcdir;  /* loop along flow path  */  node1=startnode;  pathgroup=lastnode->group;  while(node1!=lastnode){    /* update potentials along the flow path by calculating arc distances */    node2=nextonpath;    GetArc(node2->pred,node2,&arcrow,&arccol,&arcdir,nrow,ncol,nodesupp);    doutcost=node1->outcost - node2->outcost      + GetCost(incrcosts,arcrow,arccol,arcdir);    node2->outcost+=doutcost;    dincost=node1->incost - node2->incost      + GetCost(incrcosts,arcrow,arccol,-arcdir);    node2->incost+=dincost;    node2->group=node1->group+dgroup;    /* update potentials of children of this node in the flow path */    node1=node2;    if(node1->row!=GROUNDROW){      arcnum=-5;      upperarcnum=-1;    }else{      arcnum=-1;      upperarcnum=ngroundarcs-1;    }    while(arcnum<upperarcnum){      node2=NeighborNode(node1,++arcnum,&upperarcnum,nodes,ground,                         &arcrow,&arccol,&arcdir,nrow,ncol,nodesupp);      if(node2->pred==node1 && node2->group>0){        if(node2->group==pathgroup){          nextonpath=node2;        }else{          startlevel=node2->level;          group1=node1->group;          while(TRUE){            node2->group=group1;            node2->incost+=dincost;            node2->outcost+=doutcost;            node2=node2->next;            if(node2->level <= startlevel){              break;            }          }        }      }    }  }}/* function: InitNetowrk() * ----------------------- */void InitNetwork(short **flows, long *ngroundarcsptr, long *ncycleptr, 		 long *nflowdoneptr, long *mostflowptr, long *nflowptr, 		 long *candidatebagsizeptr, candidateT **candidatebagptr, 		 long *candidatelistsizeptr, candidateT **candidatelistptr, 		 signed char ***iscandidateptr, nodeT ****apexesptr, 		 bucketT **bktsptr, long *iincrcostfileptr, 		 incrcostT ***incrcostsptr, nodeT ***nodesptr, nodeT *ground, 		 long *nnoderowptr, short **nnodesperrowptr, long *narcrowptr,		 short **narcsperrowptr, long nrow, long ncol, 		 signed char *notfirstloopptr, totalcostT *totalcostptr,		 paramT *params){  long i;  /* get and initialize memory for nodes */  if(ground!=NULL && *nodesptr==NULL){    *nodesptr=(nodeT **)Get2DMem(nrow-1,ncol-1,sizeof(nodeT *),sizeof(nodeT));    InitNodeNums(nrow-1,ncol-1,*nodesptr,ground);  }  /* take care of ambiguous flows to ground at corners */  if(ground!=NULL){    flows[0][0]+=flows[nrow-1][0];    flows[nrow-1][0]=0;    flows[0][ncol-1]-=flows[nrow-1][ncol-2];    flows[nrow-1][ncol-2]=0;    flows[nrow-2][0]-=flows[2*nrow-2][0];    flows[2*nrow-2][0]=0;    flows[nrow-2][ncol-1]+=flows[2*nrow-2][ncol-2];    flows[2*nrow-2][ncol-2]=0;  }  /* initialize network solver variables */  *ncycleptr=0;  *nflowptr=1;  *candidatebagsizeptr=INITARRSIZE;  *candidatebagptr=MAlloc(*candidatebagsizeptr*sizeof(candidateT));  *candidatelistsizeptr=INITARRSIZE;  *candidatelistptr=MAlloc(*candidatelistsizeptr*sizeof(candidateT));  if(ground!=NULL){    *nflowdoneptr=0;    *mostflowptr=Short2DRowColAbsMax(flows,nrow,ncol);    if(*mostflowptr*params->nshortcycle>LARGESHORT){      fprintf(sp1,"Maximum flow on network: %ld\n",*mostflowptr);      fprintf(sp0,"((Maximum flow) * NSHORTCYCLE) too large\nAbort\n");      exit(ABNORMAL_EXIT);    }    if(ncol>2){      *ngroundarcsptr=2*(nrow+ncol-2)-4; /* don't include corner column arcs */    }else{      *ngroundarcsptr=2*(nrow+ncol-2)-2;    }    *iscandidateptr=(signed char **)Get2DRowColMem(nrow,ncol,						   sizeof(signed char *),						   sizeof(signed char));    *apexesptr=(nodeT ***)Get2DRowColMem(nrow,ncol,sizeof(nodeT **),					 sizeof(nodeT *));  }  /* set up buckets for TreeSolve (MSTInitFlows() has local set of buckets) */  *bktsptr=MAlloc(sizeof(bucketT));  if(ground!=NULL){    (*bktsptr)->minind=-LRound((params->maxcost+1)*(nrow+ncol)			       *NEGBUCKETFRACTION);    (*bktsptr)->maxind=LRound((params->maxcost+1)*(nrow+ncol)			      *POSBUCKETFRACTION);  }else{    (*bktsptr)->minind=-LRound((params->maxcost+1)*(nrow)			       *NEGBUCKETFRACTION);    (*bktsptr)->maxind=LRound((params->maxcost+1)*(nrow)			      *POSBUCKETFRACTION);  }  (*bktsptr)->size=(*bktsptr)->maxind-(*bktsptr)->minind+1;  (*bktsptr)->bucketbase=(nodeT **)MAlloc((*bktsptr)->size*sizeof(nodeT *));  (*bktsptr)->bucket=&((*bktsptr)->bucketbase[-(*bktsptr)->minind]);  for(i=0;i<(*bktsptr)->size;i++){    (*bktsptr)->bucketbase[i]=NULL;  }  /* get memory for incremental cost arrays */  *iincrcostfileptr=0;  if(ground!=NULL){    (*incrcostsptr)=(incrcostT **)Get2DRowColMem(nrow,ncol,sizeof(incrcostT *),						 sizeof(incrcostT));  }  /* set number of nodes and arcs per row */  if(ground!=NULL){    (*nnoderowptr)=nrow-1;    (*nnodesperrowptr)=(short *)MAlloc((nrow-1)*sizeof(short));    for(i=0;i<nrow-1;i++){      (*nnodesperrowptr)[i]=ncol-1;    }    (*narcrowptr)=2*nrow-1;    (*narcsperrowptr)=(short *)MAlloc((2*nrow-1)*sizeof(short));    for(i=0;i<nrow-1;i++){      (*narcsperrowptr)[i]=ncol;    }    for(i=nrow-1;i<2*nrow-1;i++){      (*narcsperrowptr)[i]=ncol-1;    }  }  /* initialize variables for main optimizer loop */  (*notfirstloopptr)=FALSE;  (*totalcostptr)=INITTOTALCOST;}/* function: InitNodeNums() * ------------------------ */void InitNodeNums(long nrow, long ncol, nodeT **nodes, nodeT *ground){  long row, col;  /* loop over each element and initialize values */  for(row=0;row<nrow;row++){    for(col=0;col<ncol;col++){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -