I have an $n$ by $m$ numpy array representing a rectangular lattice $L$, where each site contains a one or a zero, representing two different materials. I'm modelling heat flow across this lattice. The idea is that the conductivity between two lattice sites depends on the material in both sites.

To solve the heat equation I need to create from this a sparse $nm\times nm$ matrix $C$, where each of the $nm$ rows and columns corresponds to a cell in my original matrix, and where the $(i,j)^\text{th}$ element represents the thermal conductance between sites $i$ and $j$ on the lattice.

My question is whether there is an efficient way to implement this in numpy. Currently I have nested Python loops that iterate over every element of $L$ and add corresponding entries to $C$, but for large lattices this obviously gets rather slow. Is there a way to do this using numpy primitives rather than Python loops?

For clarity, my current code looks like this:

A = sp.lil_matrix((w*h,w*h))

def coords_to_index(x, y):
    return x*h+y

def setlink(p1x, p1y, p2x, p2y):
    i = coords_to_index(p1x,p1y)
    j = coords_to_index(p2x,p2y)
    ci = grid[p1x,p1y]
    cj = grid[p2x,p2y]
    if ci==cj:
        d = 1
        d = 1e-3 # conductance is much smaller between different materials
    A[i,j] = d
    return d

for x in range(w):
    for y in range(h):
        d = 0.
        if x>0:
            d += setlink(x,y,x-1,y)
            d += 1
        if x<w-1:
            d += setlink(x,y,x+1,y)
            d += 1
        if y>0:
            d += setlink(x,y,x,y-1)
            d += 1
        if y<h-1:
            d += setlink(x,y,x,y+1)
            d += 1
        i = coords_to_index(x,y)
        A[i,i] = -d

A = A.tocsr()
  • $\begingroup$ Did you find a valid answer? $\endgroup$ Sep 11 '17 at 23:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.