/* determines new minimum and new maximum * DetMinMax* (* = all cell representation) analyzes * an array of cells and adjust the min and max argument * if necessary. If min and max are not yet set then they * must be MV both. The function * assumes that both min and max are MV if min is MV. */ static void DetMinMaxREAL4( REAL4 *min, /* read-write. adjusted minimum */ REAL4 *max, /* read-write. adjusted maximum */ size_t nrCells,/* number of cells in buf */ const REAL4 *buf) /* cell values to be examined */ { size_t i = 0; if ( IS_MV_REAL4(min)) { while ( IS_MV_REAL4(min) && (i != nrCells)) *((UINT4 *)min) = ((const UINT4 *)buf)[i++]; *max = *min; } while (i != nrCells) { if (! IS_MV_REAL4(buf+i)) { if (buf[i] < *min ) *min = buf[i]; if (buf[i] > *max) *max = buf[i]; } i++; } }
static int BuildEllipse2(REAL8 xmajor_a, REAL8 yminor_b, REAL8 angle) { int i,nrLines,xCeil; int lineStart,lineEndIncl; REAL8 xIncr,c=cos(angle),s=sin(angle); HOR_CUT_LINE *l; PRECOND(xmajor_a != 0); PRECOND(yminor_b != 0); xmajor_a /= Side(); yminor_b /= Side(); xCeil = (size_t)ceil(xmajor_a); nrLines = (xCeil*2)+1; l = (HOR_CUT_LINE *)ChkMalloc(sizeof(HOR_CUT_LINE)*nrLines); for(i=0; i < nrLines; i++) { /* mark not initialized */ SET_MV_REAL4(&(l[i].start.f)); } for (xIncr = 0; xIncr < xCeil; xIncr+=1) { REAL8 y = sqrt( fabs(1-(sqr(xIncr)/sqr(xmajor_a)))*sqr(yminor_b)); Add2Lines(l,nrLines,xCeil,c,s, xIncr, y); Add2Lines(l,nrLines,xCeil,c,s, xIncr,-y); Add2Lines(l,nrLines,xCeil,c,s,-xIncr, y); Add2Lines(l,nrLines,xCeil,c,s,-xIncr,-y); } if (0) { REAL8 y; xIncr = xmajor_a; y = sqrt( fabs(1-(sqr(xIncr)/sqr(xmajor_a)))*sqr(yminor_b)); Add2Lines(l,nrLines,xCeil,c,s, xIncr, y); Add2Lines(l,nrLines,xCeil,c,s, xIncr,-y); Add2Lines(l,nrLines,xCeil,c,s,-xIncr, y); Add2Lines(l,nrLines,xCeil,c,s,-xIncr,-y); } for(i=0; i < nrLines; i++) { /* mark not initialized */ if (!IS_MV_REAL4(&(l[i].start.f))) break; } POSTCOND(i < nrLines); lineStart = i; for(i = nrLines-1; i >=0;i--) { /* mark not initialized */ if (!IS_MV_REAL4(&(l[i].start.f))) break; } POSTCOND(i >= 0); lineEndIncl = i; for (i=lineStart ; i <= lineEndIncl; i++) { PRECOND(!IS_MV_REAL4(&(l[i].start.f))); l[i].start.i = (int)Rint(l[i].start.f); l[i].end.i = (int)Rint(l[i].end.f); } return 1; }
static int BuildCircle(REAL8 radius) { int i,nrLines,xFloor; REAL8 xIncr,lineStart,lineEndIncl; HOR_CUT_LINE *l; PRECOND(radius != 0); radius /= (Side()*2); xFloor = (size_t)floor(radius); radius *= radius; nrLines = (xFloor*2)+1; l = (HOR_CUT_LINE *)ChkMalloc(sizeof(HOR_CUT_LINE)*nrLines); for(i=0; i < nrLines; i++) { /* mark not initialized */ SET_MV_REAL4(&(l[i].start.f)); } for (xIncr = 0; xIncr <= xFloor; xIncr+=1) { REAL8 y = floor(sqrt(radius-sqr(xIncr))); Add2Lines(l,nrLines,xFloor,1,0, xIncr, y); Add2Lines(l,nrLines,xFloor,1,0, xIncr,-y); Add2Lines(l,nrLines,xFloor,1,0,-xIncr, y); Add2Lines(l,nrLines,xFloor,1,0,-xIncr,-y); } for(i=0; i < nrLines; i++) { /* mark not initialized */ if (!IS_MV_REAL4(&(l[i].start.f))) break; } POSTCOND(i < nrLines); lineStart = i; for(i = nrLines-1; i >=0;i--) { /* mark not initialized */ if (!IS_MV_REAL4(&(l[i].start.f))) break; } POSTCOND(i >= 0); lineEndIncl = i; for (i=(int)lineStart ; i <= (int)lineEndIncl; i++) { PRECOND(!IS_MV_REAL4(&(l[i].start.f))); l[i].start.i = (int)Rint(l[i].start.f); l[i].end.i = (int)Rint(l[i].end.f); } return 1; }
int is_mv_float(const float *f) { #ifdef HAVE_LIBCSF return IS_MV_REAL4(f); #else const unsigned char u[sizeof(float)] = { 0xFF, 0xFF, 0xFF, 0xFF }; /* will choke if sizeof(float) != 4 */ return (memcmp(f, u, sizeof(float)) == 0); #endif }
int Do_s_2_d(REAL4 *v, size_t n) { size_t i; double (* f)(double x) = (appDirection == APP_RADIANS) ? ScaleRad : Deg2Rad; for(i=0;i < n; i++) if ( (!IS_MV_REAL4(v+i)) ) v[i] = (REAL4)f(v[i]); return 0; }
/* (LIBRARY_INTERNAL) */ void Get_in_REAL4_to_REAL8( REAL8 *value, const REAL4 **matrix, /* map matrix */ int r, /* row number */ int c) /* column number */ { if ( IS_MV_REAL4(matrix[r]+c) ) SET_MV_REAL8(value); else *value = matrix[r][c]; }
void Do_atan( REAL4 *val, size_t n) { size_t i; double t; for(i=0; i < n; i++) if (! IS_MV_REAL4(val+i)) { t = atan((REAL4)val[i]); val[i] = (REAL4)ScaleRad(t); } }
void Do_acos( REAL4 *val, size_t n) { size_t i; for(i=0; i < n; i++) if (! IS_MV_REAL4(val+i)) { if (fabs(val[i]) > (REAL4)1.0) SET_MV_REAL4(val+i); else val[i] = (REAL4)acos((REAL4)val[i]); } }
void Do_cos_d( REAL4 *val, size_t n) { size_t i; for(i=0; i < n; i++) if (! IS_MV_REAL4(val+i)) { if (val[i] != (REAL4)-1) val[i] = (REAL4)cos((REAL4)val[i]); else SET_MV_REAL4(val+i); } }
void Do_sqrt( REAL4 *val, size_t n) { size_t i; for(i=0; i < n; i++) if (! IS_MV_REAL4(val+i)) { if (val[i] >= (REAL4)0.0) val[i] = (REAL4)sqrt(val[i]); else SET_MV_REAL4(val+i); } }
void Do_log10( REAL4 *val, size_t n) { size_t i; for(i=0; i < n; i++) if (! IS_MV_REAL4(val+i)) { if (val[i] > (REAL4)0.0) val[i] = (REAL4)log10((REAL4)val[i]); else SET_MV_REAL4(val+i); } }
/* Gets value of REAL8 map at location i. * Returns the REAL8 value. */ static REAL8 GetREAL8(const MAP_REAL8 *map, /* map to read */ INT4 i) /* index in map */ { REAL8 value; /* value to read */ int nrCols = map->NrCols(map); int r = DetRow(nrCols, i); int c = DetCol(nrCols, i); #ifdef DEBUG int nrRows = map->NrRows(map); PRECOND(0 <= r && r < nrRows); PRECOND(0 <= c && c < nrCols); #endif map->Get(&value, r, c, map); PRECOND(!IS_MV_REAL4(&value)); return value; }
void Do_tan_d( REAL4 *val, size_t n) { size_t i; REAL4 tan_mv1 = (REAL4)(M_PI*0.5); REAL4 tan_mv2 = (REAL4)(M_PI*1.5); for(i=0; i < n; i++) if (! IS_MV_REAL4(val+i)) { if ( (val[i] == -1) || tan_mv1 == val[i] || tan_mv2 == val[i]) SET_MV_REAL4(val+i); else val[i] = (REAL4)tan((REAL4)val[i]); } }
PCR_DLL_FUNC (const char *) pcr_LinkInExecute( const char *xmlNotUsed, LinkInTransferArray linkInTransferArray) { float *result = (float *)linkInTransferArray[0]; const float *spatial =(const float *)linkInTransferArray[1]; const float nonSpatial =((const float *)linkInTransferArray[2])[0]; int nrCells=nrRows*nrCols; int c; for(c=0; c < nrCells; c++) { if (IS_MV_REAL4(spatial+c)) SET_MV_REAL4(result+c); else result[c]=spatial[c]+nonSpatial; } /* no error */ return 0; }
void Do_asin( REAL4 *val, size_t n) { size_t i; double t; for(i=0; i < n; i++) if (! IS_MV_REAL4(val+i)) { t = val[i]; if (fabs(t) > (double)1.0) SET_MV_REAL4(val+i); else { t = asin(t); val[i] = (REAL4)ScaleRad(t); } } }
static void Add2Lines( HOR_CUT_LINE *l, int nrLines, int xCeil, REAL8 c, REAL8 s, REAL8 x, REAL8 y ) { REAL8 xRot = (x*c)-(y*s); REAL8 yRot = (x*s)-(y*c); int xInd = ((int)floor(xRot))+(int)xCeil; POSTCOND(xInd >= 0 && xInd < nrLines); if (IS_MV_REAL4(&(l[xInd].start.f))) { l[xInd].start.f = POSSIBLE_DATA_LOSS(REAL4,yRot); l[xInd].end.f = POSSIBLE_DATA_LOSS(REAL4,yRot); } l[xInd].start.f = POSSIBLE_DATA_LOSS(REAL4,MIN(l[xInd].start.f, yRot)); l[xInd].end.f = POSSIBLE_DATA_LOSS(REAL4,MAX(l[xInd].end.f, yRot)); (void)nrLines; // shut up compiler }
/* up to 34 is ok, 35 => infinite */ void Do_fac( REAL4 *val, size_t n) { size_t i; for(i=0; i < n; i++) if (! IS_MV_REAL4(val+i)) { float v = floor(val[i]); if (v > (REAL4)0.0 && v <= (REAL4)34.0 && v == val[i]) { float r = 1,n = 1; while (n <= v) { r *= n; n += 1; } val[i] = r; } else SET_MV_REAL4(val+i); } }