首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对于许多长度可变的数组,向量化prod()调用的方法?

对于许多长度可变的数组,向量化prod()调用的方法?
EN

Stack Overflow用户
提问于 2016-08-25 22:12:30
回答 1查看 48关注 0票数 0

所以我的问题是,我想在没有for循环的情况下这样做。获取多个向量的prod(),但长度不同。

我正在处理与体素相交的光线。我通常有1e6光线和1e5体素,但这可能会有所不同。

intxRays是具有相交体素的光线列表。

gainList是一个一维向量,每个元素都有一个与之前计算的特定光线体素交点相对应的值(实际上是在你可爱的lot here的帮助下)。

rayIntxStartrayIntxEnd是的索引向量,在gainlist数组中,每条光线的相应值开始和结束(它们都是按顺序排列的)。

以下是代码、一些示例和预期输出。

代码语言:javascript
复制
gainSum = zeros(1, 5);

% only interested in the intx uniques
intxSegCtr = 1;

% loop through all of the unique segments
for rayCtr = 1:max(intxRays)

    if rayCtr == intxRays(intxSegCtr)

        startInd = rayIntxStart(intxSegCtr);
        endInd = rayIntxEnd(intxSegCtr);

        % find which rows correspoond to those segements
        gainVals = gainList(startInd:endInd);
        gainProd = prod(gainVals);

        % get the product of the gains for those voxels
        gainSumIdx = intxRays(intxSegCtr);
        gainSum(gainSumIdx) = gainProd;

        % increment counter
        intxSegCtr = intxSegCtr + 1;

    end
end

五条光线和九个体素的示例数据。假设九个体素(在上一步中使用)的体素增益数组如下(为简单起见)。

代码语言:javascript
复制
voxelGains = 10:10:90;

现在假设光线1和3没有命中任何东西,光线2命中体素1和2,光线4命中体素2:7,光线5命中体素6:9

代码语言:javascript
复制
intxRays = [2, 4, 5];

gainList = [10, 20, 20, 30, 40, 50, 60, 70, 60 70, 80, 90];

rayIntxStart = [1, 3, 9];

rayIntxEnd = [2, 8, 12];

对于这些数字,上面的代码将作为结果:

代码语言:javascript
复制
gainSum = [0, 200, 0, 5.0400e+09, 3.024e+07];

我希望这一切都有意义。

当我开发它的时候,我使用了小得多的光线和体素数,它工作得很好。随着我的进步,我的代码中的主要瓶颈就是这个循环。实际上,仅gainValsgainProd分配就占了我运行时的80%和15%。

这是我能找到的唯一一种方法,由于涉及的大小,填充和类似的方法不能工作。

有没有办法在没有这个循环的情况下得到我想要的值?

非常感谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-08-30 21:59:50

好吧,这是一个非常小的性能提升,但它可能会有所帮助。为了在没有循环的情况下测试矩阵方法,需要更大的数据样本。

这是三个解决方案,你的原创,优化和优化的方式作为一个线条。如果这已经为你做了一些事情,你能试一下吗?

代码语言:javascript
复制
clear all
% orignial loop through all Rays
intxRays = [2, 4, 5];
gainList = [10, 20, 20, 30, 40, 50, 60, 70, 60 70, 80, 90];
rayIntxStart = [1, 3, 9];
rayIntxEnd = [2, 8, 12];
gainSum = zeros(1, 5);
tic
% only interested in the intx uniques
intxSegCtr = 1;

% loop through all of the unique segments
for rayCtr = 1:max(intxRays)

    if rayCtr == intxRays(intxSegCtr)

        startInd = rayIntxStart(intxSegCtr);
        endInd = rayIntxEnd(intxSegCtr);

        % find which rows correspoond to those segements
        gainVals = gainList(startInd:endInd);
        gainProd = prod(gainVals);

        % get the product of the gains for those voxels
        gainSumIdx = intxRays(intxSegCtr);
        gainSum(gainSumIdx) = gainProd;

        % increment counter
        intxSegCtr = intxSegCtr + 1;

    end
end
toc

clear all
%loop insted of every single one to max just through the intxRays
intxRays = [2, 4, 5];
gainList = [10, 20, 20, 30, 40, 50, 60, 70, 60 70, 80, 90];
rayIntxStart = [1, 3, 9];
rayIntxEnd = [2, 8, 12];
gainSum = zeros(1, 5);
tic
for rayCtr=1:length(intxRays)
    %no if as you just go through them
    %intxRays(rayCtr) is the corresponding element

     startInd = rayIntxStart(rayCtr);
     endInd = rayIntxEnd(rayCtr);
     % find which rows correspoond to those segements
     gainVals = gainList(startInd:endInd);
     gainProd = prod(gainVals);     

    % get the product of the gains for those voxels and set them to the ray
    gainSum(intxRays(rayCtr)) = gainProd;
end
%disp(gainSum);
toc

clear all
%same as above, but down to 1 line so no additional values are generated
intxRays = [2, 4, 5];
gainList = [10, 20, 20, 30, 40, 50, 60, 70, 60 70, 80, 90];
rayIntxStart = [1, 3, 9];
rayIntxEnd = [2, 8, 12];
gainSum = zeros(1, 5);
tic
for rayCtr=1:length(intxRays)
gainSum(intxRays(rayCtr))=prod(gainList(rayIntxStart(rayCtr):rayIntxEnd(rayCtr)));
end
toc
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39147668

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档