使用对数刻度将事件组映射到片段

Mapping groups of events to segments using a logarithmic scale

我有一些事件(事件组数组),我想使用对数刻度将这些事件映射到片段。

我希望解决方案遵守一些规则:

  1. Math.log(x+1) 必须使用,因为它可以很好地缩放 1 和小于 1 的数字

  2. 我想计算单个段而不是总数

  3. 组i的段总和必须等于另一组的段总和 组 j 如果事件的线性和相等(即如果我有事件 [1, 1] 和 [2] 总 两组的映射段数必须相等)

我开发了您在下面看到的解决方案,但它部分起作用,因为组[0].段的总和不同于组[1].段的总和,因为 log(1+1)+log (1+1) != 日志(2+1)

如何在规则 3 起作用的情况下使用 Math.log(x+1) 来缩放事件?

var logSegmentLen = function(x) {
  return Math.log(x+1);
}

var groupOfSegmentsTotal = function(segmentLenFn) {
  var f = function(arrayOfSegments) {
    let segments = arrayOfSegments.map(segmentLenFn);
    let total = segments.reduce((a,b) => a+b,0);
    return {
      total: total,
      segments: segments      
    }
  }
  return f;
}

var events = [ [1, 1], [2]]
var groups = events.map(groupOfSegmentsTotal(logSegmentLen));
console.log(groups[0].segments, groups[1].segments);
console.log(Math.abs(groups[0].total - groups[1].total) < 0.001); // true must be printed

How can I use Math.log(x+1) to scale the events while having rule 3 working?

显然这是不可能的。您的要求 #3 可以根据给定的比例函数重述 F(x)

sum(Xi) = sum(Yj)  =>  sum(F(Xi)) = sum(F(Yj))

实际上意味着唯一适合它的 F(x)F(x) = k*x 形式,即只是一个线性刻度。任何非线性比例(包括对数)都会违反该要求。您可能应该描述您的更高层次的问题,有人可能会提出该问题的非自相矛盾的翻译。

旁注 证明草图。将 {Xi} 固定为 n 个相同值的集合 x 并将 {Yj} 固定为 m 个相同值 y 的集合。所以

sum(Xi) = n*x
sum(Yj) = m*y
sum(F(Xi)) = n*F(x)
sum(F(Yj)) = m*F(y)

要求变为:

sum(Xi) = sum(Yj)  =>  sum(F(Xi)) = sum(F(Yj))
n*x = m*y => n*F(x) = m*F(y)

这适用于任意整数 nm。现在让我们修复 F(1) = k。这意味着对于任何 m/n F(m/n) = m/n*k。由于实数可以用任意精度的分数来近似,这意味着对于任何 x F(x) = x*k.