question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Question: Constructing a sparse matrix

See original GitHub issue

How can I make a function like this work with autograd, given that assignment is forbidden?

def func(a, b):   # a and b are scalars
    m = np.zeros((10, 10))
    m[5,7] = a
    m[3,6] = b
    return m

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:9 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
mattjjcommented, Jun 4, 2017

Here are two ways to do it. Because func is a linear map, you can implement it in a sparse matrix form treating a and b as coefficients on fixed basis elements:

def func(a, b):
    def one_hot(i, j):
        out = np.zeros((10, 10))
        out[i, j] = 1
        return out
    return a * one_hot(5, 7) + b * one_hot(3, 6)

If the indices (5, 7) and (3, 6) are really constants (or you’re going to call func many times with the same values for those indices) you can make that more efficient with staged evaluation, so that the basis elements aren’t re-allocated on every invocation.

Another way to do it is to write your own primitive, which is probably both more straightforward and more performant:

@primitive
def func(a, b):
    m = np.zeros((10, 10))
    m[5, 7] = a
    m[3, 6] = b
    return m
func3.defvjp(lambda g, ans, vs, gvs, a, b: g[5, 7], argnum=0)
func3.defvjp(lambda g, ans, vs, gvs, a, b: g[3, 6], argnum=1)

Inside a primitive, there are no autograd boxed values; everything is raw numpy, so you’re back in the world you’re used to. You have to define any vjp’s you need for your primitives, though.

When writing custom primitives, check_grads is your friend!

Side notes: of course, you only need to do this if you’re going to differentiate through func. Assignment into autograd’s ArrayNodes is not supported, but when you’re using autograd.numpy, ArrayNodes are only created as necessary during tracing, i.e. when an autograd.numpy function gets an ArrayNode as one of its arguments; otherwise, it’s just raw numpy as usual. In fact, the kind of assignment you wrote might work anyway, since m is being created as a zeros matrix and won’t be an ArrayNode, though when a or b is an ArrayNode, the assignment would have to turn it into an array with dtype object and things might get weird.

1reaction
mattjjcommented, Jun 4, 2017

If you are differentiating with respect to a and b directly, rather than them being some intermediates in the computation, you can also get them both at once (without redoing the forward pass or backward pass) using multigrad, which is in convenience_wrappers.py. Check out that file, since there is a lot of functionality in there.

You can also do the same thing manually by writing a function that takes an (a, b) tuple argument instead of separate arguments (since autograd will happily differentiate with respect to a tuple argument).

Read more comments on GitHub >

github_iconTop Results From Across the Web

Sparse Matrix and its representations | Set 1 (Using Arrays ...
Representing a sparse matrix by a 2D array leads to wastage of lots of memory as zeroes in the matrix are of no...
Read more >
A Gentle Introduction to Sparse Matrices for Machine Learning
The sparse matrix is represented using three one-dimensional arrays for the non-zero values, the extents of the rows, and the column indexes. ...
Read more >
Sparse matrix - Wikipedia
In numerical analysis and scientific computing, a sparse matrix or sparse array is a matrix in which most of the elements are zero....
Read more >
Create sparse matrix - MATLAB sparse - MathWorks
If any of the inputs i,j or m,n are larger than 2^31-1 for 32-bit platforms, or 2^48-1 on 64-bit platforms, then the sparse...
Read more >
Creating sparse matrix from dense matrix without initializing ...
Basically a sparse matrix is created from arrays of row coordinates, column coordinates, and corresponding values. There are variations for ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found