2013-03-15 4 views
1

저는 strassen과 regular matrix multiplication 방법을 수행하기 위해 파이썬 프로그램을 만들려고합니다. 나는 createRandom 매트릭스 기능을 사용하여 만든 무작위로 생성 매트릭스 내 쉬트 라쎈 기능을 실행하려고 할 때,이 오류를 얻을 :파이썬 매트릭스 곱셈

Traceback (most recent call last): 
    File "matrixMult.py", line 106, in <module> 
    print strassen(c, d, 10) 
    File "matrixMult.py", line 77, in strassen 
    p1 = strassen(addMatrix(a11,a22), addMatrix(b11,b22), n/2) 
    File "matrixMult.py", line 78, in strassen 
    p2 = strassen(addMatrix(a21,a22), b11, n/2) 
    File "matrixMult.py", line 82, in strassen 
    p6 = strassen(subMatrix(a21,a11), addMatrix(b11,b12), n/2) 
    File "matrixMult.py", line 62, in subMatrix 
    c.append(a[i][j] - b[i][j]) 
    IndexError: list index out of range 

이 여기에 코드입니다. 무작위로 10x10 매트릭스를 만든 다음 Strassen을 실행하려고 시도하면 이전 오류가 발생합니다. 그러나 마지막에 정의한 간단한 4x4 행렬을 사용하면 strassen이 올바르게 작동하며 문제없이 임의의 행렬이 생성되어 문제가 어디 있는지 알 수 없습니다. 누구든지 아이디어가 있습니까?

import random 
import time 

random.seed() 


def createEmptyMatrix(x, y): # create empty matrix 
    matrix = [[0 for row in range(x)] for col in range(y)] 
    return matrix 

def createRandomMatrix(size): # create matrix filled with random ints 
    matrix = [] 
    matrix = [[random.randint(1,20) for row in range(size)] for col in range(10)] 
    return matrix 

def regular(a, b): # standard O(n^3) matrix multiplication 
    c = createEmptyMatrix(len(a), len(b[0])) 
    for i in range(len(a)): 
     for j in range(len(b[0])): 
      for k in range(len(b)): 
       c[i][j] += a[i][k]*b[k][j] 
    return c 

def split(matrix): # split matrix into quarters for strassen 
    a = matrix 
    b = matrix 
    c = matrix 
    d = matrix 
    while(len(a) > len(matrix)/2): 
     a = a[:len(a)/2] 
     b = b[:len(b)/2] 
     c = c[len(c)/2:] 
     d = d[len(d)/2:] 
    while(len(a[0]) > len(matrix[0])/2): 
     for i in range(len(a[0])/2): 
      a[i] = a[i][:len(a[i])/2] 
      b[i] = b[i][len(b[i])/2:] 
      c[i] = c[i][:len(c[i])/2] 
      d[i] = d[i][len(d[i])/2:] 
    return a,b,c,d 

def addMatrix(a, b): # add 2 matrices 
    d = [] 
    for i in range(len(a)): 
     c = [] 
     for j in range(len(a[0])): 
      c.append(a[i][j] + b[i][j]) 
     d.append(c) 
    return d 

def subMatrix(a, b): # subtract 2 matrices 
    d = [] 
    for i in range(len(a)): 
     c = [] 
     for j in range(len(a[0])): 
      c.append(a[i][j] - b[i][j]) 
     d.append(c) 
    return d 


