Normalize numbers from 1-.0000X to 1 - 0.0X? - math

I have range of numbers that range from 1 - 0.00000X . Most are small numbers like 0.000823. How can I map them so that they are closer in range ? I used sqrt method but any other suggestions ?
Update
Example
Numbers between 1-0.1 I don't have problem with them . My problem with numbers below 0.1. I need to bring them closer to 0.1.
.00004 -> 0.0004 or 0.004
0.023 -> 0.05 or 0.09

Have you tried logarithms?
If your numbers satisfy eps < x <= 1, the function
y = 1 - C*log(x) where C = 1/-log(eps)
will map the numbers to a range 0..1. If the range isn't required, only that the numbers are close together, you can drop the scale factor.
Edit:
This can be expressed without a subtraction of course.
y = 1 + C*log(x) where C = 1/log(eps)
For example, with an epsilon of 0.0000000001 (10^-10), you get C = -0.1 and:
0.0000000001 => 0
0.000000001 => 0.1
0.00000001 => 0.2
...
0.1 => 0.9
1 => 1
Edit: If you don't want to change the range from 0.1 ... 1.0 but only smaller numbers, then just scale the range from 0 ... 0.1. This can be done by multiplying x with 10 before the function is applied, and divide again by 10 after. Of course in this case use the scale function only if the value is less than 0.1.

Well, a simple way would be to calculate the minimal one (say, 1-t), and remap the segment [1-t, 1] to [0, 1]. The mapping function could be linear:
xnew = (xold - 1) / t + 1
(of course t = 1 - min value)

Related

Is it possible to find a few common multiples of a list of numbers, without them having to be integers?

I don't even know if something like this is possible, but:
Let us say we have three numbers:
A = 6
B = 7.5
C = 24
I would like to find a few evenly spaced common multiples of these numbers between 0 and 2.
So the requirement is: one_of_these_numbers / common_multiple = an_integer (or almost an integer with a particular tolerance)
For example, a good result would be [0.1 , 0.5 , 1 , 1.5]
I have no idea if this is possible, because one can not iterate through a range of floats, but is there a smart way to do it?
I am using python, but a solution could be represented in any language of your preference.
Thank you for your help!
While I was writing my question, I actually came up with an idea for the solution.
To find common divisors using code, we have to work with integers.
My solution is to multiply all numbers by a factor = 1, 10, 100, ...
so that we can act as if they are integers, find their integer common divisors, and then redivide them by the factor to get a result.
Better explained in code:
a = 6
b = 7.5
c = 24
# Find a few possible divisors between 0 and 2 so that all numbers are divisible
by div.
# We define a function that finds all divisors in a range of numbers, supposing
all numbers are integers.
def find_common_divisors(numbers, range_start, range_end):
results = []
for i in range(range_start + 1, range_end + 1):
if all([e % i == 0 for e in numbers]):
results.append(i)
return results
def main():
nums = [a, b, c]
range_start = 0
range_end = 2
factor = 1
results = [1]
while factor < 11:
nums_i = [e * factor for e in nums]
range_end_i = range_end * factor
results += [e / factor for e in find_common_divisors(nums_i, range_start, range_end_i)]
factor *= 10
print(sorted(set(results)))
if __name__ == '__main__':
main()
For these particular numbers, I get the output:
[0.1, 0.3, 0.5, 1, 1.5]
If we need more results, we can adjust while factor < 11: to a higher number than 11 like 101.
I am curious to see if I made any mistake in my code.
Happy to hear some feedback.
Thank you!

What is the difference between Mapreduce and Filter with sum in Julia?

Julia version: 1.4.0
I have these two snippets, I think they should be equivalent but they produce very different results. What am I missing?
samples is Vector{Float64} with 1000000 elements. Moreover, it's a random sampling of a posterior distribution.
mapreduce(p -> p < 0.5 ? 1 : 0, +, samples) / N
sum(filter(x-> x<0.5, samples))/N
Your mapreduce is mapping each element to either 1 or 0. Instead, you want to map each element to either p or 0.
julia> N = 1000000;
julia> samples = randn(1000000);
julia> mapreduce(p -> p < 0.5 ? 1 : 0, +, samples) / N
0.690901
julia> mapreduce(p -> p < 0.5 ? p : -0.0, +, samples) / N
-0.35058272143615
julia> sum(filter(x-> x<0.5, samples))/N
-0.35058272143615005
These may still see a very very slight difference (in this case it's just 1 unit-in-the-last-place) because the results will depend upon the order of summation.

How do I swap around this formula to get the opposite value?

I'm guessing this is simple but I am having a hard time working this out. The formula I have is this: (1-x) / 0.20. x equals between 0.8 and 1. Example:
(1-0.8) / 0.20 = 1
(1-0.9) / 0.20 = 0.5
(1-1) / 0.20 = 0
This is the code I currently have but I a just trying to make it run in the opposite direction button.alpha = (1-x) / 0.20). How do I solve this and what type of math is this called?
To make it run the other way you can just subtract it from 1.
So...
button.alpha = 1 - (1 - x) / 0.2

