How to print a matrix with a certain pattern in python - python

How can we create a pattern using Python which will create a square Matrix it will put values of diagonal elements equal to zero change the value of elements above diagonal elements 29 and change the values below that a diagonal equals to 5.
For example:
Input: 4
Output:
0999
5099
5509
5550
Please Help. Thanks

If you just have to print, you can try following
for i in range(n):
for j in range(n):
# diagonal case
if i == j:
print(0, end='')
# upper diagonal case
elif i < j:
print(9, end='')
# lower diagonal case
else:
print(5, end='')
print('')

Try using the numpy library.
import numpy as np
np.identity(4) # This will print out 1 on the diagnoals and 0 on the rest.
After that just use a loop to change all the 1s (diagnoals) to 0s
Then use if statements and loops to identify whether a number is above the 0 or not
Or if you just want to use a matrix with a predefined list, then just use np.array(list)

The key phrases to search for are "upper triangle" and "lower triangle". Once that's done, we can compose the desired output like this:
import numpy as np
shape = (4, 4)
np.tril(np.full(shape, 5), -1) + np.triu(np.full(shape, 9), 1)
How this works:
np.full(shape, fill_value) constructs an array of the given shape, filled with the given number.
np.tril(m, k) returns the lower triangle of the matrix m, from the kth diagonal (with the rest zeroed).
Similarly, np.triu(m, k) returns the upper triangle of the matrix m, from the kth diagonal (with the rest zeroed).

I think this should do the trick
def pattern(size):
for i in range(size):
print('5'*i + '0' + '9'*(size-i-1))
pattern(4)

You need to check the condition for , diagonal (row_index == column_index), upper triangular matrix (column_index > row_index) and lower_triangular matrix (row_index > column_index) and then add values accordingly
def func(n):
l = []
for i in range(n):
tmp = []
for j in range(n):
if j==i:
tmp.append(0)
elif j>i:
tmp.append(9)
elif j<n:
tmp.append(5)
l.append(tmp)
return l

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

I need to transform each element of a matrix if a a condition is met using a comprehension

I have the matrix "array". I need to traverse this matrix, and test each element of it, if element x!=0 else x=0. I've tried to use this but it does not accept the else. To simplify, the dimension is fixed at 500x9. I have done this:
ds_Entropy = [array[i][j] for i in range(500) for j in range(9) if array[i][j] !=0 else "0" for i in range(500) for j in range(9)]
Everything from the else onward is wrong. The above description is simplified, what I really need is:
for a matrix M with elements Mij, if MiJ !=0 then calculate Rij = sum(all column elements of Mij)*LOG(Mij) if Mij !=0 else Mij = 0
If I understood correctly, for each element you are trying to print the value if different than zero and "0" if equals zero. You can do that inline like this:
import numpy as np
r_size = 500
c_size = 9
array = np.random.randint(10, size = (r_size, c_size))
ds_Entropy = [array[i][j] if array[i][j] != 0 else "0" for i in range(r_size) for j in range(c_size)]

Writing constraints for grid squares in python z3