def strassen(a, b, n): # strassen matrix multiplication method 
    #base case 
    if n == 1: 
     d = [[0]] 
     d[0][0] = a[0][0] * b[0][0] 
     return d 
    else: 
     a11, a12, a21, a22 = split(a) 
     b11, b12, b21, b22 = split(b) 

     p1 = strassen(addMatrix(a11,a22), addMatrix(b11,b22), n/2) 
    p2 = strassen(addMatrix(a21,a22), b11, n/2) 
    p3 = strassen(a11, subMatrix(b12,b22), n/2) 
    p4 = strassen(a22, subMatrix(b21,b11), n/2) 
    p5 = strassen(addMatrix(a11,a12), b22, n/2) 
    p6 = strassen(subMatrix(a21,a11), addMatrix(b11,b12), n/2) 
    p7 = strassen(subMatrix(a12,a22), addMatrix(b21,b22), n/2) 

    c11 = addMatrix(subMatrix(addMatrix(p1, p4), p5), p7) 
    c12 = addMatrix(p3, p5) 
    c21 = addMatrix(p2, p4) 
    c22 = addMatrix(subMatrix(addMatrix(p1, p3), p2), p6) 

     c = createEmptyMatrix(len(c11)*2,len(c11)*2) 

    for i in range(len(c11)): 
      for j in range(len(c11)): 
       c[i][j]     = c11[i][j] 
       c[i][j+len(c11)]   = c12[i][j] 
       c[i+len(c11)][j]   = c21[i][j] 
       c[i+len(c11)][j+len(c11)] = c22[i][j] 

     return c 

a = [[1,1,1,1],[2,2,2,2],[3,3,3,3],[4,4,4,4]] 
b = [[5,5,5,5],[6,6,6,6],[7,7,7,7],[8,8,8,8]] 
c = createRandomMatrix(10) 
d = createRandomMatrix(10) 
print "Strassen Outputs:" 
#print strassen(c, d, 10) 
print "Should be:" 
print regular(c, d) 
print c 
print d 

print a 
print b 
print strassen(a, b, 4) 
+1

:

def subMatrix(a, b): # subtract 2 matrices assert len(a) == len(b), "Number of rows does not match!" assert len(a[0]) == len(b[0]), "Number of columns does not match!" d = [] for i in range(len(a)): c = [] for j in range(len(a[0])): c.append(a[i][j] - b[i][j]) d.append(c) return d 

전혀이 기능을 작성할 필요가 없습니다 그러나 오류의 원인이되는 코드의 일부를 찾고 해당 함수 만 게시 할 수 있으며 여전히 같은 오류가 발생하는 간단한 예제 입력을 사용하면 도움이됩니다. – askewchan

+2

'numpy' 사용을 고려하십니까? ... – shx2

+0

이 코드는'strassen' 함수에서 두 줄을 언인 트하면 나에게 달려 있습니다 :'c = createEmptyMatrix (...'와'return c') – askewchan

답변

0

트랙백의 마지막 줄은 무엇이 잘못되었는지를 알려줍니다 :

File "matrixMult.py", line 62, in subMatrix 
    c.append(a[i][j] - b[i][j]) 
    IndexError: list index out of range 

이 줄은 배열 인덱스, 그 중 하나가 배열의 범위를 벗어 4 개 용도가 포함되어 있습니다.

이 문제를 디버깅하려면 62 행으로 이동하여 바로 앞에 print i,j을 추가하십시오. 예외가 나타나기 전에 많은 출력과 출력 라인을 얻을 수 있습니다. 인덱스가 범위를 벗어 났음을 알려줍니다. 이렇게하면 여기에있는 버그를 추적 할 수 있습니다.

1

내가 쉽게 행렬을 사용할 수있는 numpy,이 모든 기능이 이미 존재를 사용하는 것이 좋습니다 것 "그냥 디버깅". 당신이 인덱스 오류로 실행하면 한편

는이 기능에 assert 같은 것을 추가하려고 :

import numpy as np 
a = np.matrix(np.random.randint(10, size=(3,3))) 
b = np.matrix(np.random.randint(10, size=(3,))).T 

c = a * b 
d = a - b 

print a 
[[5 8 1] 
[7 6 1] 
[9 2 9]] 

print b 
[[5] 
[2] 
[4]] 

print c 
[[45] 
[51] 
[85]] 

print d 
[[ 0 3 -4] 
[ 5 4 -1] 
[ 5 -2 5]]