在Ruby中计算指数衰减值

时间:2015-11-25 00:19:52

标签: ruby math exponential exponent

今天我发现我几乎忘记了所有的高中数学,所以我需要一些帮助来研究Ruby中的一些基础数学。

基本上,我有一组从1到10的值。现在,我只是将它们乘以10得到一个我用作百分比的数字。例如2 = 20%,4 = 40%等。

这有点过于线性,所以我真正需要做的是计算一个指数衰减风格值,其中通过接近1的值给出更大的百分比,数字更接近9和10,百分比变平。

将来可能会有超过10个数字,例如1到20个。我假设这只是改变了吗?

这是一个快速图表,描述了我想要做的事情。

enter image description here

任何人都可以帮我解决这个问题吗?最好是在Ruby中,否则任何伪代码都会有所帮助。

2 个答案:

答案 0 :(得分:2)

首先,您需要具有概率分布函数,比如F(x)。它不需要标准化。在你的情况下(指数衰减),这个函数可能是

F(x) = e^(-kx)

您可以调整k以调整衰减的速度。 然后计算您域名F(x)的范围。

然后计算出它的反函数G(x),即

G(x) = -(1/k)ln(x)

然后您可以按G(rand(range of F))

进行抽样

这是我的红宝石代码:

k = 1

f = -> x {Math.exp(-k * x)}
l, h = f.call(10), f.call(1)

g = -> x {-Math.log(x) / k}
r = -> {rand(h - l) + l}

samples = 10_000.times.map{g.call(r.call)}

samples.count{|x| x < 1}  #=> 6327
samples.count{|x| x < 2}  #=> 8620
samples.count{|x| x < 3}  #=> 9477
samples.count{|x| x < 4}  #=> 9809
samples.count{|x| x < 5}  #=> 9929
samples.count{|x| x < 6}  #=> 9970
samples.count{|x| x < 7}  #=> 9986
samples.count{|x| x < 8}  #=> 9994
samples.count{|x| x < 9}  #=> 9997
samples.count{|x| x < 10}  #=> 10000

答案 1 :(得分:2)

另一条可能适合你的曲线是square / squareroot / parabola

> 11.times{|x| puts "#{x}, #{100-(10-x)**2}"}
0, 0
1, 19
2, 36
3, 51
4, 64
5, 75
6, 84
7, 91
8, 96
9, 99
10, 100

要将比例更改为20,请使用

> 21.times{|x| puts "#{x}, #{100-(10-x/2.0)**2}"}