Multiplying multidimensional arrays by one dimensional arrays Python - python

I want to do matrix multiplication with my function that takes 2 matrixs as parameters. My code works for all the test cases except
mul([0, 1, 2],[[0], [1], [2]])= [0, 1, 4]
which should = [5]. Any idea why?
rows_A = get_rowCount(A)
cols_A = get_columnCount(A)
rows_B = get_rowCount(B)
cols_B = get_columnCount(B)
if cols_A != rows_B:
return 'Error(mul): size mismatch'
if isinstance(A[0],list) == False:
# if one is 1d and other is 2d:
if isinstance(B[0], list):
new_list = []
for i in B:
new_list.append(i[0])
B = new_list
return [a*b for a,b in zip(A,B)]
# Create the result matrix
# Dimensions would be rows_A x cols_B
C = [[0 for row in range(cols_B)] for col in range(rows_A)]
for i in range(rows_A):
for j in range(cols_B):
for k in range(cols_A):
C[i][j] += A[i][k] * B[k][j]
return C

Related

Do not evaluate the diagonal of a matrix Python

I am making a program that compares the elements A[i,j] with A[j,i], if it is true once that A[i,j] = A[j,i]= 1, the matrix will not be antisymmetric. In the comparison, the elements A[i,j] where i=j (diagonal of the matrix) should not be evaluated.
import numpy as np
A = np.array([[1,0,0],[0,0,0],[0,0,1]])
for i in range (0,2):
for j in range (0,2):
if A[i,j] ==1 and A[i,j] == A[j,i]:
print('A is not antisymmetric')
antisymmetric = False
break
I have tried to add the condition i != j to not evaluate the diagonal, but it has not worked
It looks like your original example had a typo, as you were checking for values of the matrix to be literally 1, which is not relevant to the matrix being antisymmetric?
You were after:
import numpy as np
def is_antisymmetric(a):
r, c = a.shape
if r != c:
return False
for i in range(r):
for j in range(c):
if a[i, j] != -a[j, i] and j != i:
return False
return True
print(is_antisymmetric(np.array(
[[1,0,-1], [0,0,0], [1,0,1]]
)))
Or, briefer:
def is_antisymmetric(a):
return (
(s := a.shape[0]) == a.shape[1] and
(all(a[i, j] == -a[j, i] or j == i for i in range(s) for j in range(s)))
)

How do I find the index of variable b from list a?

How do I find the index of variable b from list a?
I suspect that the problem is in the data types.
a=[-202516736, '-202516736', '13886', '678280946', '14514', '330251838', '14511', '639566631', '14510', '542472303', '14506']
b=['678280946']
a_INT = [int(item) for item in a]
b_INT = [int(item) for item in b]
j = 0
while True:
try:
i = a_INT.index(b_INT, j)
print(i)
j = i + 1
except:
break
Let's take this a step further and add another value to the b list and also add a duplicate in the a list. Then:
a=[-202516736, '-202516736', '13886', '678280946', '14514', '678280946', '330251838', '14511', '639566631', '14510', '542472303', '14506']
b=['678280946', 13886]
ai = list(map(int, a))
for n in map(int, b):
offset = 0
r = []
while True:
try:
i = ai[offset:].index(n)
r.append(offset+i)
offset += i + 1
except ValueError:
break
print(f'{n} occurs at {r}')
Output:
678280946 occurs at [3, 5]
13886 occurs at [2]
Version 2:
The first piece of code is functionally correct. However, it could be very inefficient if the list being searched is very large.
Python's built-in sort function is very fast. So, let's build a list of 2-tuples each made up of a value from the list and its original index. Then sort the new list. Now that it's sorted we can perform a binary search and move on from there.
Added some more values to the OP's original list for demonstration purposes:
a = [-202516736, '-202516736', '13886', '678280946', '14514', '678280946',
'330251838', '14511', '639566631', '14510', '542472303', '14506', '678280946']
b = ['678280946', 13886, 14514, '-202516736', 99]
def bsearch(lst, x):
L = 0
R = len(lst) - 1
while L <= R:
m = (L + R) // 2
if (v := lst[m][0]) == x:
return m
if v < x:
L = m + 1
else:
R = m - 1
return -1
def findall(list_, n):
templist = sorted((v, i) for i, v in enumerate(list_))
result = None
if (i := bsearch(templist, n)) >= 0:
result = [templist[i][1]]
for j in range(i-1, -1, -1):
if templist[j][0] != n:
break
result.append(templist[j][1])
for j in range(i+1, len(templist)):
if templist[j][0] != n:
break
result.append(templist[j][1])
return result
ai = list(map(int, a))
for n in map(int, b):
print(f'{n} -> {findall(ai, n)}')
Output:
678280946 -> [5, 3, 12]
13886 -> [2]
14514 -> [4]
-202516736 -> [0, 1]
99 -> None
a=[-202516736, '-202516736', '13886', '678280946', '14514', '330251838', '14511', '639566631', '14510', '542472303', '14506']
b=['678280946']
for item in b:
print(a.index(item))
Since b has only one element the output is 3.

