Slash Boxes
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.
More | Login | Reply
Loading... please wait.
  • 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:

    # 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);


    sub main

    • 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

  • i think both of the prior comments are on target.

    If you have such quantities of data that scaling and calling log repeatedly is a problem - and only if - there are old integer bitbang routines for log2 that could be done with XS or Inline::C or PDL.

    Or you could (ab)use Perl 5.10 pack() to grab the floating point representation's exponent

    Note that 256 buckets is a lot, hi res, for loglinear data unless it already was floating point or Math::BigFloat - as log2(MAXLONG) - log2(1) 256 or 8 bits -- it'

    # I had a sig when sigs were cool
    use Sig;