计算递减值的算法,接近极限

Algorithm to calculate a diminishing value, approaching a limit

本文关键字:接近 极限 算法 计算      更新时间:2023-09-26

我一直在尝试找到一个Javascript版本,我不久前在LPC中使用过(不是编写的),它被称为dimval(),它的形式是这样的:

NAME
     dimval() - returns values with a reduced increase in output
                as input values grow larger.
SYNOPSIS
     float dimval(float input, float max_input, float max_output,
                  float min_input, float min_output, float rate);
DESCRIPTION
     Returns (as a float) a value between min_output and max_output,
     with values increasing at a reduced rate as they move from
     min_input toward max_output.
     Input is the input value.
     Max_input is the maximum acceptable input. Any higher input
     value will be capped to this.
     Max_output is the maximum value returned.
     Min_input is the (optional) minimum input. Default is zero.
     Min_output is the (optional) minimum output. Default is zero.
     Rate determines how quickly the cost increases to achieve
     greater return values. Higher numbers are faster, lower numbers
     are slower.

读了这篇文章,但它似乎没有捕捉到我想要的东西(一开始看起来要简单得多)。我也读了这个SO问题和...好吧,我认为这可以工作...但老实说,数学超出了我的范围。我了解上面的描述以及参数如何协同工作以产生我想要的结果。

如果有人能在 Javascript 中提供具有上述约束的方法,我将不胜感激。

干杯!

编辑:原始方法的示例输出。

  • 评估返回 dimval(5.0, 100.0, 100.0, 0.0, 0.0, 1.0) => 22.360680
  • 评估返回 dimval(10.0, 100.0, 100.0, 0.0, 0.0, 1.0) => 31.622776
  • 评估返回 dimval(50.0, 100.0, 100.0, 0.0, 0.0, 1.0) => 70.710678

  • 评估返回 dimval(10.0, 100.0, 100.0, 0.0, 0.0, 2.0) => 15.811388

  • 评估返回 dimval(10.0, 100.0, 100.0, 0.0, 0.0, 10.0) => 3.162278

  • 评估返回 dimval(200.0, 100.0, 100.0, 0.0
  • , 0.0, 10.0) => 10.000000

  • 评估返回 dimval(200.0, 100.0, 100.0, 0.0, 0.0, 1.0) => 100.000000

  • 评估返回 dimval(1.0, 100.0, 100.0, 10.0, 0.0, 10.0) => 0.000000


如果您希望我运行更多样本,请告诉我。

也许是这样的?

function dimval(n, min_in, max_in, min_out, max_out, exponent) {
  // unscale input
  n -= min_in
  n /= max_in - min_in
  n = Math.pow(n, exponent)
  // scale output
  n *= max_out - min_out
  n += min_out
  return n
}

0 < exponent < 1先快速增加,然后小幅增加,exponent > 1相反。

例:

> dimval(0, 0, 1, 0, 100, 2)
0
> dimval(0.1, 0, 1, 0, 100, 2)
1.0000000000000002
> dimval(0.2, 0, 1, 0, 100, 2)
4.000000000000001

> dimval(0, 0, 1, 0, 100, 0.5)
0
> dimval(0.1, 0, 1, 0, 100, 0.5)
31.622776601683793
> dimval(0.2, 0, 1, 0, 100, 0.5)
44.721359549995796
> dimval(0.3, 0, 1, 0, 100, 0.5)
54.77225575051661
> dimval(0.4, 0, 1, 0, 100, 0.5)
63.245553203367585
> dimval(0.5, 0, 1, 0, 100, 0.5)
70.71067811865476
> dimval(0.6, 0, 1, 0, 100, 0.5)
77.45966692414834
> dimval(0.7, 0, 1, 0, 100, 0.5)
83.66600265340756
> dimval(0.8, 0, 1, 0, 100, 0.5)
89.44271909999159
> dimval(0.9, 0, 1, 0, 100, 0.5)
94.86832980505137
> dimval(1, 0, 1, 0, 100, 0.5)
100

函数:

function dimval( input, max_in, max_out, min_in, min_out, rate) {
    if (rate < 0.000001) {rate = 0.000001}
    if (input > max_in) {input = max_in}
    if (input < min_in) {input = min_in}
    mult = (max_out - min_out);
    input = (input - min_in) / (max_in - min_in);
    input = Math.sqrt(input) / rate;
    input = (input * mult) + min_out;
    if (input > max_out) {input = max_out}
    return input;
}

测试:

dim1 = 'dimval(5.0, 100.0, 100.0, 0.0, 0.0, 1.0)';
dim2 = 'dimval(10.0, 100.0, 100.0, 0.0, 0.0, 1.0)';
dim3 = 'dimval(50.0, 100.0, 100.0, 0.0, 0.0, 1.0)';
dim4 = 'dimval(10.0, 100.0, 100.0, 0.0, 0.0, 2.0)';
dim5 = 'dimval(10.0, 100.0, 100.0, 0.0, 0.0, 10.0)';
dim6 = 'dimval(200.0, 100.0, 100.0, 0.0, 0.0, 10.0)';
dim7 = 'dimval(200.0, 100.0, 100.0, 0.0, 0.0, 1.0)';
dim8 = 'dimval(1.0, 100.0, 100.0, 10.0, 0.0, 10.0)';

console.log(dim1 + ' => ' + eval(dim1).toFixed(6));
console.log(dim2 + ' => ' + eval(dim2).toFixed(6));
console.log(dim3 + ' => ' + eval(dim3).toFixed(6));
console.log(dim4 + ' => ' + eval(dim4).toFixed(6));
console.log(dim5 + ' => ' + eval(dim5).toFixed(6));
console.log(dim6 + ' => ' + eval(dim6).toFixed(6));
console.log(dim7 + ' => ' + eval(dim7).toFixed(6));
console.log(dim8 + ' => ' + eval(dim8).toFixed(6));

结果:

dimval(5.0, 100.0, 100.0, 0.0, 0.0, 1.0) => 22.360680
dimval(10.0, 100.0, 100.0, 0.0, 0.0, 1.0) => 31.622777
dimval(50.0, 100.0, 100.0, 0.0, 0.0, 1.0) => 70.710678
dimval(10.0, 100.0, 100.0, 0.0, 0.0, 2.0) => 15.811388
dimval(10.0, 100.0, 100.0, 0.0, 0.0, 10.0) => 3.162278
dimval(200.0, 100.0, 100.0, 0.0, 0.0, 10.0) => 10.000000
dimval(200.0, 100.0, 100.0, 0.0, 0.0, 1.0) => 100.000000
dimval(1.0, 100.0, 100.0, 10.0, 0.0, 10.0) => 0.000000

我刚刚通过一个练习来创建类似的东西,并想出了:

z*(最大值 - 最大值-x

其中 z 是起始值,max 是渐近线,x 是变化值。