Looking for a logic to keep a fraction in a range

I need to write some code that can calculate a variable which shows the preference of a consumer to buy a component for his laptop. The preference changes by the tax (T) and the importance of prices on people's purchases (PriceI). I need to include both T and PriceI to find the person's willingness (W) for purchasing a laptop. Tax changes in a slider ranging from 50 Cent to $6 . I want to keep the variable W in a range from 1 to 2, where 1 is when the tax is on its default, minimum values which is 50 cent.
So There are 2 variables that have influence on W:
50<T<600
0.6 < PriceI < 9
Since I want 1<W<2, I thought it should work if I first normalize all the data by dividing them by their max, then in order to find a fraction to be between 1 and 2, I made the numerator to be less than 4 and the denominator to be less than 2, hoping to have the result between 1 to 2 :
to setup-WCalculator
ask consumers [
set PP ((PriceI / 9) * 2)
set TT ((T / 600) * 4)
set W TT / PP
]
end
However, Netlogo makes both PP and TT zero while they should be a small value like 0.15! Does the logic for finding W make sense?
Thanks,
Normalization is normally done with a formula such as
TT = (T - Tmin) / (Tmax - Tmin)
or here
TT = (T - 50) / (600 - 50)
That gives a normalized value between 0 and 1 as T ranges between 50 and 600. If you want TTT to range between 1 and x, where x is > 1, then you can set
TTT = 1.0 + TT * (x - 1.0)
So
TTT = 1.0 + TT * (4.0 - 1.0) = 1.0 + TT * 3.0
will give you a value between 1 and 4.

Python .1 - .1 = extremely small number w/negative exponent?

This has got to be a well-traveled gotcha of some sort. Define the following function foo():
>>> def foo():
... x = 1
... while x != 0:
... x -= .1
... if x < 0:
... x = 0
... print x
So of course, when we call the function, we get exactly what we expect to get.
>>> foo()
0.9
0.8
0.7
0.6
0.5
0.4
0.3
0.2
0.1
1.38777878078e-16 # O_o
0
So, I know that math with integers vs. floating point numbers can get a little weird. Just typing 3 - 2.9 yields such an answer:
>>> 3 - 2.9
0.10000000000000009
So, in fairness -- this is not causing an issue in the script I'm mucking about with. But surely this creeps up and bites people who would actually be affected by values as astronomically small as 1.38777878078e-16. And in order to prevent there from ever being an issue because of the strangely small number, I've got this gem sitting at the bottom of my controller du jour:
if (x < .1 and x > 0) or x < 0:
x = 0
That can't be the solution... unless it totally is. So... is it? If not, what's the trick here?
This can certainly "creep up and bite people", generally when they try to compare floats:
>>> a = 1 / 10
>>> b = 0.6 - 0.5
>>> a == b
False
Therefore it is common to compare floats using a tolerance:
>>> tolerance = 0.000001
>>> abs(a - b) < tolerance
True
This program:
def foo():
x = 1
while x != 0:
x -= .1
if x < 0:
x = 0
print '%.20f' % x
foo()
prints out this:
0.90000000000000002220
0.80000000000000004441
0.70000000000000006661
0.60000000000000008882
0.50000000000000011102
0.40000000000000013323
0.30000000000000015543
0.20000000000000014988
0.10000000000000014433
0.00000000000000013878
0.00000000000000000000
You were not printing the numbers out with enough precision to see what was actually going on. Compare this with the output of print '%.20f' % x when you explicitly set x to 0.9 and 0.8 and so forth. You may want to pay particular attention to the result for 0.5.
You miss the point - that isn't something you want to have a workaround for. Just trust VM, and assume, that it does all the computations as they should be done.
What you want to do, is to format your number. Spot the difference between value, and its representation.
>>> x = 0.9
>>> while x>0.1:
... x -= 0.1
...
>>> x
1.3877787807814457e-16
>>> "{:.2f}".format(x)
'0.00'
Here you have example of showing you value with 2 decimal points. More on formatting (number formatting too) you'll find HERE

Resources