Related
This is the code I have written so far, but I'm not getting my desired output. I want to know what's missing in the code. Any help would be greatly appreciated.
def matVec(matrix,vector):
for i in range(len(matrix)):
result = []
total = 0
for j in range(len(vector)):
total += matrix[i][j] * vector[j]
result.append(total)
return result
matrix_0 = [[1, 2, 3],[2, 3, 4]]
vector_0 = [2, 2]
print(matVec(matrix_0,vector_0))
link to code
This makes the trick. The bug was in the way you declared the original matrix. In particular, you have to declare the matrix grouping the elements in the rows, not the one in the columns like in the starting code
You are going to multiply the elements on the rows of matrix for the elements of the [column] vector in order to respect the rule for a multiplication matrix vs vector. Given a matrix with size a[= rows size, 3 in your case] x b[= columns size, 2 in your case] your vector must have a number of rows equal to b [= 2 in your case]. Given your 2 x 1 vector the final result will be a 3 x 1 vector
Now when you run the code len(matrix) gives back 3, as it should be. If you run the original version you had 2 as value back and that prevented the last calculation to get the remaining third element of the resulting vector [i.e. the final 14]
def matVec(matrix,vector):
result = []
for i in range(len(matrix)):
total = 0
for j in range(len(vector)):
total += matrix[i][j] * vector[j]
result.append(total)
return result
matrix_0 = [[1, 2],[2, 3],[3, 4]]
vector_0 = [2, 2]
print(matVec(matrix_0,vector_0))
My task is to create a program that simulates a discrete time Markov Chain, for an arbitrary number of events. However, right now the part I'm struggling with is creating the right stochastic matrix that will represent the probabilities. A right stochastic matrix is a matrix that has row entries that sum to 1. And for a given size, I kind of know how to write the matrix that does that, however, the problem is that I don't know how to do that for an arbitrary size.
Any help is appreciated.
(Note that this isn't a homework problem, it's only for extra credit in my Math class and the professor doesn't mind the use of outside sources.)
Using #MBo's idea:
In [16]: matrix = np.random.rand(3,3)
In [17]: matrix/matrix.sum(axis=1)[:,None]
Out[17]:
array([[ 0.25429337, 0.22502947, 0.52067716],
[ 0.17744651, 0.42358254, 0.39897096],
[ 0.36179247, 0.28707039, 0.35113714]])
In [18]:
Generate NxN matrix with random values.
For every row:
Find sum of row S
S[j] = Sum(0..N-1){A[j, i]}
Then subtract (S-1)/N from every value in this row
A[j, i] = A[j, i] - (S[j] - 1) / N
If you need only non-negative values, generate non-negative randoms, and divide every value in row by sum of this row
A[j, i] = A[j, i] / S[j]
Here is some code:
import random
precision = 1000000
def f(n) :
matrix = []
for l in range(n) :
lineLst = []
sum = 0
crtPrec = precision
for i in range(n-1) :
val = random.randrange(crtPrec)
sum += val
lineLst.append(float(val)/precision)
crtPrec -= val
lineLst.append(float(precision - sum)/precision)
matrix.append(lineLst)
return matrix
matrix = f(5)
print matrix
I assumed the random numbers have to be positive, the sum of numbers on a raw has to be 1. I used a precision give in variable 'precision', if this is 1000 it means that the random numbers will have 3 digits after the comma. In y example 6 digits are used, you may use more.
Output:
[[0.086015, 0.596464, 0.161664, 0.03386, 0.121997],
[0.540478, 0.040961, 0.374275, 0.003793, 0.040493],
[0.046263, 0.249761, 0.460089, 0.006739, 0.237148],
[0.594743, 0.125554, 0.142809, 0.056124, 0.08077],
[0.746161, 0.151382, 0.068062, 0.005772, 0.028623]]
A right stochastic matrix is a real square matrix, with each row summing to 1.
Here's a sample you can create a function from, I leave that to you as homework
In [26]: import numpy as np
In [27]: N, M = 5, 5
In [28]: matrix = np.random.rand(N, M)
In [29]: matrix
Out[29]:
array([[ 0.27926909, 0.37026136, 0.35978443, 0.75216853, 0.53517512],
[ 0.93285517, 0.54825643, 0.43948394, 0.15134782, 0.31310007],
[ 0.91934362, 0.51707873, 0.3604323 , 0.78487053, 0.85757986],
[ 0.53595238, 0.80467646, 0.88001499, 0.4668259 , 0.63567632],
[ 0.83359167, 0.41603073, 0.21192656, 0.22650423, 0.95721952]])
In [30]: matrix = np.apply_along_axis(lambda x: x - (np.sum(x) - 1)/len(x), 1, matrix)
In [31]: matrix
Out[31]:
array([[ 0.01993739, 0.11092965, 0.10045272, 0.49283682, 0.27584341],
[ 0.65584649, 0.27124774, 0.16247526, -0.12566087, 0.03609139],
[ 0.43148261, 0.02921772, -0.12742871, 0.29700952, 0.36971886],
[ 0.07132317, 0.34004725, 0.41538578, 0.00219669, 0.17104711],
[ 0.50453713, 0.08697618, -0.11712798, -0.10255031, 0.62816498]])
Explanation
We create an N x M matrix
We then calculate the (sum - 1) / N to be subtracted from each item row-wise
Then we apply it to each row of the matrix by using np.apply_along_axis() with axis=1 to be applied on each row
Verify the result
Each row needs to sum up to 1
In [37]: matrix.sum(axis=1)
Out[37]: array([ 1., 1., 1., 1., 1.])
but how do I subtract that value from each entry in the row?
In my example I've used a lambda that is equivalent to this function
def subtract_value(x):
return x - (np.sum(x) - 1)/len(x)
You can pass a function to apply_along_axis() to be called on each element on the axis, in our case it's the rows
There are other ways too like numpy.vectorize() and numpy.frompyfunc
Making a function and apply it like any method from the above is better than looping through each item in each row, faster and less code, easier to read / understand the intent
One small point has been missed. A stochastic matrix is an M x N matrix of non-negative elements which rows sum to 1.0. MBo comment above states that:
If you need only non-negative values, generate non-negative randoms,
and divide every value in row by sum of this row
A[j, i] = A[j, i] / S[j]
This is only true if the stored matrix is comprised entirely of whole numbers (not necessarily integers). Otherwise the resulting matrix may contain negative numbers, the larger the matrix, the more the negative elements.
This can be accomplished using:
X[i, j] = Math.Abs(random.Next(100, 900));
I'm fairly new to Python and trying to create a function to multiply a vector by a matrix (of any column size).
e.g.:
multiply([1,0,0,1,0,0], [[0,1],[1,1],[1,0],[1,0],[1,1],[0,1]])
[1, 1]
Here is my code:
def multiply(v, G):
result = []
total = 0
for i in range(len(G)):
r = G[i]
for j in range(len(v)):
total += r[j] * v[j]
result.append(total)
return result
The problem is that when I try to select the first row of each column in the matrix (r[j]) the error 'list index out of range' is shown. Is there any other way of completing the multiplication without using NumPy?
The Numpythonic approach: (using numpy.dot in order to get the dot product of two matrices)
In [1]: import numpy as np
In [3]: np.dot([1,0,0,1,0,0], [[0,1],[1,1],[1,0],[1,0],[1,1],[0,1]])
Out[3]: array([1, 1])
The Pythonic approach:
The length of your second for loop is len(v) and you attempt to indexing v based on that so you got index Error . As a more pythonic way you can use zip function to get the columns of a list then use starmap and mul within a list comprehension:
In [13]: first,second=[1,0,0,1,0,0], [[0,1],[1,1],[1,0],[1,0],[1,1],[0,1]]
In [14]: from itertools import starmap
In [15]: from operator import mul
In [16]: [sum(starmap(mul, zip(first, col))) for col in zip(*second)]
Out[16]: [1, 1]
I think the problem with your code was that you loop through the rows of the matrix rather than by the columns. Also you don't reset your 'total' variable after each vector*matrix column calculation. This is what you want:
def multiply(v, G):
result = []
for i in range(len(G[0])): #this loops through columns of the matrix
total = 0
for j in range(len(v)): #this loops through vector coordinates & rows of matrix
total += v[j] * G[j][i]
result.append(total)
return result
i have attached a code for matrix multiplication do follow the example format for one dimensional multiplication (lists of list)
def MM(a,b):
c = []
for i in range(0,len(a)):
temp=[]
for j in range(0,len(b[0])):
s = 0
for k in range(0,len(a[0])):
s += a[i][k]*b[k][j]
temp.append(s)
c.append(temp)
return c
a=[[1,2]]
b=[[1],[2]]
print(MM(a,b))
result is [[5]]
r is an element from G so it's a row which only has two elements. That means you can't use index j to get a value from r because j goes from 0 till the length of v, which is 6 in your example.
I needed solution where the first matrix could be 2-dimensional. Extending the solution from #Kasramvd to accept a two dimensional first matrix. Posted here for reference:
>>> first,second=[[1,0,0,1,0,0],[0,1,1,1,0,0]], [[0,1],[1,1],[1,0],[1,0],[1,1],[0,1]]
>>> from itertools import starmap
>>> from operator import mul
>>> [[sum(starmap(mul, zip(row, col))) for col in zip(*second)] for row in first]
[[1, 1], [3, 1]]
# check matrices
A = [[1,2],[3,4]]
B = [[1,4],[5,6],[7,8],[9,6]]
def custom_mm(A,B):
if len(A[0]) == len(B): -- condition to check if matrix multiplication is valid or not. Making sure matrix is nXm and mXy
result = [] -- final matrix
for i in range(0,len(A)): -- loop through each row of first matrix
temp = [] -- temporary list to hold output of each row of the output matrix where number of elements will be column of second matrix
for j in range(0,len(B[0])): -- loop through each column of second matrix
total = 0
l = 0 -- dummy index to switch row of second matrix
for k in range(0,len(A[0])):
total += A[i][k]*B[l][j]
l = l+1
temp.append(total)
result.append(temp)
return result
else:
return (print("not possible"))
print(custom_mm(A,B))
There is a code that help u to multiply two matrix:
A=[[1,2,3],[4,5,6],[7,8,9]]
B=[[1,2,3],[4,5,6],[7,8,9]]
matrix=[]
def multiplicationLineColumn(line,column):
try:
sizeLine=len(line)
sizeColumn=len(column)
if(sizeLine!=sizeColumn):
raise ValueError("Exception")
res = sum([line[i] * column[i] for i in range(sizeLine)])
return res
except ValueError:
print("sould have the same len line & column")
def getColumn(matrix,numColumn):
size=len(matrix)
column= [matrix[i][numColumn] for i in range(size)]
return column
def getLine(matrix,numLine):
line = matrix[numLine]
return line
for i in range(len(A)):
matrix.append([])
for j in range(len(B)):
matrix[i].append(multiplicationLineColumn(getLine(A,i),getColumn(B,j)))
print(matrix)
I am trying to extract rows from a large numpy array. The columns of the array are obs number, group id (j), time id (t), and some data x_jt.
Here is an example:
import numpy as np
N = 100
T = 100
X = np.vstack((np.array(range(1,N*T+1)),np.repeat(np.array(range(1,N+1)),T), np.tile(np.array(range(1,T+1)),N), np.random.randint(100,size=N*T))).T
If I want to extract all rows from X where group id = 2, I would do
X[np.where(X[:,1] == 2)]
And if I wanted all rows where j = 2 or 3, I could extend that code. However, in my case, I have many group ids (j's) to extract. Specifically, I want to extract all rows where j comes from
samples = np.random.randint(N, size=N) + 1
For example, suppose size = 5 instead of N, and samples = (2,4,5,4,7). What I am after is code that goes through X and selects all rows where j = 2, then j = 4, then j = 5, j = 4, and finally j = 7, and creates a new array with the results. Basically this:
result = []
for j in samples:
result.extend(X[np.where(X[:,1] == j)])
However, this code is slow when N is large. Do you have any suggestions to speed it up? Thanks!
Without replacement
This could be done with vectorized functions:
def contains(X, samples):
return numpy.vectorize(lambda x: x in samples)(X)
result = X[contains(X[:, 1], set(samples)), :]
With replacement
If you want to do this with replacement just check off one count per sample until there are no more samples (assuming the order does not matter). This way you at least reduce the amount of times you need to iterate over the matrix.
result = []
sample_counts = collections.Counter(samples)
while sum(sample_counts.itervalues()):
# pick up one of each of the remaining samples and chain their rows
# together in result
s = set(key for key, value in sample_counts.iteritems() if value)
result = itertools.chain(result, X[contains(X[:, 1], s), :])
sample_counts -= collections.Counter(dict.fromkeys(s, 1))
# create a matrix of the final result
result = numpy.array(list(result))
In that case the only way I can think of that might speed up what you're already doing is preallocating a matrix. So you would do:
It doesn't do exactly what you are describing, but this type of problems are a good candidate for np.in1d. Something like this should work:
result = X[np.in1d(X[:, 1], samples)]
I have no idea how to even begin doing this
It needs to be a for loop to multiply mtrixes
for example
[[1,2],[3,4]] * [[3,4],[5,6]]
[1 , 2] , [3 , 4]
[3 , 4] *[5 , 6]
Need help much appreciated
I know 90% of dont want to code for me so that's ok
It only needs to be two square matrixes
i'm pretty sure the pattern is looking at it in the list thing
a[1][1]*b[1][1]+a[1][2]*b[2][1] a[1][1]b[1][2]+a[1][2]b[2][2]
a[2][1]b[1][1]+a[2][2]b[2][1] a[2][1]b[1][2]+a[2][2]b[2][2]
result = [] # final result
for i in range(len(A)):
row = [] # the new row in new matrix
for j in range(len(B[0])):
product = 0 # the new element in the new row
for v in range(len(A[i])):
product += A[i][v] * B[v][j]
row.append(product) # append sum of product into the new row
result.append(row) # append the new row into the final result
print(result)
Break it down. Before you try to write a function that multiplies matrices, write one that multiplies vectors. If you can do that, multiplying two matrices is just a matter of multiplying row i and column j for every element i,j of the resultant matrix.
If you look at how matrix multiplication works:
[ 1 2 ] x [ 5 6 ] = [ 1*5+2*7 1*6+2*8 ]
[ 3 4 ] [ 7 8 ] [ 3*5+4*7 3*6+4*8 ]
then you can determine a method to calculate this, e.g. if you are multiplying for element i, j of the output matrix, then you need to multiply everything in row i of the LHS matrix by everything in the column j of the RHS matrix, so that is a single for loop (as the number of elements in the row i is equal to column j).
You also need to cover every combination of i and j for the dimensions of the output matrix, which is a for loop for the columns nested inside a for loop for the rows.
The actual code is, of course, an exercise for you to implement.
>>> A=[[1,2],[3,4]]
>>> B=[[3,4],[5,6]]
>>> n=2
>>> ans=[[0]*n for i in range(n)]
>>> ans
[[0, 0], [0, 0]]
>>> for i in range(n):
... for j in range(n):
... ans[i][j]=sum((A[i][v]*B[v][j] for v in range(n)))
...
>>> ans
[[13, 16], [29, 36]]
I think you just need to simplify the formula of matrix multiplication.
We have A*B=C then:
Cij= the value in the ith row and jth column of the answer. For example above we have C12=16 and C11=13.. (note that this is the 0th position in the array so often we start from 0 instead of 1)
Cij= dot_product(row_i_of_A,column_j_of_B)=sum(row_i_of_A(v)*column_j_of_B(v) for v in range(n))
Because we want the whole answer (all of C), we need to work out all possible Cij. This means we need to try all possible pairs ij, so we loop through i in range(n), j in range(n) and do this for each possible pair.
from numpy import *
m1 = array([[1, 2, 3],[4, 5, 6] ])
m2 = array([[7, 8],[9, 10],[11, 12]])
r = array([[0, 0],[0, 0]])
s = 0
for i in range(2):
for j in range(2):
for k in range(3):
s = s + m1[i][k]*m2[k][j]
r[i][j] = s
s = 0
print(r)
I think append function is not working in a two-dimensional array when we are using numpy module, so this is the way I have solved it.
def matmul(matrix1_,matrix2_):
result = [] # final result
for i in range(len(matrix1_)):
row = [] # the new row in new matrix
for j in range(len(matrix2_[0])):
product = 0 # the new element in the new row
for v in range(len(matrix1_[i])):
product += matrix1_[i][v] * matrix2_[v][j]
row.append(product) # append sum of product into the new row
result.append(row) # append the new row into the final result
return result
u and v are constructed for visualization purpose.
from typing import List
A = [[1,0,0],[-1,0,3]]
B = [[7,0,0],[0,0,0],[0,0,1]]
def mult_mat(A:List[List[int]], B:List[List[int]]) -> List[List[int]]:
n = len(A) # Number of rows in matrix A
m = len(B[0]) # Number of columns in matrix B
ret = [[0 for i in range(m)] for j in range(n)]
for row in range(n):
u = A[row]
for col in range(m):
v = [B[i][col] for i in range(len(B))]
# Here you can calculate ret[row][col] directly without v
# But v is constructed for visualization purpose
ret[row][col] = sum([x*y for x,y in zip(u,v)])
return ret
if __name__ == '__main__':
print(mult_mat(A,B))