Nissa
Nissa

Reputation: 215

Perl: Finding maximum then divide by the max value, by comparing value vs by array position

I want to normalize my data. I wrote this code:

my $max1=0;
for (my $i=0; $i<=$#data; $i++) {
  if ($data[$i][1]>$data[$max1][1]) {$max1=$i;}
  #Disabled# if ($data[$i][1]>$max1) {$max1=$data[$i][1];}
}

for (my $i=0; $i<=$#data; $i++) {
  print "$i\t$data[$i][0]\t$data[$i][1]\t$max1\t";
  $data[$i][1] = $data[$i][1] / $data[$max1][1] * 10000;
  #Disabled# $data[$i][1] = $data[$i][1] / $max1 * 10000;
  print "$data[$i][0]\t$data[$i][1]\t$max1\n";
}

However this produced an error: All values up to the max position are divided by the max value, while values after the max position are unchanged, as if " / $data[$max1][1] * 10000 " never occured.

But, if I change the comparison using value rather than by array position, I got the correct results:

my $max1=0;
for (my $i=0; $i<=$#data; $i++) {
  #Disabled# if ($data[$i][1]>$data[$max1][1]) {$max1=$i;}
  if ($data[$i][1]>$max1) {$max1=$data[$i][1];}
}

for (my $i=0; $i<=$#data; $i++) {
  print "$i\t$data[$i][0]\t$data[$i][1]\t$max1\t";
  #Disabled# $data[$i][1] = $data[$i][1] / $data[$max1][1] * 10000;
  $data[$i][1] = $data[$i][1] / $max1 * 10000;
  print "$data[$i][0]\t$data[$i][1]\t$max1\n";
}

What did I do wrong with the first bit of code?

Upvotes: 0

Views: 98

Answers (1)

Borodin
Borodin

Reputation: 126742

The problem with your original code is that, part way through modifying the array, the value of $i will be equal to $max1. That means the statememt

$data[$i][1] = $data[$i][1] / $data[$max1][1] * 10000

will be equivalent to

$data[$max1][1] = $data[$max1][1] / $data[$max1][1] * 10000

which sets $data[$i][1] to 10,000. Thereafter, you are doing

 $data[$i][1] = $data[$i][1] / 10000 * 10000

which leaves the values unchanged

The solution, if you need one, is to extract the maximum value into a separate variable before the loop to keep it safe from modification

my $maxval =  $data[$i][1]

and change the assignment to

 $data[$i][1] = $data[$i][1] / $maxval * 10000

Your second attempt works correctly because it does exactly this, keeping the factor safe in $max1

Upvotes: 3

Related Questions