I am trying to calculate one-step, two-step transition probability matrices for a sequence as shown below :
sample = [1,1,2,2,1,3,2,1,2,3,1,2,3,1,2,3,1,2,1,2]
import numpy as np
def onestep_transition_matrix(transitions):
n = 3 #number of states
M = [[0]*n for _ in range(n)]
for (i,j) in zip(transitions,transitions[1:]):
M[i-1][j-1] += 1
#now convert to probabilities:
for row in M:
s = sum(row)
if s > 0:
row[:] = [f/s for f in row]
return M
one_step_array = np.array(onestep_transition_matrix(sample))
My question, how do we calculate two step transition matrix. because when I manually calculate the matrix it is as below :
two_step_array = array([[1/7,3/7,3/7],
[4/7,2/7,1/7],
[1/4,3/4,0]])
However. np.dot(one_step_array,one_step_arrary) gives me a result which is different and as follows :
array([[0.43080357, 0.23214286, 0.33705357],
[0.43622449, 0.44897959, 0.11479592],
[0.20089286, 0.59821429, 0.20089286]])
Please let me know which one is correct.
You just have to change the transitions index in your for loop:
def twostep_transition_matrix(transitions):
n = 3 #number of states
M = [[0]*n for _ in range(n)]
for (i,j) in zip(transitions,transitions[2:]):
M[i-1][j-1] += 1
#now convert to probabilities:
for row in M:
s = sum(row)
if s > 0:
row[:] = [f/s for f in row]
return M
Related
I am solving some python problems and been bashing my head to solve this task. I need to generate matrix N x N filled with natural numbers where:
Average of numbers in each row is natural number which is present in
that row
Average of numbers in each column is natural number which is
present in that column
All numbers in matrix are different
So far I have generated matrix and tried with random.choice but I don't see a way to handle it so that both row and columns have average present in that row/column.
Here is my code:
import random
used_numbers = []
matrix = []
matrix_done = False
rows_generated = 0
n = int(input("please enter number for nxn matrix: "))
start = 1
max_n = n
while(matrix_done is False):
row = random.sample(range(start, max_n + 1), n)
average = sum(row) / len(row)
print("row", row, average)
start = max_n + 1
max_n = max_n + n
print("start***", start, max_n)
matrix.append(row)
if(average > 0 and average.is_integer()):
print("is integer true")
rows_generated += 1
if(rows_generated == n):
matrix_done = True
for row in matrix:
print(row)
I created the code below using the following principle:
If n is even: it is just an arithmetic progression
If n is odd: we have to compensate the last element of each line, column and the very last of them to ensure the average is inside the matrix
I defined a the start at 10 so it makes easy to check results. But you can make it start in any given random number if you wish.
import random
import numpy as np
# Get user inputs
n = int(input("please enter number for nxn matrix: "))
s = 10 # First element in the matrix. Can use random.randint(1, 100)
r = 2 # Arithmetic progression ratio
c = n*(r + 1) # How much change from one line to another. Use it to avoid having the same numbers
# Now we have to scenarios: the calculation is done differently if n is iven or odd
if (n % 2 == 0):
elements = []
for i in range(n):
for j in range(n):
e = s + r*j + c*i
if j == n - 1 and i == n - 1: # Last element of the matrix
e += c*n/2 + n
elif j == n - 1: # last element of the line
e += r*n/2
elif i == n - 1: # last element of the column
e += c*n/2
else:
pass
elements.append(e)
else:
# If the number is even, we just need to create an arithmetic progression and reshape it into a matrix
elements = [s + r*i for i in range(n*n)]
matrix = np.reshape(elements, (n, n))
print(matrix)
I am trying to write a function to find the maximum value of the sums of each value in each column of a matrix without using a numpy function.
For example, given the following array, I want the answer 2.7657527806024733.
A = np.array([[0.94369777, 0.34434054, 0.80366952, 0.665736],
[0.82367659, 0.13791176, 0.6993436, 0.44473609],
[0.82337673, 0.56936686, 0.46648214, 0.50403736]])
This is the code I have so far:
def L1Norm(M):
x = 0
S = np.shape(M)
N = S[0]
P = S[1]
answer = np.zeros((1, P))
for j in range(P):
t = 0
for i in M:
t += np.abs(i[j])
answer = np.append(answer, t)
s = np.shape(answer)
n = s[0]
p = s[1]
for j in range(p):
if answer[0][j] > x:
x = answer[0][j]
return x
But I keep getting the following error:
IndexError Traceback (most recent call last)
<ipython-input-113-e06e08ab836c> in <module>
----> 1 L1Norm(A)
<ipython-input-112-624908415c12> in L1Norm(M)
12 s = np.shape(answer)
13 n = s[0]
---> 14 p = s[1]
15 for j in range(p):
16 if answer[0][j] > x:
IndexError: tuple index out of range
Any ideas about how I could fix this?
Heres my solve. I loop over the columns and push each sum into an array. Then i loop over that array to find the largest value. It's very verbose but it doesn't use numpy for anything but creating the matrix.
import numpy as np
matrix = np.array([[0.94369777, 0.34434054, 0.80366952, 0.665736],
[0.82367659, 0.13791176, 0.6993436, 0.44473609],
[0.82337673, 0.56936686, 0.46648214, 0.50403736]])
matrixShape = np.shape(matrix)
i = 0
j = 0
sumsOfColumns = []
while j < matrixShape[1]:
sumOfElems = 0
i = 0
while i < matrixShape[0]:
sumOfElems += matrix[i,j]
i += 1
sumsOfColumns.append(sumOfElems)
j += 1
print(sumsOfColumns)
maxValue = 0
for value in sumsOfColumns:
if value > maxValue:
maxValue = value
print(maxValue)
repl: https://repl.it/#ShroomCode/FrequentFunnyDisplaymanager
If you're looking to get a max sum of columns, here is a super simple approach using a pandas.DataFrame:
import numpy as np
import pandas as pd
vals = np.array([[0.94369777, 0.34434054, 0.80366952, 0.665736],
[0.82367659, 0.13791176, 0.6993436, 0.44473609],
[0.82337673, 0.56936686, 0.46648214, 0.50403736]])
# Store values to a DataFrame.
df = pd.DataFrame(vals)
# Get the max of column sums.
max_sum = df.sum(axis=0).max()
As a Function:
def max_col_sum(vals):
max_sum = pd.DataFrame(vals).sum(axis=0).max()
return max_sum
Output:
2.59075109
With numpy you can get each column as an array by using my_np_array[:,column_number]
So using this you can do a for loop:
sums = []
for i in range(0, np.shape(my_np_array)[0] + 1):
sums.append(sum(my_np_array[:,i]))
max_sum = max(sums)
To solve without numpy, we can go through each row adding each value to its corresponding column tally:
import numpy as np
answer = np.array([[0.94369777, 0.34434054, 0.80366952, 0.665736],
[0.82367659, 0.13791176, 0.6993436, 0.44473609],
[0.82337673, 0.56936686, 0.46648214, 0.50403736]])
# Convert our numpy array to a normal array
a = answer.tolist()
# list comprehension to initialise list
sums = [0 for x in range(len(a) + 1)]
for i in range(0, len(a)):
for j in range(0, len(a[i])):
sums[j] += a[i][j]
# Get the max sum
max_sum = max(sums)
print(max_sum)
Simple answer using zip, np.sum
Code
def L1Norm(M):
return max([np.sum(column) for column in zip(*M)])for column in zip(*M)]
Result
2.59075109
Explanation
List comprehension to loop over data in each column with:
[... for column in zip(*M)]
Sum column values with
np.sum(column)
Compute Max of list comprehension with:
max([...])
Please try the following?-
A.sum(0).max()
or
max(sum(A))
Both should give you the desired answer!
The aim of this program is to build a 3x3 matrix which then reduces additional rows, but, for some reason, after the second row is added to M in the while loop, it replaces it with the new row, rather than adding a third row, and, then, reducing additional (most likely 3) vectors after that. Here's the code:
from sympy import *
init_printing(use_unicode= True)
A = []
def reduceOneRow(M):
k = 0
for i in range(k,min(M.shape)-1):
if M[i,i]!=0 or i ==2:
for j in range(k,min(M.shape)-1):
T = Matrix([M.row(j+1)-(M[j+1,i]/M[i,i])*M.row(i)])
A.append(M[j+1]/M[i,i])
M.row_del(j+1)
M = M.row_insert(j+1,T)
k = k+1
else:
i = i+1
return M
# M = Matrix([[1,1,1],[1,4,7],[3,2,5]])
# reduceOneRow(M)
# A
#The following block of code generates a list of monomials, but not in reverse
#lexicagraphical order. This can be fixed later. Ultimately, I'd like to
#make it it's own function
sigma = symbols('x1:4')
D = [1]
for d in D:
for s in sigma:
if s*d not in D:
D.append(s*d)
if len(D) > 20:
break
# print(D)
# print(D[9].subs([('x1',4),('x2',2),('x3',3)]))
#We begin with the set up described in C1
P = [(1,2,3),(4,5,6),(7,8,9)]
G = []
Q = []
S = []
L = [1]
M = Matrix([])
#Here we being step C2.
while L != []:#what follows this while statement is the loop C2-C5 and back
t = L[0]
L.remove(L[0])
K = Matrix([]) #K is a kind of bucket matrix
if t==1: #this block generates the firs line in M. It had to be separate
for j in range(len(P)):#because of the way sympy works. 1 is int, rather
K = K.col_insert(j,Matrix([1])) #than a symbol
else: #here we generate all other rows of M, using K for the name of the rows
for p in P:
K = K.col_insert(0,Matrix([t.subs([(sigma[0],p[0]),(sigma[1],p[1]),(sigma[2],p[2])])]))
# K = K.col_insert(i,Matrix([t.subs([(sigma[0],p[0]),(sigma[1],p[1]),(sigma[2],p[2])]))
M = M.row_insert(min(M.shape)+1,K) #K gets added to M
M
A = []
reduceOneRow(M)#row reduces M and produces the ai in C3
sum = 0
for n in range(len(A)):
sum = sum + A[n]*S[n]
V = M.row(-1)
if V == zeros(1,len(V)):
G.append(t - sum)
M.row_del(-1)
else:
S.append(t-sum)
Q.append(t)
for i in range(1,4):
#if not t*D[i] == Q[0]:
L.append(t*D[i])
L
print('G =',' ',G,' ','Q =',Q)
I figure it out. I changed 'reduceRowOne(M)' to 'M = reduceRowOne'. Ugh.
Thank you all who took a look at this!
I'm about to write some code that computes the determinant of a square matrix (nxn), using the Laplace algorithm (Meaning recursive algorithm) as written Wikipedia's Laplace Expansion.
I already have the class Matrix, which includes init, setitem, getitem, repr and all the things I need to compute the determinant (including minor(i,j)).
So I've tried the code below:
def determinant(self,i=0) # i can be any of the matrix's rows
assert isinstance(self,Matrix)
n,m = self.dim() # Q.dim() returns the size of the matrix Q
assert n == m
if (n,m) == (1,1):
return self[0,0]
det = 0
for j in range(n):
det += ((-1)**(i+j))*(self[i,j])*((self.minor(i,j)).determinant())
return det
As expected, in every recursive call, self turns into an appropriate minor. But when coming back from the recursive call, it doesn't change back to it's original matrix.
This causes trouble when in the for loop (when the function arrives at (n,m)==(1,1), this one value of the matrix is returned, but in the for loop, self is still a 1x1 matrix - why?)
Are you sure that your minor returns the a new object and not a reference to your original matrix object? I used your exact determinant method and implemented a minor method for your class, and it works fine for me.
Below is a quick/dirty implementation of your matrix class, since I don't have your implementation. For brevity I have chosen to implement it for square matrices only, which in this case shouldn't matter as we are dealing with determinants. Pay attention to det method, that is the same as yours, and minor method (the rest of the methods are there to facilitate the implementation and testing):
class matrix:
def __init__(self, n):
self.data = [0.0 for i in range(n*n)]
self.dim = n
#classmethod
def rand(self, n):
import random
a = matrix(n)
for i in range(n):
for j in range(n):
a[i,j] = random.random()
return a
#classmethod
def eye(self, n):
a = matrix(n)
for i in range(n):
a[i,i] = 1.0
return a
def __repr__(self):
n = self.dim
for i in range(n):
print str(self.data[i*n: i*n+n])
return ''
def __getitem__(self,(i,j)):
assert i < self.dim and j < self.dim
return self.data[self.dim*i + j]
def __setitem__(self, (i, j), val):
assert i < self.dim and j < self.dim
self.data[self.dim*i + j] = float(val)
#
def minor(self, i,j):
n = self.dim
assert i < n and j < n
a = matrix(self.dim-1)
for k in range(n):
for l in range(n):
if k == i or l == j: continue
if k < i:
K = k
else:
K = k-1
if l < j:
L = l
else:
L = l-1
a[K,L] = self[k,l]
return a
def det(self, i=0):
n = self.dim
if n == 1:
return self[0,0]
d = 0
for j in range(n):
d += ((-1)**(i+j))*(self[i,j])*((self.minor(i,j)).det())
return d
def __mul__(self, v):
n = self.dim
a = matrix(n)
for i in range(n):
for j in range(n):
a[i,j] = v * self[i,j]
return a
__rmul__ = __mul__
Now for testing
import numpy as np
a = matrix(3)
# same matrix from the Wikipedia page
a[0,0] = 1
a[0,1] = 2
a[0,2] = 3
a[1,0] = 4
a[1,1] = 5
a[1,2] = 6
a[2,0] = 7
a[2,1] = 8
a[2,2] = 9
a.det() # returns 0.0
# trying with numpy the same matrix
A = np.array(a.data).reshape([3,3])
print np.linalg.det(A) # returns -9.51619735393e-16
The residual in case of numpy is because it calculates the determinant through (Gaussian) elimination method rather than the Laplace expansion. You can also compare the results on random matrices to see that the difference between your determinant function and numpy's doesn't grow beyond float precision:
import numpy as np
a = 10*matrix.rand(4)
A = np.array( a.data ).reshape([4,4])
print (np.linalg.det(A) - a.det())/a.det() # varies between zero and 1e-14
use Sarrus' Rule (non recursive method)
example on below link is in Javascript, but easily can be written in python
https://github.com/apanasara/Faster_nxn_Determinant
import numpy as np
def smaller_matrix(original_matrix,row, column):
for ii in range(len(original_matrix)):
new_matrix=np.delete(original_matrix,ii,0)
new_matrix=np.delete(new_matrix,column,1)
return new_matrix
def determinant(matrix):
"""Returns a determinant of a matrix by recursive method."""
(r,c) = matrix.shape
if r != c:
print("Error!Not a square matrix!")
return None
elif r==2:
simple_determinant = matrix[0][0]*matrix[1][1]-matrix[0][1]*matrix[1][0]
return simple_determinant
else:
answer=0
for j in range(r):
cofactor = (-1)**(0+j) * matrix[0][j] * determinant(smaller_matrix(matrix, 0, j))
answer+= cofactor
return answer
#test the function
#Only works for numpy.array input
np.random.seed(1)
matrix=np.random.rand(5,5)
determinant(matrix)
Here's the function in python 3.
Note: I used a one-dimensional list to house the matrix and the size array is the amount of rows or columns in the square array. It uses a recursive algorithm to find the determinant.
def solve(matrix,size):
c = []
d = 0
print_matrix(matrix,size)
if size == 0:
for i in range(len(matrix)):
d = d + matrix[i]
return d
elif len(matrix) == 4:
c = (matrix[0] * matrix[3]) - (matrix[1] * matrix[2])
print(c)
return c
else:
for j in range(size):
new_matrix = []
for i in range(size*size):
if i % size != j and i > = size:
new_matrix.append(matrix[i])
c.append(solve(new_matrix,size-1) * matrix[j] * ((-1)**(j+2)))
d = solve(c,0)
return d
i posted this code because i couldn't fine it on the internet, how to solve n*n determinant using only standard library.
the purpose is to share it with those who will find it useful.
i started by calculating the submatrix Ai related to a(0,i).
and i used recursive determinant to make it short.
def submatrix(M, c):
B = [[1] * len(M) for i in range(len(M))]
for l in range(len(M)):
for k in range(len(M)):
B[l][k] = M[l][k]
B.pop(0)
for i in range(len(B)):
B[i].pop(c)
return B
def det(M):
X = 0
if len(M) != len(M[0]):
print('matrice non carrée')
else:
if len(M) <= 2:
return M[0][0] * M[1][1] - M[0][1] * M[1][0]
else:
for i in range(len(M)):
X = X + ((-1) ** (i)) * M[0][i] * det(submatrix(M, i))
return X
sorry for not commenting before guys :)
if you need any further explanation don't hesitate to ask .
Hello (excuse my English), I have a big doubt in python with matrix multiplication, I create a list of lists and multiplied by a scaling matrix, this is what I've done and I can not alparecer perform a multiplication operation problem with indexes, I check with paper and pencil and it works, I'm doing something bad to accommodate indexes or am I wrong accommodating matrices from the beginning?
def main():
if len(sys.argv) > 1:
v = int(sys.argv[1])
else:
print "error python exe:"
print "\tpython <programa.py> <num_vertices>"
A = []
for i in range(v):
A.append([0]*2)
for i in range(v):
for j in range(2):
A[i][j] = input("v: ")
print A
Escala(A)
def Escala(A):
print "Escala"
sx = input("Sx: ")
sy = input("Sy: ")
S = [(sx,0),(0,sy)]
print S
M = mult(S,A)
print M
def mult(m1,m2):
M = zero(len(m1),len(m2[0]))
for i in range(len(m2)):
for j in range(len(m2[0])):
for k in range(len(m1)):
M[i][j] += m1[k][j]*m2[k][j]
print M
return M
def zero(m,n):
# Create zero matrix
new_matrix = [[0 for row in range(n)] for col in range(m)]
return new_matrix
This seems wrong to me:
M[i][j] += m1[k][j]*m2[k][j]
shouldn't it be:
M[i][j] += m1[i][k]*m2[k][j]