NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

## All the Perl that's Practical to Extract and Report

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.

Full
Abbreviated
Hidden
• #### scale linear then log(Score:0)

by slanning (5049) on 2008.09.03 10:30 (#64731) Homepage Journal

Maybe I'm misunderstanding, but I think you want to first scale logarithmically: log(\$val) if it's log base 'e'. Then linearly: so find the max value in the logged sequence, then multiply each value by 255 and divide by the max. Here's a kind of generic script, if I got it right:

#!/usr/bin/perl
# convert @VALS to a log scale base \$LOG_BASE
# and scaled linearly to \$SCALE_MAX

use strict;
use warnings;
use List::Util qw(max);

my \$SCALE_MAX = 1000;
my \$LOG_BASE = 10;
my @VALS = (1, 10, 100, 1000);

main();

sub main {
my @logvals = map { logN(\$_, \$LOG_BASE) } @VALS;
my \$maxval = max @logvals;

foreach my \$val (@logvals) {
print \$val * \$SCALE_MAX / \$maxval, \$/;
}
}

sub logN {
my (\$val, \$N) = @_;
return (\$N eq 'e') ? log(\$val) : log(\$val) / log(\$N);
}

• #### Re:(Score:1)

Need to scale linearly first in the case the minimum value is less than 1 before taking logs. (Also, \$SCALE_MAX should be 255)

Instead, if you simplify the mathematics (and you know the minimum and maximum values), calculate the logarithmic 'scaling factor'

\$scale = log( \$maximum ) / 255;

Then apply logarithmic scaling to each data element

map { int( log( \$_ - \$minimum + 1 ) / \$scale ) } @VALS;

So that the minimum value scales to zero, maximum value scales to 255. Adjust the linear scale in the log calculatio