Python matrix multiplication - result matrix size - python

I am trying to create the product matrix for matrix multiplication in Python, but I am not sure what size the matrix will be as the user can give any input for the matrix multiplication.
I've approached the situation using this for a previous task on matrices when the actual matrix size is provided
product_matrix = [[col for col in range(4)] for row in range(4)]
But I'm not sure how to tackle it in this case.

For x = range(len(B[0])), did you mean x = len(B[0])?
By multiplying A * B, your resulting matrix result should have the num_raw of A and num_col of B.
x = len(B[0]) means that your x is counting how many elements are there for each row of B, that is x is num_col of B. len(A) is counting how many rows are there in A, that is len(A) is num_row of A. Therefore, your result is initialized as "each row has x elements, and there are len(A) rows" with all entries of 0.
And the second line you provided should be in a for-loop, which is exactly the same how you calculate each entry of resulting matrix by hand.

def inMatrix(m,n):#function For Multiplication And Pass Row and col number as Parameter
a=[]#Blank Matrix
for i in range(m):#Row
b=[]#Blank List
for j in range(n):#col
j=int(input("Enter Matrix Elements in pocket ["+str(i)+"]["+str(j)+"]"))
b.append(j)#add element to list
a.append(b)#add List to Matrix
return a #return Matrix
def priMatrix(a):#function for Print Matrix
for i in range(len(a)): #row
for j in range(len(a[0])):#col
print(a[i][j],end=" ") #print Number with space
print()#print line for New row
def multply(a,b):#Multiplication function Pass two Matrix as Parameter
mul=[] #Blank Matrix
sum=0#sum With ) Value
for i in range(len(a)):#row
l=[] #Blank list
for j in range(len(a[0])):#col
for k in range(len(b)):#select
sum=sum+a[i][k]*b[k][j]#sum with Mul
l.append(sum)#add Mul Value
sum=0#Sum 0 For Next Calculation
mul.append(l)#Add List
return mul #return Multiplication Matrix
m=int(input("row"))#First Matrix Row
n=int(input("col"))#First Matrix Col
a=inMatrix(m,n)#First Matrix input
j=int(input("row"))#second Matrix Row
k=int(input("col"))#second Matrix Col
b=inMatrix(j,k)#Second Matrix Input
priMatrix(a)#First Matrix Print
priMatrix(b)#second Matrix Print
c=multply(a,b)#Multiplication Matrix Function Call
priMatrix(c)#Multiplication Matrix Print

Related

sparse matrix multipliction with dictionaris in python

A sparse matrix is a matrix whose most members have zero value. Therefore, in order to save memory and storage
The matrices, it is convenient to represent them using a dictionary in the following configuration: for each cell in the matrix that is not zero, a tuple key will be stored in the dictionary
which represents the coordinates of the cell, and the value represents the value of the cell in the matrix (some number of type int or float) as usual in mathematics,
The indices of the matrix start from one.
• The cell coordinate (j, i) contains natural numbers so that the coordinate represents the cell in the i-th row
and in the jth column.
• The order in the dictionary is not important.
Realize the function sparse_mult(n, mat2, mat1) which receives 2 dictionaries, mat1 and mat2, representing square sparse matrices
of size n×n, and returns a dictionary representing the mat2×mat1 matrix multiplication matrix.
pay attention:
There is no need to check the correctness of the matrices.
It can be assumed that n is a natural number < 1.
The repeated dictionary must represent a sparse matrix as defined above.
for i in range(1, n + 1):
temp = 0
for j in range(1, n + 1):
if (mat1.get((i, j), 0) != 0)|(mat2.get((j, i), 0) != 0):
temp += mat1.get((i, j), 0) * mat2.get((j, i), 0)
if temp !=0:
resultrow[(i, i)]=temp
That's my code, I know I got it wrong but i just don't have a clue
It is inefficient to iterate over all indices in the 2-dimensional index set when multiplying two sparse matrices. Instead, you can iterate over all pairs of keys where 1 pair is drawn from each sparse matrix. Given such a pair (i,j) and (k,l), it contributes a product of 2 numbers if and only if j == k. In this case the corresponding product goes towards entry (i,l) in the overall product. A final dictionary comprehension can get rid of any zero entries. This last step might be inadequate if the numbers are floats and some entries are non-zero only due to round-off error. In that case a threshold approach which removes entries close to zero and not merely equal to zero.
def sparse_multiply(a,b):
c = {}
for i,j in a.keys():
for k,l in b.keys():
if j == k:
p = a[(i,j)]*b[(k,l)]
if (i,l) in c:
c[(i,l)] += p
else:
c[(i,l)] = p
return {k:v for k,v in c.items() if v != 0}
Note that n plays no role here. The complexity is mk where m is the number of non-zero entries in the first matrix and k the number of such entries in the second. For matrices which are very sparse this will be substantially faster than the n^3 of using straight-forward matrix multiplication. There will be some threshold where mk will actually be larger than n^3, but at that stage the matrices are no longer sparse.
so i eventually got it, if anyone care:
initialize the result dictionary
result = {}
# iterate over the rows and columns of the result matrix
for i in range(1, n + 1):
for j in range(1, n + 1):
# initialize the sum to 0
sum = 0
# iterate over the columns of the first matrix and the rows of the second matrix
for k in range(1, n + 1):
# check if the cell (i, k) in the first matrix and the cell (k, j) in the second matrix are non-zero
if (i, k) in mat1 and (k, j) in mat2:
sum += mat1[(i, k)] * mat2[(k, j)]
# add the result to the dictionary if it is non-zero
if sum != 0:
result[(i, j)] = sum
# return the result dictionary
return result