So I'm working with Z3 in python and I have to write constraints/conditions for a "marvellous square" which is just a grid of numbers. the conditions for a marvellous square are:
It is filled with all the integers from 1 to 𝑛**2
Every row in the square sums to the same number t
Every column in the square also sums to that same number t
Both diagonals sum to that same number t
Using the list constraints I've been been able to do the first 1:
aGrid = [ [ Int("x_%s_%s" % (i+1, j+1)) for j in range(n) ] for i in range(n) ]
conditionOne = [ And(1 <= aGrid[i][j], aGrid[i][j] <= n**2) for i in range(n) for j in range(n) ]
So in line 1 I create the instance for an n-by-n grid.
In line 2, I create the first condition where each of the entries is from 1 to n squared
The issue I have now is getting the sum of each column and row and equating them to the same thing in the same constraint. As well as the diagonal constraints. I have a feeling they will all be done in the same constraint, but the list comprenhension is confusing.
Here's one way to do it:
from z3 import *
# Grid size
n = 4
# Total and grid itself
t = Int('t')
grid = [[Int("x_%s_%s" % (i+1, j+1)) for j in range(n)] for i in range(n)]
s = Solver()
# Range constraint
allElts = [elt for row in grid for elt in row]
for x in allElts: s.add(And(x >= 1, x <= n*n))
# Distinctness constraint
s.add(Distinct(*allElts))
# Each row
for row in grid: s.add(t == sum(row))
# Each column
for i in range(n): s.add(t == sum([grid[j][i] for j in range(n)]))
# Each diagonal
s.add(t == sum([grid[i][i] for i in range(len(grid))]))
s.add(t == sum([grid[n-i-1][i] for i in range(len(grid))]))
# Solve:
if s.check() == sat:
m = s.model()
print(f't = {m[t]}')
for row in grid:
for elt in row:
print(f'{str(m[elt]):>3s}', end="")
print("")
else:
print("No solution")
When I run this, I get:
t = 34
7 4 14 9
11 16 2 5
6 13 3 12
10 1 15 8
Which satisfies the constraints.
Note that as n gets larger the time z3 will spend in solving will increase quite a bit. Here're are two ideas to make it go much faster:
Note that t depends on n. That is, if you know n, you can compute t from it. (It'll be n * (n*n + 1) / 2, you can justify to yourself why that's true.) So, don't make t symbolic, instead directly compute it and use its value.
Computing over Int values is expensive. Instead, you should use bit-vector values of minimum size. For instance, if n = 6, then t = 111; and you only need 7-bits to represent this value. So, instead of using Int('x'), use BitVec('x', 7). (It's important that you pick a large enough bit-vector size!)
If you make the above two modifications, you'll also see that it performs better than Int values only.

How to find sum of neighbor elements in a matrix

I am trying to find the sum of neighbors around an element in a matrix and wrote few functions to convert a boolean matrix to 1s and 0s and finding the neighbors. But I'm not sure why it is throwing the following error
matrix=[[True,False,False],[False,True,False],[False,False,False]]
def minesweeper(matrix):
matrix=[[1 if j==True else 0 for j in i] for i in matrix]
bin_mt = matrix.copy()
print(bin_mt)
for i in range(len(matrix)):
for j in range(len(matrix[0])):
matrix[i][j]=get_neighbors(i,j,matrix, bin_mt)
print('matrix: '+str(matrix))
print('bin_mt: '+str(bin_mt))
print(matrix)
return matrix
def get_neighbors(a, b, matrix, bin_mt):
sum=0
if bin_mt[a][b]==1:
return 1
else:
for i in find_neighbor_indices(matrix,a,b):
print(bin_mt[i[0]][i[1]], end=' ')
sum=sum+bin_mt[i[0]][i[1]]
print('--')
return sum
def find_neighbor_indices(matrix, i, j, dist=1):
neighbors = []
irange = range(max(0,i-dist), min(len(matrix), i+dist+1))
if len(matrix) > 0:
jrange = range(max(0, j - dist), min(len(matrix[ 0 ]), j + dist + 1))
else:
jrange = []
for icheck in irange:
for jcheck in jrange:
if icheck != i or jcheck != j:
neighbors.append((icheck, jcheck))
return neighbors
minesweeper(matrix)
PS: I have updated the code. However I created a matrix containing 1's and 0's for comparision and sum of neighbors. But I'm not sure why it is updating the both bin_mat and actual matrix instead of just actual matrix. Could someone help me with that.
No worries. I figured it out. The issue was binary matrix is a shallow copy of actual matrix. Whatever the changes I was making in actual matrix were getting updated in binary matrix. I needed a deep copy instead of shallow.
Solved it using below code.
import copy
bin_mt = copy.deepcopy(matrix)
instead of
bin_mt = matrix.copy()

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