[xiph-commits] r12800 - trunk/sushivision
xiphmont at svn.xiph.org
xiphmont at svn.xiph.org
Fri Mar 23 01:19:31 PDT 2007
Author: xiphmont
Date: 2007-03-23 01:19:28 -0700 (Fri, 23 Mar 2007)
New Revision: 12800
Modified:
trunk/sushivision/dimension.c
trunk/sushivision/panel-1d.c
trunk/sushivision/panel-2d.c
trunk/sushivision/panel-xy.c
trunk/sushivision/plot.c
trunk/sushivision/scale.c
trunk/sushivision/scale.h
Log:
A nifty little 'obvious in retrospect' enhancement to scales; rather
than tracking a power-of-ten exponent, track seperate power-of-two and
power-of-five exponents.
a) corrects an easy-to-hit overflow in xy-panels on 32 bit machines
b) eliminates the step_val element entirely, also eliminating all the divisons
associated with it
c) simplifies power of two scaling without affect base-ten performance in scales
d) increases representable range
Modified: trunk/sushivision/dimension.c
===================================================================
--- trunk/sushivision/dimension.c 2007-03-23 04:28:54 UTC (rev 12799)
+++ trunk/sushivision/dimension.c 2007-03-23 08:19:28 UTC (rev 12800)
@@ -810,4 +810,5 @@
int sv_dim_callback_value (sv_dim_t *d, int (*callback)(sv_dim_t *, void *), void *data){
d->private->value_callback = callback;
d->private->value_callback_data = data;
+ return 0;
}
Modified: trunk/sushivision/panel-1d.c
===================================================================
--- trunk/sushivision/panel-1d.c 2007-03-23 04:28:54 UTC (rev 12799)
+++ trunk/sushivision/panel-1d.c 2007-03-23 08:19:28 UTC (rev 12800)
@@ -379,7 +379,8 @@
char buffer[320];
_sv_plot_legend_clear(plot);
- if(3-p1->x_v.decimal_exponent > depth) depth = 3-p1->x_v.decimal_exponent;
+ if(3-_sv_scalespace_decimal_exponent(&p1->x_v) > depth)
+ depth = 3-_sv_scalespace_decimal_exponent(&p1->x_v);
// add each dimension to the legend
for(i=0;i<p->dimensions;i++){
Modified: trunk/sushivision/panel-2d.c
===================================================================
--- trunk/sushivision/panel-2d.c 2007-03-23 04:28:54 UTC (rev 12799)
+++ trunk/sushivision/panel-2d.c 2007-03-23 08:19:28 UTC (rev 12800)
@@ -888,8 +888,10 @@
// dimensions only if crosshairs are active
// display decimal precision relative to display scales
- if(3-p2->x.decimal_exponent > depth) depth = 3-p2->x.decimal_exponent;
- if(3-p2->y.decimal_exponent > depth) depth = 3-p2->y.decimal_exponent;
+ if(3-_sv_scalespace_decimal_exponent(&p2->x) > depth)
+ depth = 3-_sv_scalespace_decimal_exponent(&p2->x);
+ if(3-_sv_scalespace_decimal_exponent(&p2->y) > depth)
+ depth = 3-_sv_scalespace_decimal_exponent(&p2->y);
for(i=0;i<p->dimensions;i++){
sv_dim_t *d = p->dimension_list[i].d;
if( (d!=p2->x_d && d!=p2->y_d) ||
Modified: trunk/sushivision/panel-xy.c
===================================================================
--- trunk/sushivision/panel-xy.c 2007-03-23 04:28:54 UTC (rev 12799)
+++ trunk/sushivision/panel-xy.c 2007-03-23 08:19:28 UTC (rev 12800)
@@ -327,8 +327,10 @@
char buffer[320];
_sv_plot_legend_clear(plot);
- if(3-xy->x.decimal_exponent > depth) depth = 3-xy->x.decimal_exponent;
- if(3-xy->y.decimal_exponent > depth) depth = 3-xy->y.decimal_exponent;
+ if(3-_sv_scalespace_decimal_exponent(&xy->x) > depth)
+ depth = 3-_sv_scalespace_decimal_exponent(&xy->x);
+ if(3-_sv_scalespace_decimal_exponent(&xy->y) > depth)
+ depth = 3-_sv_scalespace_decimal_exponent(&xy->y);
// if crosshairs are active, add them to the fun
if( plot->cross_active){
@@ -353,7 +355,9 @@
}
// add each dimension to the legend
- if(-xy->data_v.decimal_exponent > depth) depth = -xy->data_v.decimal_exponent;
+ if(-_sv_scalespace_decimal_exponent(&xy->y) > depth)
+ depth = -_sv_scalespace_decimal_exponent(&xy->y);
+
for(i=0;i<p->dimensions;i++){
sv_dim_t *d = p->dimension_list[i].d;
@@ -979,8 +983,8 @@
// an assumption: v->step_pixel == 1 because spacing is 1. We can
// increment first_val instead of first_pixel.
while(_sv_scalespace_value(v,1)*neg < d->bracket[0]*neg){
- v->first_val += v->step_val*neg;
- i->first_val += v->step_val*neg;
+ v->first_val += v->neg;
+ i->first_val += v->neg;
v->pixels--;
i->pixels--;
}
Modified: trunk/sushivision/plot.c
===================================================================
--- trunk/sushivision/plot.c 2007-03-23 04:28:54 UTC (rev 12799)
+++ trunk/sushivision/plot.c 2007-03-23 08:19:28 UTC (rev 12800)
@@ -40,7 +40,7 @@
// the data scale (plotted in terms of the panel scale). In most
// cases they will be the same, but not always.
static double scale_demark(_sv_scalespace_t *panel, _sv_scalespace_t *data, int i, char *buffer){
- if(abs(data->step_val*data->m) > abs(panel->step_val*panel->m)){
+ if(data->expm > panel->expm){
double x=_sv_scalespace_mark(data,i);
if(buffer) _sv_scalespace_label(data,i,buffer);
return _sv_scalespace_pixel(panel, _sv_scalespace_value(data, x));
Modified: trunk/sushivision/scale.c
===================================================================
--- trunk/sushivision/scale.c 2007-03-23 04:28:54 UTC (rev 12799)
+++ trunk/sushivision/scale.c 2007-03-23 08:19:28 UTC (rev 12800)
@@ -207,96 +207,111 @@
return sv_scale_new(s->legend, s->vals, s->val_list, (char **)s->label_list, s->flags);
}
-/* plot and graph scales */
+/************************* plot and graph scalespaces *********************/
double _sv_scalespace_value(_sv_scalespace_t *s, double pixel){
- double val = (double)(pixel-s->first_pixel)*s->step_val/s->step_pixel + s->first_val;
- return val * s->m;
+ double val = (double)(pixel-s->first_pixel)*s->neg/s->step_pixel + s->first_val;
+ return val * s->expm;
}
void _sv_scalespace_double(_sv_scalespace_t *s){
- // mildly complicated by mantissa being powers of ten
- if(s->step_val & 0x1){ // ie, not divisible by two
- s->decimal_exponent--;
- s->m = pow(10,s->decimal_exponent);
- s->step_val *= 10;
- s->first_val *= 10;
- }
- s->step_val >>= 1;
- s->first_pixel <<= 1;
- s->pixels <<= 1;
+ s->two_exponent--;
+ s->expm = pow(5,s->five_exponent) * pow(2,s->two_exponent);
+ s->first_val *= 2;
+ s->first_pixel *= 2;
+ s->pixels *= 2;
}
double _sv_scalespace_pixel(_sv_scalespace_t *s, double val){
- val /= s->m;
+ val /= s->expm;
val -= s->first_val;
val *= s->step_pixel;
- val /= s->step_val;
+ val *= s->neg;
val += s->first_pixel;
return val;
}
double _sv_scalespace_scaledel(_sv_scalespace_t *from, _sv_scalespace_t *to){
- return (double)from->step_val / from->step_pixel * from->m / to->m * to->step_pixel / to->step_val;
+ return from->expm * to->step_pixel * from->neg * to->neg / (from->step_pixel * to->expm);
}
long _sv_scalespace_scalenum(_sv_scalespace_t *from, _sv_scalespace_t *to){
- int dec = from->decimal_exponent - to->decimal_exponent;
- long ret = from->step_val * to->step_pixel * from->neg;
- while(dec-->0)
- ret *= 10;
+ int five = from->five_exponent - to->five_exponent;
+ int two = from->two_exponent - to->two_exponent;
+ long ret = to->step_pixel;
+ while(two-->0)
+ ret *= 2;
+ while(five-->0)
+ ret *= 5;
return ret*2;
}
long _sv_scalespace_scaleden(_sv_scalespace_t *from, _sv_scalespace_t *to){
- int dec = to->decimal_exponent - from->decimal_exponent;
- long ret = from->step_pixel * to->step_val * to->neg;
- while(dec-->0)
- ret *= 10;
+ int five = to->five_exponent - from->five_exponent;
+ int two = to->two_exponent - from->two_exponent;
+ long ret = from->step_pixel;
+ while(two-->0)
+ ret *= 2;
+ while(five-->0)
+ ret *= 5;
return ret*2;
}
long _sv_scalespace_scaleoff(_sv_scalespace_t *from, _sv_scalespace_t *to){
- int decF = from->decimal_exponent - to->decimal_exponent;
- int decT = to->decimal_exponent - from->decimal_exponent;
+ int fiveF = from->five_exponent - to->five_exponent;
+ int twoF = from->two_exponent - to->two_exponent;
+ int fiveT = to->five_exponent - from->five_exponent;
+ int twoT = to->two_exponent - from->two_exponent;
long expF = 1;
long expT = 1;
- while(decF-->0) expF *= 10;
- while(decT-->0) expT *= 10;
+ while(twoF-->0) expF *= 2;
+ while(fiveF-->0) expF *= 5;
+ while(twoT-->0) expT *= 2;
+ while(fiveT-->0) expT *= 5;
- return (2 * from->first_val * from->step_pixel - (2 * from->first_pixel + 1) * from->step_val)
- * expF * to->step_pixel * from->neg
- - (2 * to->first_val * to->step_pixel - (2 * to->first_pixel + 1) * to->step_val)
- * expT * from->step_pixel * to->neg;
+ return (2 * from->first_val * from->step_pixel * from->neg - (2 * from->first_pixel + 1))
+ * expF * to->step_pixel
+
+ - (2 * to->first_val * to->step_pixel * to->neg - (2 * to->first_pixel + 1))
+ * expT * from->step_pixel;
}
long _sv_scalespace_scalebin(_sv_scalespace_t *from, _sv_scalespace_t *to){
- int decF = from->decimal_exponent - to->decimal_exponent;
- int decT = to->decimal_exponent - from->decimal_exponent;
+ int fiveF = from->five_exponent - to->five_exponent;
+ int twoF = from->two_exponent - to->two_exponent;
+ int fiveT = to->five_exponent - from->five_exponent;
+ int twoT = to->two_exponent - from->two_exponent;
long expF = 1;
long expT = 1;
- while(decF-->0) expF *= 10;
- while(decT-->0) expT *= 10;
+ while(twoF-->0) expF *= 2;
+ while(fiveF-->0) expF *= 5;
+ while(twoT-->0) expT *= 2;
+ while(fiveT-->0) expT *= 5;
- return (2 * from->first_val * from->step_pixel - (2 * from->first_pixel) * from->step_val)
- * expF * to->step_pixel * from->neg
- - (2 * to->first_val * to->step_pixel - (2 * to->first_pixel) * to->step_val)
- * expT * from->step_pixel * to->neg;
+ return (2 * from->first_val * from->step_pixel * from->neg - (2 * from->first_pixel))
+ * expF * to->step_pixel
+
+ - (2 * to->first_val * to->step_pixel * to->neg - (2 * to->first_pixel))
+ * expT * from->step_pixel;
}
int _sv_scalespace_mark(_sv_scalespace_t *s, int num){
return s->first_pixel + s->step_pixel*num;
}
+int _sv_scalespace_decimal_exponent(_sv_scalespace_t *s){
+ return rint(s->two_exponent*.3 + s->five_exponent*.7);
+}
+
double _sv_scalespace_label(_sv_scalespace_t *s, int num, char *buffer){
int pixel = _sv_scalespace_mark(s,num);
double val = _sv_scalespace_value(s,pixel);
-
- if(s->decimal_exponent<0){
- sprintf(buffer,"%.*f",-s->decimal_exponent,val);
+ int decimal_exponent = _sv_scalespace_decimal_exponent(s);
+ if(decimal_exponent<0){
+ sprintf(buffer,"%.*f",-decimal_exponent,val);
}else{
sprintf(buffer,"%.0f",val);
}
@@ -308,8 +323,8 @@
double orange = fabs(highpoint - lowpoint), range;
_sv_scalespace_t ret;
- int place;
- int step;
+ int five_place;
+ int two_place;
long long first;
int neg = (lowpoint>highpoint?-1:1);
@@ -320,8 +335,8 @@
ret.lo = lowpoint;
ret.hi = highpoint;
ret.init = 1;
- ret.pixels=pixels;
- ret.legend=name;
+ ret.pixels = pixels;
+ ret.legend = name;
ret.spacing = max_spacing;
if(orange < 1e-30*pixels){
@@ -334,43 +349,43 @@
while(1){
range = orange;
- place = 0;
- step = 1;
+ five_place = 0;
+ two_place = 0;
while(rint(pixels / range) < max_spacing){
- place++;
+ five_place++;
+ two_place++;
range *= .1;
}
while(rint(pixels / range) > max_spacing){
- place--;
+ five_place--;
+ two_place--;
range *= 10;
}
- ret.decimal_exponent = place;
-
if (rint(pixels / (range*.2)) <= max_spacing){
- step *= 5;
+ five_place++;
range *= .2;
}
if (rint(pixels / (range*.5)) <= max_spacing){
- step *= 2;
+ two_place++;
range *= .5;
}
- step *= neg;
- ret.step_val = step;
+ ret.two_exponent = two_place;
+ ret.five_exponent = five_place;
if(pixels == 0. || range == 0.)
ret.step_pixel = max_spacing;
else
ret.step_pixel = rint(pixels / range);
- ret.m = pow(10,place);
+ ret.expm = pow(2,two_place) * pow(5,five_place);
- first = (long long)(lowpoint/ret.m)/step*step;
+ first = (long long)(lowpoint/ret.expm);
- if(neg){
+ if(neg<0){
/* overflow check */
- if(LLONG_MAX * ret.m < highpoint){
+ if(LLONG_MAX * ret.expm < highpoint){
lowpoint += orange/2;
orange *= 2;
highpoint = lowpoint - orange;
@@ -379,7 +394,7 @@
}
}else{
/* overflow check */
- if(LLONG_MAX * ret.m < lowpoint){
+ if(LLONG_MAX * ret.expm < lowpoint){
lowpoint -= orange/2;
orange *= 2;
highpoint = lowpoint + orange;
@@ -388,12 +403,12 @@
}
}
- while(first * ret.m * neg < lowpoint*neg)
- first += step;
+ while((first+neg) * ret.expm * neg < lowpoint*neg)
+ first += neg;
- if(neg){
+ if(neg<0){
/* overflow check */
- if(LLONG_MIN * ret.m > lowpoint){
+ if(LLONG_MIN * ret.expm > lowpoint){
lowpoint += orange/2;
orange *= 2;
highpoint = lowpoint - orange;
@@ -402,7 +417,7 @@
}
}else{
/* overflow check */
- if(LLONG_MIN * ret.m > highpoint){
+ if(LLONG_MIN * ret.expm > highpoint){
lowpoint -= orange/2;
orange *= 2;
highpoint = lowpoint + orange;
@@ -411,13 +426,13 @@
}
}
- while(first * ret.m * neg > highpoint*neg)
- first -= step;
+ while((first-neg) * ret.expm * neg > highpoint*neg)
+ first -= neg;
// make sure the scale display has meaningful sig figs to work with */
if( first*128/128 != first ||
- first*16*ret.m == (first*16 +step)*ret.m ||
- (first*16+step)*ret.m == (first*16 +step*2)*ret.m){
+ first*16*ret.expm == (first*16+neg)*ret.expm ||
+ (first*16+neg)*ret.expm == (first*16+neg*2)*ret.expm){
lowpoint -= orange/(neg*2);
orange *= 2;
highpoint = lowpoint + neg*orange;
@@ -427,7 +442,7 @@
ret.first_val = first;
- ret.first_pixel = rint((first - (lowpoint / ret.m)) * ret.step_pixel / ret.step_val);
+ ret.first_pixel = rint((first - (lowpoint / ret.expm)) * ret.step_pixel);
ret.neg = neg;
break;
Modified: trunk/sushivision/scale.h
===================================================================
--- trunk/sushivision/scale.h 2007-03-23 04:28:54 UTC (rev 12799)
+++ trunk/sushivision/scale.h 2007-03-23 08:19:28 UTC (rev 12800)
@@ -27,12 +27,11 @@
long long first_val;
long first_pixel;
-
- long step_val;
long step_pixel;
- int decimal_exponent;
- double m;
+ int five_exponent;
+ int two_exponent;
+ double expm;
int init;
int pixels;
@@ -52,3 +51,4 @@
extern double _sv_scalespace_label(_sv_scalespace_t *s, int num, char *buffer);
extern _sv_scalespace_t _sv_scalespace_linear (double lowpoint, double highpoint, int pixels, int max_spacing,char *name);
extern void _sv_scalespace_double(_sv_scalespace_t *s);
+extern int _sv_scalespace_decimal_exponent(_sv_scalespace_t *s);
More information about the commits
mailing list