简体   繁体   中英

Why is numpy.dot() throwing a ValueError: shapes not aligned?

I want to write a program that finds the eigenvectors and eigenvalues of a Hermitian matrix by iterating over a guess (Rayleigh quotient iteration). I have a test matrix that I know the eigenvectors and eigenvalues of, however when I run my code I receive

ValueError: shapes (3,1) and (3,1) not aligned: 1 (dim 1) != 3 (dim 0)

By splitting each numerator and denominator into separate variables I've traced the problem to the line:

nm=np.dot(np.conj(b1),np.dot(A,b1))

My code:

import numpy as np
import numpy.linalg as npl

def eigen(A,mu,b,err):

    mu0=mu
    mu1=mu+10*err

    while mu1-mu > err:

        n=np.dot((npl.inv(A-mu*np.identity(np.shape(A)[0]))),b)
        d=npl.norm(np.dot((npl.inv(A-(mu*np.identity(np.shape(A)[0])))),b))

        b1=n/d
        b=b1

        nm=np.dot(np.conj(b1),np.dot(A,b1))
        dm=np.dot(np.conj(b1),b1)

        mu1=nm/dm
        mu=mu1

    return(mu,b)

A=np.array([[1,2,3],[1,2,1],[3,2,1]])
mu=4
b=np.array([[1],[2],[1]])
err=0.1

eigen(A,mu,b,err) 

I believe the dimensions of the variables being input into the np.dot() function are wrong, but I cannot find where. Everything is split up and renamed as part of my debugging, I know it looks very difficult to read.

The mathematical issue is with matrix multiplication of shapes (3,1) and (3,1). That's essentially two vectors. Maybe you wanted to use the transposed matrix to do this?

nm = np.dot(np.conj(b1).T, np.dot(A, b1))
dm = np.dot(np.conj(b1).T, b1)

Have a look at the documentation of np.dot to see what arguments are acceptable.

If both a and b are 1-D arrays, it is inner product of vectors (...)

If both a and b are 2-D arrays, it is matrix multiplication (...)

The variables you're using are of shape (3, 1) and therefore 2-D arrays.

Also, this means, alternatively, instead of transposing the first matrix, you could use a flattened view of the array. This way, it's shape (3,) and a 1-D array and you'll get the inner product:

nm = np.dot(np.conj(b1).ravel(), np.dot(A, b1).ravel())
dm = np.dot(np.conj(b1).ravel(), b1.ravel())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM