gint adjustPosAndNegLimits(gint mappedMin, gint mappedMax, gint minTMs, gint maxTMs, gint sd, gint *goodIncs, gint numGoodIncs, gint* numTms, gint* tmi, gint* adjMin, gint* adjMax) { gint bestAdj=32767; gint inc; gint found=0; gint bestNewMin=0,bestNewMax=0,bestTm=0,bestInc=0; gint mapMax=MAPMAX(sd); if (MAX(abs(mappedMin),abs(mappedMax))>mapMax) return (localError("adjustPosAndNegLimits: some data is > supplied mapping upper limit"),-1); // for (inc=1;inc<=mapMax;inc++) { for (inc=1;inc<=maxTMs;inc++) { gint quo1,quo2; gint newMin,newMax; gint adj,tm; zeroRem(-1,mappedMin,inc,&quo1,&newMin); zeroRem(1,mappedMax,inc,&quo2,&newMax); adj=abs(mappedMin-newMin)+abs(mappedMax-newMax);/* total adjustment */ tm=abs(quo1)+abs(quo2); /* tick marks; convention here is to not include the first, (though really it is 1 more than this). */ if (tm>=minTMs && tm<=maxTMs && adj<bestAdj && isGoodInc(inc,sd,goodIncs,numGoodIncs)) { bestAdj=adj; bestTm=tm; bestInc=inc; bestNewMin=newMin; bestNewMax=newMax; found=1; } } if (!found) return (localError("adjustPosAndNegLimits: found no acceptable divisor into the limits"),-1); *adjMin=bestNewMin; *adjMax=bestNewMax; *numTms=bestTm; *tmi=bestInc; return 0; }
int adjust_limits(gdouble dataMin, gdouble dataMax, gint denyMinEqualsAdjMin, gint minTMs, gint maxTMs, gint* numTms, gdouble* tmi, gdouble* adjMin, gdouble* adjMax, gint *goodIncs, gint numGoodIncs) { int sd = 2; int maxPossibleGoodInc=MAPMAX(sd); double zMin,zMax; /* zeroized limits (after unmapped above) */ double szMin,szMax; /* shifted zeroized limits */ int mszMin,mszMax; /* mapped shifted zeroized limits */ int amszMin,amszMax;/* adjusted mapped shifted zeroized limits */ double aszMin,aszMax; /* adjusted shifted zeroized limits */ double azMin,azMax; /* adjusted zeroized limits */ int falseOrigin; /* if true, we have decided on a false origin */ int mTmi; /* tick mark interval in mapped range */ int raise; /* power to which original limits must be raised so as to map into range specified by sd */ int i; /* loop index */ int adjMaxTMs=(denyMinEqualsAdjMin?maxTMs-1:maxTMs); /* This is the requested maxTMs UNLESS denyMinEqualsAdjMin is true. In that case it is possible that one of the limits will be shifted by an extra tickmark interval after the call to adjustPosAndNegLimits. To account for this possibility, need to decrement the maximum number of tickmarks available to the adjstment algorithm in advance, so that the total is gauranteed to be no more than the specified maximum. */ /* test to see parameters make sense */ if (dataMin>=dataMax) return(localError("adjustLimits: bad data range"),-1); if (minTMs<=0 || maxTMs<=0) return(localError("adjustLimits: negative or zero tickmarks specified"),-1); if (maxTMs==1 && denyMinEqualsAdjMin) return(localError("adjustLimits: cannot specify 1 tickmark AND require a margin"),-1); if (sd<1 || sd >4) return(localError("adjustLimits: sd out of range [1,4]"),-1); if(denyMinEqualsAdjMin && dataMin < 0 && dataMax < 0) dataMax = 0; /*check to see that the acceptable increments do not have more significant figures than allowed for the limits */ for (i=0;i<numGoodIncs;i++) { if (goodIncs[i]>maxPossibleGoodInc) return (localError("adjustLimits: supplied with a good increment that is too large given the number of significant digits"),-1); if (goodIncs[i]<=0) return (localError("adjustLimits: supplied with a good increment that is <=0"),-1); } /* see if either limit can be set to zero */ tryToZeroize(dataMin,dataMax,1.0/(double)maxTMs,&zMin,&zMax); /* Shift the origin. Note that shifting the origin may reduce the number of significant figures. For example (1000,1003) will be shifted to (0,3). Therefore need to shift the data BEFORE performing the map. Hence get (0,30) in this case. */ if (zMin*zMax>0) /*both of same sign and non-zero */ { if (zMax>0) { falseOrigin=1; /* positive false origin */ szMax=zMax-zMin; /* remove offset */ szMin=0; } else { falseOrigin=-1; /* negative false origin */ szMin=zMin-zMax; /* remove offset (zMappedMax<0 here) */ szMax=0; } } else { /* If here, then either zMin =0, or zMax =0, or they are both non-zero and of same sign. In all these cases do not shift the origin */ falseOrigin=0; szMax=zMax; szMin=zMin; } /* map the data */ mapData(szMin,szMax,sd,&mszMin,&mszMax,&raise); /* adjust limits */ if(adjustPosAndNegLimits(mszMin,mszMax,minTMs,adjMaxTMs,sd,goodIncs,numGoodIncs,numTms, &mTmi,&amszMin,&amszMax) == -1) { *adjMin = dataMin; *adjMax = dataMax; *numTms = 10; return -1; } /* unmap the data */ aszMin=((double)amszMin)*POWER10(-raise); aszMax=((double)amszMax)*POWER10(-raise); *tmi=((double)mTmi)*POWER10(-raise); /* unshift the origin */ if (falseOrigin==1) { azMin=aszMin+zMin; azMax=aszMax+zMin; } else if (falseOrigin==-1) { azMin=aszMin+zMax; azMax=aszMax+zMax; } else { azMin=aszMin; azMax=aszMax; } /* set outputs whilst performing margin adjustment */ if (denyMinEqualsAdjMin && falseOrigin==1 && azMin-dataMin<*tmi) /* requested margin is absent */ { *adjMin=azMin-*tmi; /* shift down by extra tickmark interval */ *adjMax=azMax; (*numTms)++; } else if (denyMinEqualsAdjMin && falseOrigin==-1 && azMax-dataMax<*tmi) /* requested margin is absent */ { *adjMin=azMin; /* shift down by extra tickmark interval */ *adjMax=azMax+*tmi; /* shift up by extra tickmark interval */ (*numTms)++; } else { *adjMin=azMin; *adjMax=azMax; } return 0; }