How would I write the following using list comprehension?
def mv(A,X,n):
Y = [0]*n
for i in range(n):
for j in range(n):
Y[i] += A[i][j] * X[j]
return Y
I believe that A is a matrix and that X is a vector. This is what I have tried so far, but it does not output the same thing:
def mv2(A,X,n):
res = [sum((A[i][j] * X[i]) for i in range(n) for j in range(n))]
return res
You are very close to the right answer, as you should apply sum on the right target
return [sum([A[i][j] * X[j] for j in range(n)]) for i in range(n)]
Notes: if you want to do the math with a library, numpy is a good option
import numpy as np
def mv2(A, X):
A = np.array(A)
X = np.array(X)
return np.dot(A, X)
Related
I am trying to bring something from an R package by Lotze & Loecher into python as all of the rest of the project is.
Here is the python code:
def dbeta(x,shape1,shape2):
from scipy.stats import beta
result=beta.pdf(x=x,a=shape1,b=shape2,loc=0,scale=1)
return result
def pbeta(q,shape1,shape2):
from scipy.stats import beta
result=beta.cdf(x=q,a=shape1,b=shape2,loc=0,scale=1)
return result
def combinations(array, tuple_length, prev_array=[]):
if len(prev_array) == tuple_length:
return [prev_array]
combs = []
for f, val in enumerate(array):
prev_array_extended = prev_array.copy()
prev_array_extended.append(val)
combs += combinations(array[f+1:], tuple_length, prev_array_extended)
return combs
After defining these functions here I have the problem with too many iterations in the function I think:
from scipy.integrate import quad
def best_binominal_bandit(x, n, alpha=1, beta=1):
ans = []
# x = vector of number of successes
# n = vector of number of tries
k = len(x)
l = list(range(0,k))
b = combinations(l, k-1)
for i in l:
indx = b[i]
def f(z):
r = dbeta(z, x[i] + alpha, n[i] - x[i] + beta)
for j in indx:
r = r*pbeta(z, x[j] + alpha, n[j] - x[j] + beta)
return r
a = quad(f, 0, 1)[0]
ans.append(a)
return ans
So when calling
x = [10,20,30,50]
n = [100,102,120,130]
best_binominal_bandit(x, n)
I do not receive similar results as they do in their specification. I have the feeling that there are just more iterations in the f function. After all, the bottom line should add up to 1.
I came up with a solution. I will post it here and then close the question. Seems like I misread something and made an easy mistake (that kept vexing me however).
The combination function is not necessary for what I intended, rather the ith element of the list simply needs to be excluded.
def dbeta(x,shape1,shape2):
from scipy.stats import beta
result=beta.pdf(x=x,a=shape1,b=shape2,loc=0,scale=1)
return result
def pbeta(q,shape1,shape2):
from scipy.stats import beta
result=beta.cdf(x=q,a=shape1,b=shape2,loc=0,scale=1)
return result
from scipy.integrate import quad
def best_binominal_bandit(x, n, alpha=1, beta=1):
ans = []
k = len(x)
l = list(range(0,k))
for i in l:
excluded_index = i
indx = l[:excluded_index] + l[excluded_index+1:]
def f(z):
r = dbeta(z, x[i] + alpha, n[i] - x[i] + beta)
print(z)
for j in indx:
r = r*pbeta(z, x[j] + alpha, n[j] - x[j] + beta)
return r
a = quad(f, 0, 1)[0]
ans.append(a)
return ans
All in all this seems to work for a python translation of: p. 648 in
Scott, S. L. (2010). A modern Bayesian look at the multi-armed bandit. Applied Stochastic Models in Business and Industry, 26(6), 639–658. doi:10.1002/asmb.874
I have some constraints of the form of
A_{i,j,k} = r_{i,j}B_{i,j,k}
A is a nxmxp matrix, as is B. r is an nxm matrix.
I would like to vectorize this in Python somehow, as efficiently as possible. Right now, I am making r into nxmxp matrix by saying r_{i,j,k} = r_{i,j} for all 1 <= k <= p. Then I call np.multiply on r and B. This seems inefficient. Any ideas welcome, thanks.
def ndHadamardProduct(r, n, m, p): #r is a n x m matrix, p is an int
rnew = np.zeros(n, m, p)
B = np.zeros(n, m, p)
for i in range(n):
for j in range(m):
for k in range(p):
r[i, j, k] = r[i, j]
B[i, j, k] = random.uniform(0, 1)
return np.multiply(r, B)
Add an extra dimension with np.newaxis and then broadcasting takes care of the repetition for you.
import numpy as np
r = np.random.random((3,4))
b = np.random.random((3,4,5))
a = r[:,:,np.newaxis] * b
RuntimeWarning: divide by zero encountered in double_scalars
While trying to insert array to an function
import numpy as np
import random
def lagrange(x, y, x_int):
n = x.size
y_int = 0
for i in range(0, n):
p = y[i]
for j in range(0, n):
if i != j:
p = p * (x_int - x[j]) / (x[i] - x[j])
y_int = y_int + p
return [y_int]
x = []
y = []
for i in range(1000):
x.append(random.randint(0,100))
y.append(random.randint(0,100))
fx = 3.5
print(lagrange(np.array(x),np.array(y),fx))
i expected to have 1000 iteration of output of an output, any solution to these problems?
Your error message refers to a function not mentioned in your code. But I assume the issue is because x[i] and x[j] could be the same number, and therefore you are dividing by zero on your p = p * (x_int - x[j]) / (x[i] - x[j]) line, which is not possible. You will need to add an exemption to do something different in the case x[i] equals x[j].
Since you're generating your x array randomly from a range of (0,100), and the array size is 1000, it's guranteed that x[i] = x[j] for some i,j. You need to ensure elements in x are unique.
See: How do I create a list of random numbers without duplicates?
In your nested loop could it be that you meant to do if x[i] != x[j]:
Those would be the values you wouldn't want to be the same in your division.
I have a 1d ndarray A of shape (n,) and a 2d ndarray E of shape (n,m). I am trying to preform the following calculation (the circle-dot denotes element wise multiplication):
I have written it using with a for loop, but this block of code is called thousands of times, and I was hoping there was a way to accomplish this with broadcasting or numpy functions. The following is my for loop solution I'm trying to rewrite:
def fun(E, A):
X = E * A[:,np.newaxis]
R = np.zeros(E.shape[-1])
for ii in xrange(len(E)-1):
for jj in xrange(ii+1, len(E)):
R += X[ii] * X[jj]
return R
Any help would be appreciated.
Current approach, but still not working:
def fun1(E, A):
X = E * A[:,np.newaxis]
R = np.zeros(E.shape[-1])
for ii in xrange(len(E)-1):
for jj in xrange(ii+1, len(E)):
R += X[ii] * X[jj]
return R
def fun2(E, A):
n = E.shape[0]
m = E.shape[1]
A_ = np.triu(A[1:] * A[:-1].reshape(-1,1))
E_ = E[1:] * E[:-1]
R = np.sum((A_.reshape(n-1, 1, n-1) * E_.T).transpose(0,2,1).reshape(n-1*n-1,m), axis=0)
return R
A = np.arange(4,9)
E = np.arange(20).reshape((5,4))
print fun1(E,A)
print fun2(E,A)
Now, this should work:
def fun3(E,A):
n,m = E.shape
n_ = n - 1
X = E * A[:, np.newaxis]
a = (X[:-1].reshape(n_, 1, m) * X[1:])
b = np.tril(np.ones((m, n_, n_))).T
R = np.sum((a*b).reshape(n_*n_, m), axis=0)
return R
Last function was only based on the given formula. This is instead based on fun and tested with your added test case.
Hope this works for you!
I wrote the following code to do multiplication of matrix permutations and I was wondering if it can be written in a numpy style, such that I can get rid of the two for loops:
Z = np.empty([new_d, X.shape[1]])
Z = np.ndarray(shape=(new_d, X.shape[1]))
Z = np.concatenate((X, X**2))
res = []
for i in range(0, d):
for j in range(i+1, d):
res.append(np.array(X.T[:,i]* X.T[:,j]))
Z = np.concatenate((Z, res))
while: X shape is (7, 1000), d = 7, new_d=35
any suggestion ?
Approach #1
We could use np.triu_indices to get those pair-wise permutation-indices and then simply perform elementwise multiplicatons of row-indexed arrays -
r,c = np.triu_indices(d,1)
res = X[r]*X[c]
Approach #2
For memory efficiency and hence performance especially on large arrays, we are better off slicing the input array and run a single loop with each iteration working on chunks of data, like so -
n = d-1
idx = np.concatenate(( [0], np.arange(n,0,-1).cumsum() ))
start, stop = idx[:-1], idx[1:]
L = n*(n+1)//2
res_out = np.empty((L,X.shape[1]), dtype=X.dtype)
for i,(s0,s1) in enumerate(zip(start,stop)):
res_out[s0:s1] = X[i] * X[i+1:]
To get Z directly and thus avoid all those concatenations, we could modify the earlier posted approach, like so -
n = d-1
N = len(X)
idx = 2*N + np.concatenate(( [0], np.arange(n,0,-1).cumsum() ))
start, stop = idx[:-1], idx[1:]
L = n*(n+1)//2
Z_out = np.empty((2*N + L,X.shape[1]), dtype=X.dtype)
Z_out[:N] = X
Z_out[N:2*N] = X**2
for i,(s0,s1) in enumerate(zip(start,stop)):
Z_out[s0:s1] = X[i] * X[i+1:]