对数缩放算法由x而不是y [英] Logarithmic scaling algo by x, not y
问题描述
好吧,好像我变得愚蠢,因为我无法接受以下内容:
我有一组数据y(x)。基本上,x是离散时间(秒),y是一些数据值,取决于x。缩放y很简单:ScaledY = ln(y - min(y)+ 1)。如果我需要压缩数据,让我们说,按分钟,它也很容易:每分钟计算平均y,然后使用上面的公式计算ScaledY。现在,我试图解决的问题是 - 而不是Y,以对数方式缩放X.到目前为止,我唯一的想法就是:
- 将我的数据分为两部分。计算左边所有x的平均y;将右边部分分成两部分,并重复这个除法/计算平均逻辑直到所有处理完毕。
我不喜欢这种方法的原因是平均在左边部分,因为从数学的角度来看这是不正确的。
有没有其他方法或者可能是标准算法?
OK, seems like I got stupid, as I can't embrace myself on the following:
I have a set of data y(x). Basically, x is discrete time (seconds), y is some data values, dependent on that x. Scaling y is simple: ScaledY = ln(y - min(y) + 1). If I need to compress data, let's say, by minute, it's also easy: calc average y for each minute, then calc ScaledY using the above formula. Now, the problem I'm trying to solve is - instead of Y, scale X logarithmically. The only idea that I have so far is this:
- divide my data set in two parts. Calculate average y for all x on the left part; divide right part in two parts, and repeat this divide/calc average logic until all is processed.
The reason I don't like this approach is an "average" on the left part, because this is not correct from a math point of view.
Is there any other approach or may be a standard algo?
推荐答案
感谢CPallini,他给了我一个很好的提示,如果有人有兴趣,我想出了这个功能。 (这是第一个,粗略的代码,但它产生了我正在寻找的东西):
Thanks to CPallini, who gave me a good hint, I came up with this function if anyone is interested. (This is first, rough code, but it produced exactly what I was looking for):
void scaleXLn(std::vector<double>& data, std::vector<double>& result)
{
size_t oldSize = data.size();
size_t newSize = log((double)oldSize);
++newSize; // because it is always truncated during conversion
result.resize(newSize, 0.0);
// now we have "newSize" number of "new" points.
// Let's loop by them:
size_t leftIdx = 0;
for (int i=newSize - 1; i>=0; --i)
{
// get the right index:
size_t rightIdx = i ? oldSize - exp(i) : oldSize - 1;
// now we have "old" interval "left" to "right".
// Our w(x) is 1/log(x + 1)
// Let's calculate weighted average:
double wxSum = 0.0f;
double avg = 0.0f;
for (size_t j = leftIdx; j<=rightIdx; ++j)
{
double wx = 1.0f/log(oldSize - j + 1);
wxSum += wx;
avg += wx*data[j];
}
result[newSize - i - 1] = avg/wxSum;
// next
leftIdx = rightIdx + 1;
}
}
这篇关于对数缩放算法由x而不是y的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!