【问题标题】:multiplying a vector and a matrix using for nested for loops使用 for 嵌套 for 循环将向量和矩阵相乘
【发布时间】:2021-11-02 10:21:48
【问题描述】:

我想编写一个函数 matvec_row_variant_scalar(A,x) 来实现矩阵向量乘法的标量行变体,其中 A 是二维数组,x 是一维数组。它必须使用两个嵌套循环和对 ???? 条目的标量访问。和 ???? . 这是我尝试过的。

def matvec_row_variant_scalar(A,x):
    y = np.zeros(x.shape)
    for i in range(A.shape[0]):
        for j in range(A.shape[0]):
            A[i,j] =int(x[j])*A[i,j]
            y[j] = A[i,:].sum()
    return y      

A= np.array([[1,0,0],[0,,0],[0,0,1]])
x= np.array([[1], [2], [3]])
print(matvec_row_variant_scalar(A,x))

【问题讨论】:

    标签: python


    【解决方案1】:

    我知道您想要一个列向量b = A * x,其中b[i] = (A[i, :] * x[i]).sum(),其中x 也是一个列向量。您实际上并不需要循环,因为 numpy 可以在没有循环的情况下更快地为您完成此操作。

    A = np.array([[1,0,0],[0,1,0],[0,0,1]])
    x = np.array([[1], [2], [3]])
    
    b = (A * x).sum(axis=1, keepdims=True)
    
    # b = array([[1],
    #       [2],
    #       [3]])
    

    或者,您可以在计算之前简化您的问题: (A[i, :] * x[i]).sum()A[i, :].sum() * x[i] 相同,因此您可以对 A 的行求和 first,然后乘以 x 得到相同的结果。

    b = A.sum(axis=1, keepdims=True) * x
    

    但是,由于您必须有两个循环,(请注意,这会慢得多,尤其是对于较大的数组)

    y = np.zeros(x.shape)
    for i in range(A.shape[0]): # iterate over rows
        for j in range(A.shape[1]): # iterate over columns
            y[i, 0] = y[i, 0] + x[i, 0] * A[i,j] # Keep adding x[i] * A[i, j] to y[i] 
    
    # y = array([[1.],
    #       [2.],
    #       [3.]])
    

    速度对比:

    import timeit
    from matplotlib import pyplot as plt
    
    sizes = [1, 5, 10, 50, 100, 500, 1000, 5000, 10000]
    
    def mult1(A, x):
        return (A * x).sum(axis=1, keepdims=True)
    
    def mult2(A, x):
        return A.sum(axis=1, keepdims=True) * x
        
    def mult3(A, x):
        y = np.zeros(x.shape)
        for i in range(A.shape[0]): # iterate over rows
            for j in range(A.shape[1]): # iterate over columns
                y[i, 0] = y[i, 0] + x[i, 0] * A[i,j] # Keep adding x[i] * A[i, j] to y[i]
        return y
    
    time_vals = np.zeros((len(size),3))
    
    for i, size in enumerate(sizes):
        reps = 10 if size < 1000 else 1
        print(sizes, reps)
        
        A = np.random.random((size, size))
        x = np.random.random((size, 1))
        time_vals[i, 0] = timeit.timeit("mult1(A, x)", setup="from __main__ import A, x, mult1", number=reps) / reps
        time_vals[i, 1] = timeit.timeit("mult2(A, x)", setup="from __main__ import A, x, mult2", number=reps) / reps
        time_vals[i, 2] = timeit.timeit("mult3(A, x)", setup="from __main__ import A, x, mult3", number=reps) / reps
    
    plt.plot(sizes, time_vals[:, 0], label="mult1")
    plt.plot(sizes, time_vals[:, 1], label="mult2")
    plt.plot(sizes, time_vals[:, 2], label="mult3")
    

    给出这个情节。对于显着大小的数组,迭代方法始终比矢量化方法慢 1+ 个数量级。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-21
      • 2021-12-09
      • 2021-09-24
      • 2021-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多