Raw File
linearradius.c
#include <R.h>
#include <R_ext/Utils.h>
#include "chunkloop.h"

/* 
   linearradius.c

   Bounding radius in linear network

   $Revision: 1.1 $  $Date: 2016/07/19 06:52:57 $

*/

#define DPATH(I,J) dpath[(J) + Nv * (I)]

#include "yesno.h"

#undef DEBUG

void 
linearradius(ns, from, to,  /* network segments */
	     lengths, /* segment lengths */
	     nv, dpath,  /* shortest path distances between vertices */
	     huge, 
	     result)
     int *nv, *ns;
     int *from, *to; /* integer vectors (mappings) */
     double *dpath; /* matrix of shortest path distances between vertices */
     double *lengths; /* vector of segment lengths */
     double *huge; /* very large value */
     double *result; 
{
  int Nv, Ns;
  int i, j, A, B, C, D;
  double AB, AC, AD, BC, BD, CD;
  double sAij, sBij, sAiMax, sBiMax, smin;
  int maxchunk;

  Nv = *nv;
  Ns = *ns;
  smin = *huge;

  OUTERCHUNKLOOP(i, Ns, maxchunk, 16384) {
    R_CheckUserInterrupt();
    INNERCHUNKLOOP(i, Ns, maxchunk, 16384) {
      /* indices of endpoints of segment i */
      A = from[i];
      B = to[i];
      AB = lengths[i];
      sAiMax = sBiMax = AB/2.0;
      for(j = 0; j < Ns; j++) {
	if(j != i) {
	  /* indices of endpoints of segment i */
	  C = from[j];
	  D = to[j];
	  CD = lengths[j];
	  AC = DPATH(A,C);
	  AD = DPATH(A,D);
	  BC = DPATH(B,C);
	  BD = DPATH(B,D);
	  /* max dist from A to any point in segment j */
	  sAij = (AD > AC + CD) ? AC + CD :
 	          (AC > AD + CD) ? AD + CD : (AC + AD + CD)/2.0;
	  /* max dist from B to any point in segment j */
	  sBij = (BD > BC + CD) ? BC + CD : 
  	          (BC > BD + CD) ? BD + CD : (BC + BD + CD)/2.0;
	  /* row-wise maximum */
	  if(sAij > sAiMax) sAiMax = sAij;
	  if(sBij > sBiMax) sBiMax = sBij;
	}
      }
      if(sAiMax < smin) smin = sAiMax;
      if(sBiMax < smin) smin = sBiMax;
    }
  }

  *result = smin;
}

back to top