ValueError: non-broadcastable output operand with shape (1,) doesn't match the broadcast shape (0,)

I am trying to understand the mergeSort algorithm and ran the code provided on this link (https://medium.com/#ssbothwell/counting-inversions-with-merge-sort-4d9910dc95f0)
However, I get the error ValueError: non-broadcastable output operand with shape (1,) doesn't match the broadcast shape (0,)
I am unable to understand why this occurs as the code works on smaller examples like arr = [1, 20, 6, 4, 5]. (The array test contains 50 random numbers)
Can someone explain what I'm doing wrong? And can someone also please explain when we get shape(0,)? Is it when the array is empty?
test = numbers[0:50]
def mergeSortInversions(arr):
if len(arr) == 1:
return arr, 0
else:
mid = len(arr)//2
a = arr[:mid]
b = arr[mid:]
a, ai = mergeSortInversions(a)
b, bi = mergeSortInversions(b)
c = []
i = 0
j = 0
inversions = 0 + ai + bi
while i < len(a) and j < len(b):
if a[i] <= b[j]:
c.append(a[i])
i += 1
else:
c.append(b[j])
j += 1
inversions += (len(a)-i)
c += a[i:]
c += b[j:]
return c, inversions
arr = [1, 20, 6, 4, 5]
#print('test', np.shape(test))
x, inv = mergeSortInversions(test)
print(inv)
Ok, I figured it out, you can't add elements to an empty array.
I solved it using the condition
if len(a[i:]) != 0:
c += a[i:]

Matrix rotation, list index out of range

Trying to rotate a matrix of size 3 in counterclockwise direction.
def anti(matrix,n):
while n > 0: # n is the no of rotations
l = len(matrix)
new_matrix = [[row[:] for row in matrix]]
for i in range(l-1,-1,-1):
for j in range(l):
new_matrix[l-i-1][j] = matrix[j][i]
matrix = [row[:] for row in new_matrix]
n -= 1
return matrix
The error I got was:
List index out of range in line 7
There is extra [] in your new_matrix. Which is causing dimension miss match between new_matrix and matrix.
def anti(matrix,n):
while n > 0: # n is the no of rotations
l = len(matrix)
new_matrix = [row[:] for row in matrix]
for i in range(l-1,-1,-1):
for j in range(l):
new_matrix[l-i-1][j] = matrix[j][i]
matrix = [row[:] for row in new_matrix]
n -= 1
return matrix
a = [[1,2,3],[4,5,6],[7,8,9]]
print(anti(a, 3))

Python Matrix Multiplication,

I'm trying to create a python program to perform the strassen and regular matrix multiplication methods. However, when I try to run my strassen function with the randomly generated matrix created with the createRandom Matrix function, get this error:
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
Here's the code. I randomly create a 10x10 matrix, then try to perform Strassen with it, and I get the preceding error. However, when I use the simple 4x4 matrices I have defined at the end, strassen works fine, and it seems my random matrices are being generated without a problem, so I'm not sure where the issue is. Anyone have any ideas?
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)
I would recommend using numpy, in which you can use matrices easily and all these functions already exist.
In the meantime, if you run into index errors in this function try adding something like an assert:
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
However you don't need to write this function at all:
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]]
The last line of the trackback tells you what's wrong:
File "matrixMult.py", line 62, in subMatrix
c.append(a[i][j] - b[i][j])
IndexError: list index out of range
This line contains 4 usages of array index, one of them is out of the range of the array.
To debug this, go to line 62, add a print i,j just before it. You'll get lots of output and the output line just before the exception will tell you what index is out of range. This way it might be possible for you to track down the bug you have here.
"Just debug it"

Categories