Opened 11 months ago

Last modified 5 months ago

#32480 needs_info enhancement

trivial __copy__ and __deepcopy__ methods for symbolic expressions and functions

Reported by: mkoeppe Owned by:
Priority: major Milestone: sage-9.7
Component: symbolics Keywords:
Cc: egourgoulhon, tscrim Merged in:
Authors: Matthias Koeppe Reviewers: Travis Scrimshaw
Report Upstream: N/A Work issues:
Branch: u/mkoeppe/trivial___copy___and___deepcopy___methods_for_symbolic_expressions_and_functions (Commits, GitHub, GitLab) Commit: f8289868c1e34ee7b64fdb755c87a5738238d49e
Dependencies: Stopgaps:

Status badges

Description (last modified by mkoeppe)

By definition, symbolic expressions are immutable (but see #32450).

We define trivial __copy__ and __deepcopy__ methods that just return self.

Before:

sage: ex = sin(x)                                                                                                                                              
sage: %timeit copy(sin)                                                                                                                                        
7.06 µs ± 91.8 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
sage: %timeit deepcopy(sin)                                                                                                                                    
7.91 µs ± 511 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
sage: %timeit copy(ex)                                                                                                                                         
339 ns ± 2.64 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
sage: %timeit deepcopy(ex)                                                                                                                                     
29.7 µs ± 259 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

After:

sage: %timeit copy(sin)                                                                                                                                        
263 ns ± 1.57 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
sage: %timeit deepcopy(sin)                                                                                                                                    
440 ns ± 3.93 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
sage: %timeit copy(ex)                                                                                                                                   
257 ns ± 2.17 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
sage: %timeit deepcopy(ex)                                                                                                                                     
429 ns ± 3.69 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Also fixes #30018

Change History (10)

comment:1 Changed 11 months ago by mkoeppe

  • Authors set to Matthias Koeppe
  • Description modified (diff)

comment:2 Changed 11 months ago by mkoeppe

  • Branch set to u/mkoeppe/trivial___copy___and___deepcopy___methods_for_symbolic_expressions_and_functions

comment:3 Changed 11 months ago by git

  • Commit set to f8289868c1e34ee7b64fdb755c87a5738238d49e

Branch pushed to git repo; I updated commit sha1. New commits:

f828986Function.__copy__, __deepcopy__: Immutable, so just return self

comment:4 Changed 11 months ago by mkoeppe

  • Cc egourgoulhon tscrim added
  • Description modified (diff)
  • Status changed from new to needs_review

comment:5 Changed 11 months ago by mkoeppe

  • Description modified (diff)

comment:6 Changed 11 months ago by tscrim

  • Reviewers set to Travis Scrimshaw

Green bot => positive review.

comment:7 Changed 11 months ago by mkoeppe

A related question here is whether we want to make Expression hashable even if the wrapped Python object is not, for example by falling back to taking the hash of the repr. Example:

sage: s = SR(matrix(QQ, [[1, 2], [3, 4]]))                                                                                                                     
sage: hash(s)                                                                                                                                                  
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-2-9333020f3184> in <module>
----> 1 hash(s)

~/s/sage/sage-rebasing/worktree-gcc11/src/sage/symbolic/expression.pyx in sage.symbolic.expression.Expression.__hash__()
   1947         sig_on()
   1948         try:
-> 1949             return self._gobj.gethash()
   1950         finally:
   1951             sig_off()

RuntimeError: Python object not hashable

comment:8 Changed 11 months ago by mkoeppe

  • Status changed from needs_review to needs_info

comment:9 Changed 8 months ago by mkoeppe

  • Milestone changed from sage-9.5 to sage-9.6

comment:10 Changed 5 months ago by mkoeppe

  • Milestone changed from sage-9.6 to sage-9.7
Note: See TracTickets for help on using tickets.