如何使用CUDA推力用下一个非缺失值填充数组中缺失的值?
通过使用带有如何使用CUDA推力用下一个非缺失值填充数组中缺失的值?,cuda,gpgpu,thrust,Cuda,Gpgpu,Thrust,通过使用带有max运算符的CUDA推力,我能够用以前的非缺失值(即左侧最后一个非缺失值)填充缺失值 但如何使用下一个非缺失值(右侧)进行填充?因此,例如,使用0作为缺少的值标记: Input: [0 1 0 0 4 0 6 0] Fill missing from left: [0 1 1 1 4 4 6 6] Fill missing from right: [0 1 4 4 4 6 6 6] <- want 输入:[0 1 0 4 0 6 0
max
运算符的CUDA推力,我能够用以前的非缺失值(即左侧最后一个非缺失值)填充缺失值
但如何使用下一个非缺失值(右侧)进行填充?因此,例如,使用0
作为缺少的值标记:
Input: [0 1 0 0 4 0 6 0]
Fill missing from left: [0 1 1 1 4 4 6 6]
Fill missing from right: [0 1 4 4 4 6 6 6] <- want
输入:[0 1 0 4 0 6 0]
左侧缺少填充:[0 1 1 4 6]
从右开始填充缺失:[0 1 4 4 6 6]从左到右扫描时,max()
对升序值起作用的原因是当前最大值始终高于0
缺失元素,因此它成为填充缺失元素的正确值,即使它有“内存”从一开始就一路走来
如果您只是从右向左扫描,max()
不再工作,因为您有一个递减范围
因此,您似乎需要使用rbegin()
和rend()
从右向左扫描,此外,还需要使用MAX\u INT作为占位符,使用min()
作为运算符
Input: [MAX_INT 1 MAX_INT MAX_INT 4 MAX_INT 6 MAX_INT]
Fill missing from right: [1 1 4 4 4 6 6 MAX_INT]
然后,您需要在左侧和右侧为您的特殊情况捏造一些东西。从左到右扫描时,max()
对升序值起作用的原因是当前最大值将始终高于0
缺少的元素,因此,它成为填充缺失元素的正确值,即使它从一开始就有一个“内存”
如果您只是从右向左扫描,max()
不再工作,因为您有一个递减范围
因此,您似乎需要使用rbegin()
和rend()
从右向左扫描,此外,还需要使用MAX\u INT作为占位符,使用min()
作为运算符
Input: [MAX_INT 1 MAX_INT MAX_INT 4 MAX_INT 6 MAX_INT]
Fill missing from right: [1 1 4 4 4 6 6 MAX_INT]
然后,你需要在左边和右边为你的特殊情况捏造一些东西。函子FillMissing
意味着如果元素为0,用上一个元素替换它,否则保留它。使用反向迭代器时,“previous”表示正确的迭代器
#include <thrust/device_vector.h>
#include <thrust/scan.h>
#include <iterator>
template<class T>
struct FillMissing
{
__host__ __device__ T operator()(const T& res, const T& dat)
{
return dat == T(0) ? res : dat;
}
};
int main()
{
thrust::device_vector<double> vec(8);
vec[1] = 1;
vec[4] = 4;
vec[6] = 6;
thrust::inclusive_scan(
vec.rbegin(), vec.rend(),
vec.rbegin(),
FillMissing<double>());
thrust::copy(
vec.begin(), vec.end(),
std::ostream_iterator<double>(std::cout, " "));
std::cout << std::endl;
}
您可能需要额外的代码来处理尾随的0functorFillMissing
表示如果元素为0,则将其替换为上一个元素,否则保留它。使用反向迭代器时,“previous”表示正确的迭代器
#include <thrust/device_vector.h>
#include <thrust/scan.h>
#include <iterator>
template<class T>
struct FillMissing
{
__host__ __device__ T operator()(const T& res, const T& dat)
{
return dat == T(0) ? res : dat;
}
};
int main()
{
thrust::device_vector<double> vec(8);
vec[1] = 1;
vec[4] = 4;
vec[6] = 6;
thrust::inclusive_scan(
vec.rbegin(), vec.rend(),
vec.rbegin(),
FillMissing<double>());
thrust::copy(
vec.begin(), vec.end(),
std::ostream_iterator<double>(std::cout, " "));
std::cout << std::endl;
}
如果反转数组,您可能需要额外的代码来处理尾随的0?当然,@ks6g10,但我看不出反转数组如何帮助解决上述问题。以相反的方式进行包含式扫描会使[06666]
的max
和[00000000]
的min
成为操作员,而不是需要的[0144466]
。请你澄清一下你的解决方案好吗?非常感谢,“前瞻性”到底是什么意思?(我不知道如何阅读你的O/关系语法)。@MiloChen啊,好的,谢谢你的澄清。@RogerDahl,为你的混淆道歉。我只是想用它后面(右边)的数字填充[0 1 0 0 4 0 6 0]
中的0,或者如果它是数组中最右边的元素,则使用它前面(左边)的元素填充。非常感谢。如果你反转数组?当然可以,@ks6g10,但我不认为反转数组有助于解决上述问题。以相反的方式进行包含式扫描会使[06666]
的max
和[00000000]
的min
成为操作员,而不是需要的[0144466]
。请你澄清一下你的解决方案好吗?非常感谢,“前瞻性”到底是什么意思?(我不知道如何阅读你的O/关系语法)。@MiloChen啊,好的,谢谢你的澄清。@RogerDahl,为你的混淆道歉。我只是想用它后面(右边)的数字填充[0 1 0 0 4 0 6 0]
中的0,或者如果它是数组中最右边的元素,则使用它前面(左边)的元素填充。非常感谢。我用米洛提供的数据测试了代码。如果只有一个尾随的零,它就可以工作。让我澄清一下,如果尾随的零超过一个,它就会失败。@Pavan我认为他的数据的结果将是11444660
是的,你是对的。我用错误的方式测试它。不管怎样,你能编辑你的答案并说后面的零需要特殊的代码吗?我用米洛提供的数据测试了代码。如果只有一个尾随的零,它就可以工作。让我澄清一下,如果尾随的零超过一个,它就会失败。@Pavan我认为他的数据的结果将是11444660
是的,你是对的。我用错误的方式测试它。无论如何,你能编辑你的答案并说尾随的零需要特殊的代码吗?这是可行的,但你能改成asch::minimum()
而不是min
,只是为了弄清楚。还提到您正在使用包含式扫描。这是可行的,但您是否可以更改为推力::最小值()
,而不是min
,只是为了清楚起见。并且还提到您正在使用包容性扫描。