using Theano.scan for iterating over ndarray with a condition - python

Pardon me for a basic question(I am new to Theano)!
I want to get the difference of 2 matrices for only those positions that satisfy a condition. So, suppose we have 2 matrices A and B, this(python equivalent code) is what I want to calculate:
sum = 0
n,m = A.shape
for i in xrange(n):
for j in xrange(m):
if(A[i][j] != 3.5): #some random condition!
sum += A[i][j] - B[i][j]
I want a Theano equivalent code to calculate the sum.
I know there is Theano.scan that can be used to scan an ndarray, but I could not get any example that has an if condition.
Thank you in advance :)

Related

Possible ways to draw n diagonals in an mxm square such that they do not touch each other

I'm trying to write the code to draw n diagonals in an m by m square such that they do not touch each other.
For example, for m=2 and n=3:
I tried to approach it by creating a list of pairs of points by generating the permutations and checking the solution before proceeding. Therefore, I have (m+1)*(m+1) points that create the cells of an m by m square.
def dist(a,b):
return ((a[0] - b[0])**2 + (a[1] - b[1])**2)**.5
def can_be_extended_to_solution(perm):
i = len(perm) - 1
for j in range(i):
for k in range(2):
for l in range(2):
if dist(perm[i][k],perm[j][l]) == 0:
return False
return True
def diagonal(perm,n,m):
if len(perm)==n:
print(perm)
return
temp =[]
for k in range(m):
for i in range(m):
if [k,i] not in perm:
for j in [+1,-1]:
if [k+j,i+j] not in perm and (k+j<m and i+j<m) and (0<k+j and 0<i+j):
temp = [[k,i],[k+j,i+j]]
perm.append(temp)
if can_be_extended_to_solution(perm):
diagonal(perm,n,m)
perm.pop()
m=2
n=3
diagonal([],m+1,n)
The output:
The code works and I'm getting the expected result. However, it's very slow. I'm trying to learn to improve my coding skills and do it more efficiently. So, I'd appreciate it if someone reviews my code and tells me what I can do better and what mistakes I'm making. I see that I have many loops and that's the reason for the slow speed, but I can't figure out any other way to implement those loops or avoid them.
Unique Diagonals
An algorithmic map of the unique diagonals
Probably, the code can improve if you try using the algorithm based on this pattern.
I am using 1 as positive diagonal, -1 as negative (slope=-45deg) diagonal.
My impression on the pattern is that based on the starting cell and neighbouring cells will get selected based on this.
I may update this answer with some code if possible. Does this help?
More inputs may help. let me know.

Turn this summation into Python code (int or float)

