Creating different matrix by same matrix-matrix multiplication inside loop using python - python

I have a square matrix of dimension n*n. I have to define a function which takes this matrix A as input and also a value k.
Matrix A is random matrix generated by numpy random function.
Suppose k=4 then we have to produce three different matrices such that:
matrix_2=A*A
matrix_3=A*A*A
matrix_4=A*A*A*A
Where all multiplication above are matrix multiplication( where columns A = Row of B), not element wise multiplication.
k can have any value given by user. How can we implement this using for loop in python.

Use list or dict for a variable number of variables. In this case, you can use a dictionary comprehension, with dictionary keys aligned with the power:
from numpy.linalg import matrix_power
np.random.seed(0)
n = 2
A = np.random.random((n, n))
def make_arrays(arr, k):
return {i: matrix_power(arr, i) for i in range(1, k+1)}
res = make_arrays(A, 4)
Result:
{1: array([[0.5488135 , 0.71518937],
[0.60276338, 0.54488318]]),
2: array([[0.73228622, 0.78220024],
[0.65924031, 0.72798764]]),
3: array([[0.87337022, 0.94993107],
[0.80060427, 0.86814988]]),
4: array([[1.05190103, 1.14222656],
[0.96267139, 1.04562393]])}

Related

Generating all binary combinations of 2d array in Python

I am trying to generate all possible 2D arrays (of size n*n) of 0 and 1. Since there are two choices for each entry of the 2D array, there are 2^{n^2} such arrays that need to be generated.
I have a code that generates all possible 1D arrays (of size n) of 0 and 1. It is:
def generateAllSpinConfigs(n,arr,l,i):
if i == n:
l.append(arr[:])
return
arr[i] = 0
generateAllSpinConfigs(n,arr,l,i+1)
arr[i] = 1
generateAllSpinConfigs(n,arr,l,i+1)
return l
arr=[None]*n
l=[]
answer=generateAllSpinConfigs(n,arr,l,0)
I understand how that works. In this recursive code, the lowest function call returns an array of all 0 first, then an array with all 0 with a 1 in the last location and so on.
Can we extend this logic to generate all 2D arrays or is there a Python function that does the job that I'm not aware of?
You can use itertools.product. First to generate 1-dimensional lists, and then again to use that as a basis to increase the dimension:
from itertools import product
def get_bin_rows(size):
return product(range(2), repeat=size)
def get_bin_matrices(size):
return product(get_bin_rows(size), repeat=size)
Example use for n=2:
for matrix in get_bin_matrices(2):
# print matrix row by row
for row in matrix:
print(*row)
print() # separate matrix outputs

Multiply each row of a matrix with it's conjugate transposed numpy

I have a numpy.ndarray variable A of size MxN. I wish to take each row and multiply with it's conjugate transposed. For the first row we will get:
np.matmul(np.expand_dims(A[0,:],axis=1),np.expand_dims(A[0,:].conj(),axis=0))
we get an NxN sized result. I want the final result for the total operation to be of size MxNxN.
I can fo this with a simple loop which iterates over the rows of A and concatenates the results. I wish to avoid a for loop for a faster run time with SIMD operations. Is there a way to do this in a single code line with broadcasting?
Otherwise, can I do something else and somehow reshape the results into my requierment?
The next code does what the same as your code snippet but without for-loop. On the other hand, it uses np.repeat twice, so you will need to benchmark both versions and compare them to test their memory/time performance.
import numpy as np
m, n = A.shape
x, y = A.conj().repeat(n, axis=0), A.reshape([-1, 1]).repeat(n, axis=1)
B = (x * y).reshape([m, n, n])
How it works
Basically x holds the conjugate values of the array A in a single column and then is repeated n times on the column axis (it has a shape m*n by n).
y repeats each row in the conjugate matrix of A, n consecutive times (its final shape is m*n by n also)
x and y are multiplied element-wise and the result is unwrapped to a matrix of shape m by n by n stored in B
A list comprehension comprehension could do the trick:
result = np.array([np.matmul(np.expand_dims(A[i,:],axis=1), np.expand_dims(A[i,:].conj(),axis=0)) for i in range(A.shape[0])])

Python - Create sparse matrix representation from 10000 random values

