缩放和插值数组
Scale and interpolate an array
我有一个简单的一维数组,其中包含一些数字(不代表任何与图像有关的内容),以及包含例如
的四个元素
1 5 9 13
现在我想将这个数组缩放 3 倍到 12 个元素的大小,并在新数组元素中线性插入包含的数字。因此,在此缩放操作之后,对于此示例,新数组将包含以下值:
1 2 3 4 5 6 7 8 9 10 11 12 13
我的问题:是否有任何标准 C/C++ function/library/code 可用于执行具有不同数组大小和因子的此类操作?这对我来说听起来像是一个标准问题,人们不必再次重新发明轮子。
谢谢!
C++ 标准库目前不包含此类功能。有一个 proposal 用于添加线性代数支持,但我看不到任何与插值相关的东西,无论如何它可能需要几年才能产生任何成果。
在C++20中,有std::lerp做线性插值。
但是你必须在调整数组大小后手动调用它。类似于:
std::vector<int> grow(const std::vector<int>& v, std::size_t k)
{
if (v.empty()) {
return {};
}
std::vector<int> res(v.size() * (k - 1) + 1);
for (std::size_t i = 0; i + 1 < v.size(); ++i) {
for (std::size_t j = 0; j != k; ++j) {
res[i * k + j] = std::lerp(v[i], v[i + 1], float(j) / k);
}
}
res.back() = v.back();
return res;
}
你想如何处理"before first value"和"after last value"?有3种可能:
a) 压制他们。在这种情况下 1, 4
按 3 倍缩放将变为 1, 2, 3, 4
.
b) 假设数据环绕。在这种情况下 1, 4
按 3 倍缩放将变为 2, 1, 2, 3, 4, 3
.
c) 假设 "before" 和 "after" 是默认值,例如零。在这种情况下 1, 4
按 3 倍缩放将变为 0.66, 1, 2, 3, 4, 2.66
.
您想如何处理舍入?例如(对于整数),1, 2
按 2 倍缩放(使用上面的 "a)")将是 1, 1.5, 2
但 1.5
不是整数而是 "equally close" 到 1
和 2
。这里有 5 种可能性(舍入到负无穷大、舍入到零、远离零舍入、舍入到偶数、舍入到正无穷大)。
现在...
假设有 4 种整数数据类型(8 位、16 位、32 位和 64 位)和 3 种浮点数据类型(32 位、64 位和 80 位),并且因此,数据类型、缩放方法和舍入有“7*3*5= 105
”种可能的排列方式。
您想向 C 标准库添加 105 个不同的函数来涵盖所有这些排列吗?
如果你这样做;那么缩放 2D 数组和缩放 "array of structure/bitfield" 以及...呢?当然,这些东西都是更经常需要的。
在缩放原始数的二维数组成为目前甚至没有的库中的 "next least infrequently desired" 功能之前,需要将多少百万个很少需要的函数添加到标准库中支持非常基本的东西(比如 beep(frequency)
)?
我有一个简单的一维数组,其中包含一些数字(不代表任何与图像有关的内容),以及包含例如
的四个元素1 5 9 13
现在我想将这个数组缩放 3 倍到 12 个元素的大小,并在新数组元素中线性插入包含的数字。因此,在此缩放操作之后,对于此示例,新数组将包含以下值:
1 2 3 4 5 6 7 8 9 10 11 12 13
我的问题:是否有任何标准 C/C++ function/library/code 可用于执行具有不同数组大小和因子的此类操作?这对我来说听起来像是一个标准问题,人们不必再次重新发明轮子。
谢谢!
C++ 标准库目前不包含此类功能。有一个 proposal 用于添加线性代数支持,但我看不到任何与插值相关的东西,无论如何它可能需要几年才能产生任何成果。
在C++20中,有std::lerp做线性插值。
但是你必须在调整数组大小后手动调用它。类似于:
std::vector<int> grow(const std::vector<int>& v, std::size_t k)
{
if (v.empty()) {
return {};
}
std::vector<int> res(v.size() * (k - 1) + 1);
for (std::size_t i = 0; i + 1 < v.size(); ++i) {
for (std::size_t j = 0; j != k; ++j) {
res[i * k + j] = std::lerp(v[i], v[i + 1], float(j) / k);
}
}
res.back() = v.back();
return res;
}
你想如何处理"before first value"和"after last value"?有3种可能:
a) 压制他们。在这种情况下 1, 4
按 3 倍缩放将变为 1, 2, 3, 4
.
b) 假设数据环绕。在这种情况下 1, 4
按 3 倍缩放将变为 2, 1, 2, 3, 4, 3
.
c) 假设 "before" 和 "after" 是默认值,例如零。在这种情况下 1, 4
按 3 倍缩放将变为 0.66, 1, 2, 3, 4, 2.66
.
您想如何处理舍入?例如(对于整数),1, 2
按 2 倍缩放(使用上面的 "a)")将是 1, 1.5, 2
但 1.5
不是整数而是 "equally close" 到 1
和 2
。这里有 5 种可能性(舍入到负无穷大、舍入到零、远离零舍入、舍入到偶数、舍入到正无穷大)。
现在...
假设有 4 种整数数据类型(8 位、16 位、32 位和 64 位)和 3 种浮点数据类型(32 位、64 位和 80 位),并且因此,数据类型、缩放方法和舍入有“7*3*5= 105
”种可能的排列方式。
您想向 C 标准库添加 105 个不同的函数来涵盖所有这些排列吗?
如果你这样做;那么缩放 2D 数组和缩放 "array of structure/bitfield" 以及...呢?当然,这些东西都是更经常需要的。
在缩放原始数的二维数组成为目前甚至没有的库中的 "next least infrequently desired" 功能之前,需要将多少百万个很少需要的函数添加到标准库中支持非常基本的东西(比如 beep(frequency)
)?