Please note that, as implied in the post above, the log scale generator is actually a cheat, based on noticing that the input & output ranges specified happened to lend themselves to a simplified calculation. Ie. log( 8000 ) + 1 is very close to 10.
However, that means that genLogScaler() is basically ignoring most of its input parameters and thus won't work for the generic case.
Here's a fixed version that works for your case and (a couple of other tested examples of) the generic case:
#! perl -slw
use strict;
sub genScaler {
my( $minout, $maxout, $minin, $maxin ) = @_;
my $outRange = $maxout - $minout;
my $inRange = $maxin - $minin;
my $factor = $inRange / $outRange;
sub {
my $in = shift;
return $minout + ( $in / $factor );
}
}
sub genLogScaler {
my( $minout, $maxout, $minin, $maxin ) = @_;
my $outRange = $maxout - $minout;
my $inRange = log( $maxin - $minin );
my $factor = $inRange / $outRange;
sub {
my $in = shift;
$in = 1 if $in < 1;
return $minout + ( log( $in ) / $factor );
}
}
my $fscale = genScaler( 1, 10, 0.1, 8000 );
print "Linear:";
printf "%7.1f -> %.1f\n", $_, $fscale->( $_ ) for 0.1, 1, 10, 100, 800
+, 1000, 4000, 6000, 8000;
print "\nLog";
my $lscale = genLogScaler( 1, 10, 0.1, 8000 );
printf "%7.1f -> %.1f\n", $_, $lscale->( $_ ) for 0.1, 1, 10, 100, 800
+, 1000, 4000, 6000, 8000;
print "\nNother Log:";
my $lscale2 = genLogScaler( -5, +5, 0.1, 8000 );
printf "%7.1f -> %.1f\n", $_, $lscale2->( $_ ) for 0.1, 1, 10, 100, 80
+0, 1000, 4000, 6000, 8000;
print "\nNother Log:";
my $lscale3 = genLogScaler( 0, +1000, 0.1, 8000 );
printf "%7.1f -> %.1f\n", $_, $lscale3->( $_ ) for 0.1, 1, 10, 100, 80
+0, 1000, 4000, 6000, 8000;
Produces: C:\test>genScalar.pl
Linear:
0.1 -> 1.0
1.0 -> 1.0
10.0 -> 1.0
100.0 -> 1.1
800.0 -> 1.9
1000.0 -> 2.1
4000.0 -> 5.5
6000.0 -> 7.8
8000.0 -> 10.0
Log
0.1 -> 1.0
1.0 -> 1.0
10.0 -> 3.3
100.0 -> 5.6
800.0 -> 7.7
1000.0 -> 7.9
4000.0 -> 9.3
6000.0 -> 9.7
8000.0 -> 10.0
Nother Log:
0.1 -> -5.0
1.0 -> -5.0
10.0 -> -2.4
100.0 -> 0.1
800.0 -> 2.4
1000.0 -> 2.7
4000.0 -> 4.2
6000.0 -> 4.7
8000.0 -> 5.0
Nother Log:
0.1 -> 0.0
1.0 -> 0.0
10.0 -> 256.2
100.0 -> 512.4
800.0 -> 743.8
1000.0 -> 768.6
4000.0 -> 922.9
6000.0 -> 968.0
8000.0 -> 1000.0
But note: it still contains the hack-y $in = 1 if $in < 1; fix.
With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
|