矢量化MATLAB代码

时间:2016-04-21 18:46:08

标签: matlab vectorization

我们假设我们有三个大小相等的m-by-n矩阵:ABC

C中的每一列代表一个时间序列 AC中每个时间序列的最大运行时间(超过固定窗口长度) BC中每个时间序列的最小值(超过固定窗口长度)。

有没有办法以矢量化方式确定T

[nrows, ncols] = size(A);
T = zeros(nrows, ncols);
for row = 2:nrows                           %loop over the rows (except row #1).
    for col = 1:ncols                       %loop over the columns.
        if     C(row, col) > A(row-1, col)
            T(row, col) =  1;
        elseif C(row, col) < B(row-1, col)
            T(row, col) = -1;
        else
            T(row, col) = T(row-1, col);
        end
    end
end

这是我到目前为止所提出的:

T = zeros(m, n);
T(C > circshift(A,1)) =  1;
T(C < circshift(B,1)) = -1;

2 个答案:

答案 0 :(得分:2)

执行此向量化非常困难,因为当前行的输出取决于前一行的输出。做矢量化操作通常意味着每个元素应该使用一些与其周围的其他元素无关的关系独立出来。

如果没有for循环,我对如何实现这一点没有任何意见,但我可以帮助您将操作减少到一个而不是两个。您可以按行向量进行分配,但我无法一次性查看您的所有操作。

因此,请尝试这样的事情:

[nrows, ncols] = size(A);
T = zeros(nrows, ncols);
for row = 2:nrows                           
    out = T(row-1,:); %// Change - Make a copy of the previous row
    out(C(row,:) > A(row-1,:)) = 1; %// Set those elements of C 
                                    %// in the current row that are larger
                                    %// than the previous row of A to 1
    out(C(row,:) < B(row-1,:)) = -1; %// Same logic but for B now and it's 
                                     %// less than and the value is -1 instead
    T(row,:) = out; %// Assign to the output
end

我目前正在弄清楚如何使用任何循环执行此操作。我会告诉你的。

答案 1 :(得分:2)

嗯,问题在于条件语句的ELSE部分的依赖性。因此,经过长时间的精神锻炼,我总结了一种方法,将 hell-outta 的所有内容矢量化。

现在,这种方法基于映射。我们得到与1s部分的2D掩码相对应的列式运行或ELSE孤岛,并为它们分配相同的标签。然后,我们沿每个此类运行的每一列转到start-1并存储该值。最后,将每个这样的start-1索引到带有标记数字的%// Store sizes [m1,n1] = size(A); %// Masks corresponding to three conditions mask1 = C(2:nrows,:) > A(1:nrows-1,:); mask2 = C(2:nrows,:) < B(1:nrows-1,:); mask3 = ~(mask1 | mask2); %// All but mask3 set values as output out = [zeros(1,n1) ; mask1 + (-1*(~mask1 & mask2))]; %// Proceed if any element in mask3 is set if any(mask3(:)) %// Row vectors for appending onto matrices for matching up sizes mask_appd = false(1,n1); row_appd = zeros(1,n1); %// Get 2D mapped indices df = diff([mask_appd ; mask3],[],1)==1; cdf = cumsum(df,1); offset = cumsum([0 max(cdf(:,1:end-1),[],1)]); map_idx = bsxfun(@plus,cdf,offset); map_idx(map_idx==0) = 1; %// Extract the values to be used for setting into new places A1 = out([df ; false(1,n1)]); %// Map with the indices obtained earlier and set at places from mask3 newval = [row_appd ; A1(map_idx)]; mask3_appd = [mask_appd ; mask3]; out(mask3_appd) = newval(mask3_appd); end ,它们将作为映射索引,它将为我们提供在新输出中设置的所有元素。

这是实现所有这些愿望的实施 -

#include <iostream>;

class Vectors {
public:
    Vectors() {};
    Vectors(int a, int b) {
        x = a, y = b;
    }
    int getX() {
        return x;
    }
    int getY() {
        return y;
    }
    float getX() {
        return (float)x;
    }
    float getY() {
        return (float) y;
    }
     friend Vectors operator+(const Vectors& v1, const Vectors& v2);
     friend Vectors operator/(const Vectors& v1, const Vectors& v2);
protected:
    int x, y;
private:

};

Vectors operator+(const Vectors& v1, const Vectors& v2) {
    Vectors brandNew;
    brandNew.x = v1.x + v2.x;
    brandNew.y = v1.y + v2.y;
    return (brandNew);
};

Vectors operator/(const Vectors& v1, const Vectors& v2) {
    Vectors brandNew(v1.x / v2.x, v1.y/v2.y);
    return brandNew;
}

int main() {
    Vectors v1(2, 3);
    Vectors v2(4, 5);
    Vectors v3;
    v3 = v1 + v2;
    Vectors v4 = v1 / v2;

    std::cout << "VECTOR 4 X : " << v4.getX() << std::endl;
    std::cout << "VECTOR 4 Y : " << v4.getY() << std::endl;

    std::cout << "Vector V3 X : " << v3.getX() << std::endl;
    std::cout << "VECTOR V3 Y : " << v3.getX() << std::endl;
}