Skip to content

[Proposal] change FactoredMatric.svd() so it doesn't prevent all instances of FactoredMatrix from being garbage collected #796

@manulari

Description

@manulari

Proposal

FactoredMatrix.svd is annotated with @lru_cache. This prevents instances of FactoredMatrix from ever being garbage collected, as explained here: https://rednafi.com/python/lru_cache_on_methods/

This post also gives a solution, which is to remove the annotation on the method definition, and instead do

def __init__(self, A, B):
    ...
    self.svd = lru_cache()(self._svd)
    ...

def _svd(self):
    ...

Additional context

There is more discussion of the issue in this stackoverflow post.
The python docs also have a faq entry

The solution above still creates a cyclical reference, so requires cycle detection by the garbage collector.

Alternative solution

In this specific case it probably makes more sense to use the @cached_property-decorator from functools instead, as it is in the standard library and designed to be used per instance. It avoids a cyclic reference.

@cached_property
def svd(self):
    ...

Or if for backwards compatibility one wants svd to remain a method and not a property, then one could do:

@cached_property
def _svd(self):
    ...
def svd(self):
    return self._svd

Note that svd being a method is a bit inconsistent anyways, as U, S, Vh are properties.
Also, eigenvalues could be a @cached_property as well.

Checklist

  • I have checked that there is no similar issue in the repo (required)

Metadata

Metadata

Assignees

No one assigned

    Labels

    complexity-moderateModerately complicated issues for people who have intermediate experience with the code

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions