Normalise values based on two bands - math

I have data that comes from different sources with different typical ranges, like so:
VALUE LOWERBAND UPPERBOUND
5 2 7
6 1 10
2 1 4
22 3 8
...
I would like to normalise VALUEs with respect to LOWERBAND and UPPERBOUND, but as I have no background in statistics I really can't see how it could be done. Any pointers?
To put it in other words, I guess I would like to rescale VALUES so they would all belong to the same LOWERBAND and UPPERBOUND (perhaps the global mean LOWERBANDs and UPPERBOUNDs?)

I guess what you are after is something like the following:
Move the lower bound to zero:
newValue = oldValue - LOWERBOUND
Calculate the value as a percentage of the upper bound (scale 0 - 100)
newValuePercent = (newValue / UPPERBOUND) * 100
In you example the last value is btw. outside the [LOWERBOUND, UPPERBOUND] range... so not sure whether you want to limit it at the end or not

Related

How to increase two values to match a ratio of 17:8 in Google Sheets

If I have two values with a calculated ratio for example:
Value 1 = 5000
Value 2 = 100
Calculated Ratio = 50:1
How do I distribute a value of 500 between value 1 and value 2 so I can get to a 17:8 ratio or as close as possible to 17:8 ratio without decreasing any of the values.
I tried adding all the values and then splitting them into 17:8 ratio but this will in some cases decrease one value to get to another.
Incorrect example as value one has decreased from its original value of 5000:
Value 1 = 3808
Value 2 = 1792
Calculated Ratio = 17:8
You have two equations and two unknowns. The two unknowns are the adjustment values a and b such as the ratio below is known (17/8)
aspect = (value1+a)/(value2+b)
but the combined value of the adjustments has to be a fixed amount (500)
sum = a + b
Soution 1
The solution if the aspect ratio is float type value 17/8=2.125, then the solution is
a = (aspect*(value2+sum) - value1)/(aspect+1)
b = (value1 - aspect*value2+sum)/(aspect+1)
In your case I get a = -1192 and b = 1692 for
value1 + a = 3808
value2 + b = 1792
The ratio 3808/1792 = 17/8 and the sum (1692) + (-1192) = 500
Solution 2
The solution if the aspect ratio is a rational number aspect = num/den is:
a = (num*(value2+sum) - den*value1)/(den + num)
b = (den*(value1+sum) - num*value2)/(den + num)
and again the sample calculation is (num=17, den=8)
a = (17*(100+500) - 8*5000)/(8 + 17) = -1192
b = (8*(5000+500) - 17*100)/(8 + 17) = +1692
Adjustments
If you constrain a>=0 and a<=sum as well as b>=0 and b<=sum then you would not reach the aspect ratio.
You can do this will the following code adjusting a and b
if (a<0)
{
a = 0;
b = sum;
}
else if(b<0)
{
a = sum;
b = 0;
}
Graph
Graphically this problem is a follows:
The blue line is the combination of Value 1 and Value 2 that have the aspect ratio desired.
The pink dot is the starting value (5000,100).
The slanted lines are the adjusted Value 1 and Value 2 for a given sum amount to adjust by. I have included lines for 500, 1000, 2000, and 4000.
Where the slanted lines intersect the blue line is the ideal solution. The solution
The red dot is where the above solution(s) lead you before adjustments. After adjusting for non-negative a and b you will end up at the black dot.
In google sheets, you need some extra columns to implement the above
This is not specific to sheets and is a basic math cross multiplication problem
So, 17 is to 8 as 500 is to x
17/8 = 500/x
Cross multiplying give us
8 * 500 = 4,000
17 * x = 17x
solving for x
x = 4,000/17
x = 235.29
This was a really fun problem thanks for sharing it. Solution
Spoiler alert! The integers are 5302 and 298 with a final ratio of 17.79 which can be found in row 303.
Edit 1:
I misunderstood the question. A 17:8 ratio can be simplified to 2.125:1. The spreadsheet lists all of the possible combinations, where the smallest ratio is 8.35:1. Thus it doesn't seem there is a solution close to a 17:8 ratio.

How do you scale game difficulty with a curve?

I would just like to start by saying my calculus is terrible and I have next to no experience with using it.
I am trying to find an algorithm to help scaling in my game. Specifically it should scale the amount of waves that spawn per level. Ideally it will take any number as a level up to the max integer value. There would also be a minimum value and a maximum value that would be the minimum waves and maximum waves. So:
level = 0 to infinity
minValue = 3
maxValue = 40
result = an algorithm that will have a max curvature of the max value and shouldnt exceed it no matter what value the level is. I'm not sure how to calculate this but I think it would also need some kind of threshold that i could control to dictate the curvature based on the the level.
Try the next approach:
mult = Min(1, (level/MaxLevel)**Somepower))
minValue + (maxValue - minValue) * mult
Choose Somepower value suitable for your tasks. For example, value 2 gives parabola (note that value might be less than 1)
If you want more complex curve, show a picture of desired form.
Edit:
For the case when curve tends but does not become above some level, you can choose some function with horizontal asymptote. For example:
max * x /(x+1)
or
max * arctan(k*x) * 2 / Pi

Normalize number between 0 and 1 in user profile

I'm working on user-profile where each term exists in the user-profile have wight and the weight formulated from set of factors such as (duration, total number of visit ...etc) , I need to normalize the result of their summation to be number between 0 and 1, I performed this equation:
(x+y+z+......)/100
Where x, y and z are factors. I have suggested this equation to my self (I'm sorry I'm not very good in math :( ), but unfortunately it returns some value more than 1 , so is there any way that can be applied to limit the result of the summation between 0 and 1?
Many thanks in advance.
Ok, generally, to normalize, this is what you do:
Find the absolute minimum value, and subtract this from your number. (This may be 0, in which case you can skip this step.)
Find the absolute maximum value. Your total range after step 1 will be from 0..(maximum - minimum). Divide your number by this value, and everything will be in the range of 0..1.
To spin it back, you do the opposite: take your normalized number, multiply by the range (i.e. max - min), then add back the min.
The reason you're having a problem is because x + y + z + ... has a range that is not 100.
Example
If x has a range of 0-10, y has a range of 15-25 and z has a range of 10-25, and your specific values are x = 8, y = 17, z = 12:
x + y + z = 8 + 17 + 12 = 37
min = 0 + 15 + 10 = 25
max = 10 + 25 + 25 = 60
so your normalized value is calculated by doing:
(37 - 25) / (60 - 25) = (12 / 35) = 0.342857 (approximately).
To go back from normalized to a composite number, do the opposite:
0.342857 * 35 = 11.999995 = 12 once rounded.
12 + 25 = 37
If your variables are unbounded, nobody can reach the normalized value 1, because if someone achieved 1, another person with larger factors would exceed 1.
This said, you can transform every factor with a function that maps [0 +inf[ to [0 1[, like X/(X+a) or 1-2^(-X/a), where a is some scaling constant (chosen by you). You will apply this transform to the individual factors and average them, or just apply it to the global sum.

Finding the opposite of a number in a 0 to 10 scale

This is probably something silly and simple in vectors or something, but I can't figure it out with my remedial Algebra. (Sorry for the initial confusion, I didn't fully explain this as I didn't think the 2nd half of my operation was relevant.)
I have a variable between 0 and 10. I want to find its opposite in that same scale, but I also want to change the "depth" of what that opposite means.
Variables:
X = User input variable between 0-10 (really 0-1.0)
Y = User input Depth between 0-10 (really 0-1.0)
Z = My result I'm looking for.
Example if my depth (Y) is Full (10), X would be:
X=0's opposite would be 10
X=1's opposite would be 9
X=2's opposite would be 8
etc..
Example if my depth (Y) is None (0), X would be:
X=0's opposite would be 0
X=1's opposite would be 1
X=2's opposite would be 2
etc..
I'm trying to accomplish this in Reaktor, a program for designing musical synthesizers. Specifically designing a "depth" parameter on a Chorus effect that inverts the left and right signal delay. So that the "rate" (X in this example) for the left signal is the opposite of the "rate" for the right signal, and the difference of how opposite they are is controlled by the "depth" (Y).
If x is your number, then what you're looking for is simply (10 - x).
edit One functional form that satisfies your updated spec is (x + y - (x * y) / 5.0). This is designed for values of x and y between 0 and 10.
X = 10 - Y where Y is input and X is output
0's opposite is 10: 10 = 10-0
1's opposite is 9: 9 = 10-1
2's opposite is 8: 8 = 10-2

Convert arbitrary length to a value between -1.0 a 1.0?

How can I convert a length into a value in the range -1.0 to 1.0?
Example: my stage is 440px in length and accepts mouse events. I would like to click in the middle of the stage, and rather than an output of X = 220, I'd like it to be X = 0. Similarly, I'd like the real X = 0 to become X = -1.0 and the real X = 440 to become X = 1.0.
I don't have access to the stage, so i can't simply center-register it, which would make this process a lot easier. Also, it's not possible to dynamically change the actual size of my stage, so I'm looking for a formula that will translate the mouse's real X coordinate of the stage to evenly fit within a range from -1 to 1.
-1 + (2/440)*x
where x is the distance
So, to generalize it, if the minimum normalized value is a and the maximum normalized value is b (in your example a = -1.0, b = 1.0 and the maximum possible value is k (in your example k = 440):
a + x*(b-a)/k
where x is >= 0 and <= k
This is essentially two steps:
Center the range on 0, so for example a range from 400 to 800 moves so it's from -200 to 200. Do this by subtracting the center (average) of the min and max of the range
Divide by the absolute value of the range extremes to convert from a -n to n range to a -1 to 1 range. In the -200 to 200 example, you'd divide by 200
Doesn't answer your question, but for future googlers looking for a continuous monotone function that maps all real numbers to (-1, 1), any sigmoid curve will do, such as atan or a logistic curve:
f(x) = atan(x) / (pi/2)
f(x) = 2/(1+e-x) - 1
(x - 220) / 220 = new X
Is that what you're looking for?
You need to shift the origin and normalize the range. So the expression becomes
(XCoordinate - 220) / 220.0
handling arbitrary stage widths (no idea if you've got threads to consider, which might require mutexes or similar depending on your language?)
stageWidth = GetStageWidth(); // which may return 440 in your case
clickedX = MouseInput(); // should be 0 to 440
x = -1.0 + 2.0 * (clickedX / stageWidth); // scale to -1.0 to +1.0
you may also want to limit x to the range [-1,1] here?
if ( x < -1 ) x = -1.0;
if ( x > 1 ) x = 1.0;
or provide some kind of feedback/warning/error if its out of bounds (only if it really matters and simply clipping it to the range [-1,1] isn't good enough).
You have an interval [a,b] that you'd like to map to a new interval [c,d], and a value x in the original coordinates that you'd like to map to y in the new coordinates. Then:
y = c + (x-a)*(c-d)/(b-a)
And for your example with [a,b] = [0,440] and [c,d] = [-1,1], with x=220:
y = -1 + (220-0)*(1 - -1)/(440-0)
= 0
and so forth.
By the way, this works even if x is outside of [a,b]. So as long as you know any two values in both systems, you can convert any value in either direction.

Resources