首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将for循环转换为矩阵计算,从np.matmul(1xn,nx1)转换为np.matmul(mxn,nxm)?

将for循环转换为矩阵计算,从np.matmul(1xn,nx1)转换为np.matmul(mxn,nxm)?
EN

Stack Overflow用户
提问于 2020-02-14 09:23:03
回答 3查看 93关注 0票数 0

我有一个线性代数问题,可以将for循环转换为矩阵计算。

代码语言:javascript
复制
def f():
    # w.shape = (n,1)
    # X.shape = (m,n)
    # y.shape = (m,)
    # v.shape = (n,n)
    # c is constant
    for t in range(len(X)): 
        x = X[t].reshape((1,-1))
        flag = np.dot(x, w)*y[t]
        cov = np.matmul(np.matmul(x, v), x.T)  # cov is a scalar

        if flag<1:
            b = 1.0/(cov + c)
            a = max(0.0, 1-flag) * b
            w += a*y[t]*np.matmul(v, x.T)
            v -= b*np.matmul(np.matmul(v, x.T), np.matmul(x, v))
    return w, v

如何删除for循环并将其替换为矩阵计算?

EN

回答 3

Stack Overflow用户

发布于 2020-02-14 10:13:24

您将获取res1的对角线元素。所以您可以使用$np.diagonal来获取对角线元素。

代码语言:javascript
复制
res2 = np.diagonal(np.dot(A[mask], A[mask].T))

希望这能解决你的问题。

票数 2
EN

Stack Overflow用户

发布于 2020-02-14 11:11:27

让我们一步一步地思考这个问题

代码语言:javascript
复制
def f():
    # w.shape = (n,1)
    # X.shape = (m,n)
    # y.shape = (m,)
    # v.shape = (n,n)
    # c is constant
    for t in range(len(X)): 
        x = X[t].reshape((1,-1))

X是(m,n),x是(n,)重塑为(1,n)

代码语言:javascript
复制
        flag = np.dot(x, w)*y[t]

flag is dot of (1,n) with (n,1) => (1,1) times scalar element ofy`;结果标量

将(m,n) X点与(n,1)相加,得到(m,1)?(X@w)*y[:,None] => (m,1)。

另一种方法是X@w[:,0])*y以产生(m,)形状

代码语言:javascript
复制
        cov = np.matmul(np.matmul(x, v), x.T)  # cov is a scalar

matmul/dot xv,(1,n)与(n,n)=> (1,n);matmul/dot与(n,1) => (1,1)

再次使用XX@v (m,n)@(n,n)=>(m,n)另一个(n,1)点生成(m,1)

代码语言:javascript
复制
cov = X@v@X.T


        if flag<1:
            b = 1.0/(cov + c)
            a = max(0.0, 1-flag) * b
            w += a*y[t]*np.matmul(v, x.T)
            v -= b*np.matmul(np.matmul(v, x.T), np.matmul(x, v))

如果flag是(m,1)或(m,),我们就不能使用if。但是我们做了

代码语言:javascript
复制
 mask = flag < 1
 b = 1.0/(cov[mask]+c                  # (k,) (k less than m)
 a = np.amax(0.0, 1-flag[mask]) * b    # (k,)
 w = np.sum(a*y[mask]*(X[mask,:]@v), axis=?)   # ???
 v ???

我还没有弄清楚最后一部分的细节。为了清楚起见,您可能希望命名为X[mask,:]cov[mask]flag[mask]y[mask],这样您现在就有了一堆(p,n)和(p,)形状的数组。

代码语言:javascript
复制
    return w, v
票数 1
EN

Stack Overflow用户

发布于 2020-02-14 13:22:57

我终于弄明白了。感谢@hpaulj

代码语言:javascript
复制
        flag = X@w[:,0]*y #(m,)
        cov = (X[:,None,:]@v@X[:,:,None])[:,0,0] #(m,)

        mask = 1-flag>0   # (p,)

        b = 1.0/(cov[mask]+c)  # (p,)
        a = 1-flag[mask]*b  # (p,)

        tmp1 = a[:,None]*y[mask][:,None]*(X[mask,:]@v) # (p,n)
        w = np.sum(tmp1, axis=0).reshape(w.shape)
        tmp2 = ((v@X.T)@(X@v)).ravel()[:,None]*b  # (n^2,p)
        v = np.sum(tmp2,axis=1).reshape(v.shape)  # (n,n)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60218762

复制
相关文章

相似问题

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