Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Re^5: Normalizing a range of numbers to a percentage

by tybalt89 (Monsignor)
on Mar 07, 2019 at 23:36 UTC ( [id://1231041]=note: print w/replies, xml ) Need Help??


in reply to Re^4: Normalizing a range of numbers to a percentage
in thread Normalizing a range of numbers to a percentage

No.

my $x = (($tap - $min) * ($new_max - $new_min) / ($max - $min)) + $new +_min;

The offset on the new range has to be outside the multiply.

Replies are listed 'Best First'.
Re^6: Normalizing a range of numbers to a percentage
by pryrt (Abbot) on Mar 08, 2019 at 00:41 UTC

    stevieb: I don't know how rusty your algebra is, but it's always good to go back to first principles: what you're doing is a liner transformation from an input number to an output number. So let's derive it using everybody's favorite line, y = mx + b. The y are your output points (y0 = $new_min and y1 = $new_max), the x are you input points (x0 = $min and x1 = $max). Then let's calculate a y from a given x (where x = $tap). (We'll ignore the fact that you called the output $x, just to confuse us, until the very end.)

        #I#     y0 = m*x0 + b
        #II#    y1 = m*x1 + b
    
    Want to eliminate b, so we're down to one unknown:
    
        #III#   (y1-y0) = m*(x1-x0) + (b-b)     #II#-#I#
        #IV#    (y1-y0) = m*(x1-x0)             ## simplify
        #V#     m = (y1-y0)/(x1-x0)             ## solve for m
    
    Now we need to solve for b
    
        #VI#    y0 = (y1-y0)/(x1-x0)*x0 + b     #V# into #I#
        #VII#   b = y0 - x0*(y1-y0)/(x1-x0)     ## solve for b
    
    Plug into the generic equation
    
        #VIII#  y = m*x + b                                         ## generic
        #IX#    y = (y1-y0)/(x1-x0)*x + y0 - x0*(y1-y0)/(x1-x0)     #V# and #VII# into #VIII#
        #X#     y = ( (y1-y0)*x - (y1-y0)*x0 )/(x1-x0) + y0         ## bring most over common denominator
        #XI#    y = ( y1*(x-x0) - y0*(x-x0) )/(x1-x0) + y0          ## group the y1's and the x1's
        #XII#   y = ( (y1-y0)*(x-x0) )/(x1-x0) + y0                 ## combine the multipliers of (x-x0)
        #XIII#  y = (x-x0)*(y1-y0)/(x1-x0) + y0                     ## reorder, remove extra parens
    
    Convert to your notation
        x0 => $min
        x1 => $max
        x  => $tap
        y0 => $new_min
        y1 => $new_max
        y => $x
    
        y = (x-$min)*(y1-y0)/(x1-$min) + y0                         ## substitute for x0 into #XIII#
        y = (x-$min)*(y1-y0)/($max-$min) + y0                       ## substitute for x1 into prev
        y = ($tap-$min)*(y1-y0)/($max-$min) + y0                    ## substitute for x  into prev
        y = ($tap-$min)*(y1-$new_min)/($max-$min) + $new_min        ## substitute for y0 into prev
        y = ($tap-$min)*($new_max-$new_min)/($max-$min) + $new_min  ## substitute for y1 into prev
        $x = ($tap-$min)*($new_max-$new_min)/($max-$min) + $new_min ## substitute for y  into prev
    

    And with my and the end semicolon, you now have the equation that typbalt89 gave: my $x = ($tap-$min)*($new_max-$new_min)/($max-$min) + $new_min;

      stevieb: pyrt's equation #XIII# is the key here.

      I am probably labouring the point, but the process is to subtract the input min and divide by the input range to normalise into the interval 0,1, then rescale the result to the new range and shift it to the new minimum.

      Another way of describing it is that it is four steps of shift, scale, rescale, and re-shift.

        "shift, scale, rescale, and re-shift"

        Excellent !!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1231041]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (5)
As of 2024-04-20 00:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found