I need to turn the following summation into Python code:
This Summation
the summation length N is known.
I'm struggling with the second summation
I need something like this
for i in range(N):
(1 - (for j in range(N):
sum(x[i][j]))**2
But the second for loop is obviously not going to work (Syntax Error)
How can I iterate over j within the first for loop?
The result needs to be saved in a variable
Thank you very much
sum can take a generator expression, so you can make this a pretty clean one-liner with:
total = sum((1 - sum(x[i][j] for j in range(N)))**2 for i in range(N))
If N is such that you are actually summing all the elements (array is square and N == number of rows/columns) in the array you can do away with the ranges and just use:
sum((1 - sum(n for n in row))**2 for row in x)
which you can also do in numpy with something like:
x = np.array(x)
np.sum((1 - np.sum(x, axis=1))**2)
or if N is to take a slice of the matrix:
a = np.array(x)
N = 2
np.sum((1 - np.sum(a[0:N, 0:N], axis=1))**2)
sum = 0
for i in range(N):
sum_inside = 0
for j in range(N):
sum_inside += x[i][j]
sum += (1 - sum_inside)**2
I hope you aren't asking stack overflow to do your homework!
The summation is a simple nested comprehension:
sum(1 - sum(x[i,j] for j in range(1, N+1)) ** 2 for i in range(1, N+1))
Don't take my word for it though; it's a good idea to check the results. Here I am using x as a tuple-keyed dict.
Be aware that the image ranges from 1 to N, not from 0 to N-1. If x is a 2d array, then that would be okay if you are adjusting for zero-indexing.
#MarkMeyer has a more comprehensive answer than this one.
Regarding vectors / multi-dimensional arrays, we have recently decided it's a little more pythonic to represent them as tuple-keyed dicts instead of nested lists. For instance, with x above, we define it as follows:
x = {(i,j): fn(i,j) for j in range(1, N) for i in range(1, N)}
The major advantage is that there is no preference of index, and we are able to use filter/map for most functions.
I think this is may be a solution for your problem. Still x[i][j] is confusing.
N=int(input("Enter the value of N "))
Sum=0
for i in range(N):
for j in range(N):
Sum =Sum+( 1 - (sum(x[i][j]))**2)
print(Sum)

How to calculate efficiently the sum between two elements on a vector

I have a mathematic problem, someone asking me how to obtain efficiently the sum of several elements of a vector onto a program in python for example.
For example, we have a vector (v) with n elements (n=100000000 and n is a random real number) and we want to calculate the sum between v(10) and v(100000) and after, between v(8) and v(100). In fact, we want to calculate efficiently the sum of elements between two elements A and B with (A < B).
I'm not looking for an answer with directly a code. I'm looking for a mathematic explanation to understand this problem which is certainly a basic concept in vector efficient calculus.
The solution is to calculate in first a new vector (w) which is the cumulated sum of the vector v. So, if we want the sum between v(1) and v(1000), the answer is w(1000) and if we want the sum between v(10) and v(1000), the answer will be w(1000)-w(10-1). The only low calcul will be the cumulated sum.
The easiest way would be to build a memoisation table:
def sums(L):
answer = {i:{j:0 for j in range(i,len(L))} for i in range(len(L))}
for i,num in enumerate(L):
answer[i][i] = L[i]
for j in range(i+1, len(L)):
answer[i][j] = answer[i][j-1] + L[j]
return answer
Then query the table as follows:
table = sums(my_vector)
print(table[8][100])

How to solve a linear system using Three Column Representation output vector as input data for Cholesky?

I am trying to learn some methods in order to solve linear systems with Python. I have implemented a sort of these methods. Now I wish I could test them with large and sparse matrices. In order to do that I began to learn about Three Column Representation method cause I noticed that I am expected to reduce my sparse matrix before inputing it in my method. Three Column Representation seems to be simple but I cant figure out how to use its output as an input of my Cholesky method (for example). How do I use its output (a three column array with, values and references) as an input to my method? Do I need to rewrite my Cholesky method?
Here is my Cholesky method: https://raw.githubusercontent.com/angellicacardozo/linear-algebra-methods/master/P03CHOLE.py
Thank you
Maybe this can help you:
For i = 1 To n
For j = 1 To i
Sum = a(i, j)
For k = 1 To j-1
Sum = Sum - a(i, k) * a(j, k)
If i > j Then
a(i, j) = Sum / a(j, j)
Else If Sum > 0 Then
a(i, i) = Sqrt(Sum)
Else
ERROR

Speed up double for loop in numpy

I currently have the following double loop in my Python code:
for i in range(a):
for j in range(b):
A[:,i]*=B[j][:,C[i,j]]
(A is a float matrix. B is a list of float matrices. C is a matrix of integers. By matrices I mean m x n np.arrays.
To be precise, the sizes are: A: mxa B: b matrices of size mxl (with l different for each matrix) C: axb. Here m is very large, a is very large, b is small, the l's are even smaller than b
)
I tried to speed it up by doing
for j in range(b):
A[:,:]*=B[j][:,C[:,j]]
but surprisingly to me this performed worse.
More precisely, this did improve performance for small values of m and a (the "large" numbers), but from m=7000,a=700 onwards the first appraoch is roughly twice as fast.
Is there anything else I can do?
Maybe I could parallelize? But I don't really know how.
(I am not committed to either Python 2 or 3)
Here's a vectorized approach assuming B as a list of arrays that are of the same shape -
# Convert B to a 3D array
B_arr = np.asarray(B)
# Use advanced indexing to index into the last axis of B array with C
# and then do product-reduction along the second axis.
# Finally, we perform elementwise multiplication with A
A *= B_arr[np.arange(B_arr.shape[0]),:,C].prod(1).T
For cases with smaller a, we could run a loop that iterates through the length of a instead. Also, for more performance, it might be a better idea to store those elements into a separate 2D array instead and perform the elementwise multiplication only once after we get out of the loop.
Thus, we would have an alternative implementation like so -
range_arr = np.arange(B_arr.shape[0])
out = np.empty_like(A)
for i in range(a):
out[:,i] = B_arr[range_arr,:,C[i,:]].prod(0)
A *= out

Categories