Are there some functions in Python for generating matrices with special conditions?

I'm writing dataset generator on Python and I got following problem: I need a set of zero-one matrices with no empty columns/rows. Also the ratio between zeros and ones should be constant.
I've tried to shuffle zero-one list with fixed ratio of zeros and ones with following reshaping, but for matrices with hundreds of rows/cols it's too long. Also I took into account that I can't achieve some inputs like 3*10 matrix with 9 one-elements and that some inputs can have only solution like 10*10 matrix with 10 one-elements.
If I understand the task, something like this might work:
import numpy as np
from collections import defaultdict, deque
def gen_mat(n, m, k):
"""
n: rows,
m: cols,
k: ones,
"""
assert k % n == 0 and k % m == 0
mat = np.zeros((n, m), dtype=int)
ns = np.repeat(np.arange(n), k // n)
ms = np.repeat(np.arange(m), k // m)
# uniform shuffle
np.random.shuffle(ms)
ms_deque = deque(ms)
assigned = defaultdict(set)
for n_i in ns:
while True:
m_i = ms_deque.popleft()
if m_i in assigned[n_i]:
ms_deque.append(m_i)
continue
mat[n_i, m_i] = 1
assigned[n_i].add(m_i)
break
return mat
We first observe that an n x m matrix can be populated with k ones s.t. equal ratios only k is divisible by both n and m.
Assuming this condition holds, each row index will appear k/n times and each column index will appear m/k times. We shuffle the column indices to ensure that the assignment is random, and store the random column indices in a deque for efficiency.
For each row, we store a set of columns s.t. mat[row, column] = 1 (initially empty).
We can now loop over each row k/n times, picking the next column s.t. mat[row, column] = 0 from the deque and set mat[row, column] to 1.
Without loss, assume that n <= m. This algorithm terminates successfully unless we encounter a situation when all remaining columns in the deque satisfy mat[row, column] = 1. This can only happen in the last row, meaning that we have already assigned k/m + 1 ones to some column, which is impossible.

Function that returns the sum of the elements of a single row of a matrix in Python

So i have a Python program that creates a 3 x 3 matrix (without using numPy). It contains a function that inputs the elements of the matrix, prints it out, and calculates the sum of a single row of the matrix. The latter is the part i'm having issues with. How would i write the getSumRow function, so that it returns the sum of the elements of a single row of the matrix. The function is passed the matrix and the row index.
#Program that creates a 3x3 matrix and prints sum of rows
def getMatrix():
A=[[[] for i in range(3)] for i in range(3)] #creating 2d list to store matrix
for i in range(3): #setting column bounds to 3
for j in range(3): #settting row bounds to 3
number=int(input("Please Enter Elements of Matrix A:"))
A[i][j]=number #fills array using nested loops
return A #returns 2d array (3x3 matrix)
def getSumRow(a,row):
def printMatrix(a):
for i, element in enumerate(a): #where a is the 3x3 matrix
print(*a[i])
#accesses the 2d array and prints them in order of rows and columns
def main():
#includes function calls
mat = getMatrix()
print("The sum of row 1 is", getSumRow(mat,0))
print("The sum of row 2 is", getSumRow(mat,1))
print("The sum of row 3 is", getSumRow(mat,2))
printMatrix(mat)
main()
How can i get it so that when it prints using the getSumRow function, it will print the sum of each row of the matrix individually?
Given a matrix like:
matrix = [
[1, 2, 6],
[5, 8, 7],
[9, 1, 2]
]
You can get a row by indexing (indexes start at 0) into the matrix:
matrix[1] # --> [5, 8, 7]
Since that's just a list, you can call sum() on it:
sum(matrix[1]) # --> 20
sum(matrix[2]) # --> 12

max n * n Reshape 2d numpy array function that discards lowest values and returns sum of col means?

I am working on this problem for my data science class:
Write a function that takes in an integer, and does the following:
Creates an array of the numbers from 0 up to that inputted integer
Reshapes it to be the largest n * n array that it could be, discarding any elements that are extra (i.e. if you want to make a 10 x 10, but have 102 elements, discard the last 2)
Returns the cumulative sum of the column means
I have the following code so far for the matrix reshaping, but it times out for large numbers. Any suggestions on how to complete the first step of this problem would be much appreciated.
import numpy as np
def ranged_arr(n):
ranged_arr = np.arange(0,n+1,1)
if len(ranged_arr)%int(len(ranged_arr)**0.5)== 0:
array = ranged_arr.reshape(int(len(ranged_arr)**0.5),int(len(ranged_arr)**0.5))
return array
else:
len(ranged_arr)%int(len(ranged_arr)**0.5)!= 0
idx = 0
new_arr = np.arange(0,n-idx,1)
while len(new_arr)%int(len(new_arr)**0.5)!= 0:
idx +=1
q = new_arr.reshape(int(len(new_arr)**0.5),int(len(new_arr)**0.5))
return q
From the code that #Alber8295 started, the rest of the problem:
def ranged_arr(n):
#Creates an array of the numbers from 0 up to that inputted integer
ranged_arr = np.arange(0,n+1)
#Reshapes it to be the largest n * n array that it could be
#Find the largest dim
largest_dim = math.floor(math.sqrt(n+1))
#Find the size of the array that will be reshaped
last_index = largest_dim**2
#Take the slice of the original array that could be reshaped
fitted_ranged_arr = ranged_arr[:last_index]
#Finally, reshape it!
reshaped_range_arr = fitted_ranged_arr.reshape((largest_dim,largest_dim))
# get the sum of the col means
#get the means of each col
col_means = np.mean(reshaped_range_arr,axis=0)
# get the sum of the means
sum_of_means = col_means.sum()
#Return everything, so you can check the steps
return ranged_arr,largest_dim,fitted_ranged_arr,reshaped_range_arr,col_means, sum_of_means
print(sum_of_means)
Let's keep it sweet and simple :)
First, let's decompose your problem, you have to:
1. Create an array of the numbers from 0 up to that inputted integer
2. Reshape it to be the largest m x m array that it could be
2.1. Find the largest dimension (m)
Now let's write that Python function!
def ranged_arr(n):
#Creates an array of the numbers from 0 up to that inputted integer
ranged_arr = np.arange(0,n+1)
#Reshapes it to be the largest n * n array that it could be
#Find the largest dim
largest_dim = math.floor(math.sqrt(n+1))
#Find the size of the array that will be reshaped
last_index = largest_dim**2
#Take the slice of the original array that could be reshaped
fitted_ranged_arr = ranged_arr[:last_index]
#Finally, reshape it!
reshaped_range_arr = fitted_ranged_arr.reshape((largest_dim,largest_dim))
#Return everything, so you can check the steps
return ranged_arr,largest_dim,fitted_ranged_arr,reshaped_range_arr
I uploaded it to my Github so you can check it with some tests here

conditional sum over a range python

I have created X as folowing
num_locations = 2
X= [ ]
for n in range(num_locations):
X.append([0 for j in range(num_locations)])
Now I want to sum these X[n][m] values for the case n != m . Such that the result should be like
X[0][1]+X[1][0]
Is there a way to do that with the sum formulation ?
X[n][m] for n in range(num_locations)for m in range(num_locations))
This is effectively taking the sum of the non-diagonal elements of your 2D array. One option using Numpy could simply be to subtract the sum of the main diagonal (np.trace) from the sum of the entire array.
num_locations = 2
X= [[1,2],[2,1]]
import numpy as np
s = np.sum(X) - np.trace(X)
print(s)
Outputs:
4
You can simply use enumerate
>>> sum(o for i, a in enumerate(X) for j, o in enumerate(a) if i!=j)
0
Where i and j are row (1st dim) and column (2nd dim) indices respectively
This should work
sum([sum(row) - (row[i] if len(row) < i else 0) for i,row in enumerate(X)])
It runs over every row in the 2d array, and sums it, then take out the i cell (if exists) so it won't get into sum

Categories