I'm having a homework assignment about airport flights, where at first i have to create the representation of a sparse matrix(i, j and values) for a 1000x1000 array from 10000 random numbers with the following criteria:
i and j must be between 0-999 since are the rows and columns of array
values must be between 1.0-5.0
i must not be equal to j
i and j must be present only once
The i is the departure airport, the j is the arrival airport and the values are the hours for the trip from i to j.
Then i have to find the roundtrips for an airport A with 2 to 8 maximum stops based on the criteria above. For example:
A, D, F, G, A is a legal roundtrip with 4 stops
A, D, F, D, A is not a legal roundtrip since the D is visited twice
NOTE: the problem must be solved purely with python built-in libraries. No external libraries are accepted like scipy and numpy.
I have tried to run a loop for 10000 numbers and assign to row, column and value a random number based on the above criteria but i guess this is not what the assignment asks me to do since the loop doesn't stop.
I guess the i and j are not the actual iloc and j representations of the sparse matrix but rather the values of those? i don't know.
I currently don't have a working code other than the example for the roundtrip implementation. Although will raise an error if the list is empty:
dNext = {
0: [],
1: [4, 2, 0],
2: [1, 4],
3: [0],
4: [3, 1]
}
def findRoundTrips(trip, n, trips):
if (trip[0] == trip[-1]) and (1 < len(trip) <= n + 1):
trips.append(trip.copy())
return
for x in dNext[trip[-1]]:
if ((x not in trip[1:]) and (len(trip) < n)) or (x == trip[0]):
trip.append(x)
findRoundTrips(trip, n, trips)
trip.pop()
Here's how I would build a sparse matrix:
from collections import defaultdict
import random
max_location = 1000
min_value = 1.0
max_value = 5.0
sparse_matrix = defaultdict(list)
num_entries = 10000
for _ in range(num_entries):
source = random.randint(0, max_location)
dest = random.randint(0, max_location)
value = random.uniform(min_value, max_value)
sparse_matrix[source].append((dest, value))
What this does is define a sparse matrix as a dictionary where the key of the dictionary is the starting point of a trip. The values of a key define everywhere you can fly to and how long it takes to fly there as a list of tuples.
Note, I didn't check that I'm using randint and uniform perfectly correctly, if you use this, you should look at the documentation of those functions to find out if there are any off-by-one errors in this solution.

Performing mathematical operations with arrays of arbirary length?

I don't understand this question. Actually just this part;
"Given two vectors of length n that are represented with one-dimensional arrays"
I use two vectors but I don't know what value they have.
For example,
vector can be a = [1,2,3]
but I don't know exactly what are they? What do they have?
Maybe it is a = [3,4,5].
You don't need numpy do something as simple as this.
Instead just translate the formula into Python code:
import math
a = [1, 2, 3]
b = [3, 4, 5]
n = len(a)
# Compute Euclidean distance between vectors "a" and "b".
# First sum the squares of the difference of each component of vectors.
distance = 0
for i in range(n):
difference = a[i] - b[i]
distance += difference * difference
# The answer is square root of those summed differences.
distance = math.sqrt(distance)
print(distance) # -> 3.4641016151377544
Your task is to write code that computes the value if the vectors a and b are given. Your job is not to write down a number.
You could start with this:
distance = 0
for value in a:
[your code]
print(distance)
You could use numpy. Your so called vectors would then correspond to numpy arrays.
import numpy as np
np.sqrt(np.sum(np.power(a-b,2)))
You might need to add this before
a, b = np.array(a),np.array(b)

fast way to get the indices of a lower triangular matrix as 1 dimensional list in python

Given the number of rows (or columns) , n, of a square matrix, I am trying to get the index pairs of the lower triangular matrix in a 1 dimensional list. So far I thought of the following solution:
def getLowerTriangularIndices(n):
inds=[];
for i in range(1,n):
for j in range(i):
inds.append((i,j))
return inds;
Considering the two for loops, it would be far better to have a more efficient way of calculating this maybe using numpy. Does anyone have a suggestion?
Numpy has a method for that...
import numpy as np
# create your matrix. If it's not yet a numpy array, make it one
ar = np.array(matrix)
indices = np.tril_indices_from(ar)
This returns a tuple of two arrays. If you want to have them as lists, you could do
indices = [list(x) for x in np.tril_indices_from(ar)]
You actually do not need to have an array to get the indices, there is also np.tril_indices, which takes the shape as arguments.
So your function would read:
def getLowerTriangularIndices(n):
return [list(x) for x in np.tril_indices(n)]
or if you want a list of tuples instead:
def getLowerTriangularIndices(n):
return zip(*np.tril_indices(n)]

Categories