ASKSAGE: Sage Q&A Forum - RSS feedhttps://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Thu, 30 Nov 2017 21:13:17 +0100Monkey-patching PARI callshttps://ask.sagemath.org/question/39807/monkey-patching-pari-calls/I'm currently trying to implement some number field computations on a very particular number field (specifically, $K = \mathbb{Q}(\zeta_{n-1},n^{1/(n-1)})$). The code I've written so far has some bottlenecks that profiling via %prun has identified, namely:
1. `{method '_nf_rnfeq' of 'sage.libs.cypari2.gen.gen' objects}`, which seems to compute the minimal polynomial of $K$ (currently I'm defining $K$ via `F.<u> = CyclotomicField(n-1)`, and then `K.<a> = F.extension(x^(n-1) - n)`, so $K$ is a relative extension. `_nf_rnfeq` seems to compute the absolute minimal polynomial of a given relative extension (via PARI).
2. `{method 'discriminant' of 'sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint' objects}`, which appears to just be the polynomial discriminant computation.
Assume I've done analysis by hand gives me a much faster computation of the absolute minimal polynomial for this particular number field. I'd then want a version of `_nf_rnfeq` that:
1. Checks if it's being called on my special case, where better algorithms exist. If so, run that.
2. Otherwise, run the traditional algorithm.
Of course, I'd prefer to make this modification without modifying the source code, as that seems to be an especially ugly solution.
One way to implement this is to change is by modifying the relevant method at run-time, via a technique known as "Monkey-Patching" (see [here](https://stackoverflow.com/questions/47503061/replacing-specific-function-calls/47503146#47503146)).
The issue I'm having now is that attempting to monkey-patch the PARI call gives me the error:
`TypeError: can't set attributes of built-in/extension type 'sage.libs.cypari2.gen.gen'`
The code I'm using (in the first cell of my IPython notebook) is below:
import sage.libs.cypari2.gen
orig_nf_rnfeq = sage.libs.cypari2.gen.gen._nf_rnfeq
def _nf_rnfeq(*args, **kwargs):
print("Rnfeq works!")
return orig_nf_rnfeq(*args, **kwargs)
sage.libs.cypari2.gen.gen._nf_rnfeq = _nf_rnfeqMon, 27 Nov 2017 00:37:25 +0100https://ask.sagemath.org/question/39807/monkey-patching-pari-calls/Answer by vdelecroix for <p>I'm currently trying to implement some number field computations on a very particular number field (specifically, $K = \mathbb{Q}(\zeta_{n-1},n^{1/(n-1)})$). The code I've written so far has some bottlenecks that profiling via %prun has identified, namely:</p>
<ol>
<li><p><code>{method '_nf_rnfeq' of 'sage.libs.cypari2.gen.gen' objects}</code>, which seems to compute the minimal polynomial of $K$ (currently I'm defining $K$ via <code>F.<u> = CyclotomicField(n-1)</code>, and then <code>K.<a> = F.extension(x^(n-1) - n)</code>, so $K$ is a relative extension. <code>_nf_rnfeq</code> seems to compute the absolute minimal polynomial of a given relative extension (via PARI).</p></li>
<li><p><code>{method 'discriminant' of 'sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint' objects}</code>, which appears to just be the polynomial discriminant computation.</p></li>
</ol>
<p>Assume I've done analysis by hand gives me a much faster computation of the absolute minimal polynomial for this particular number field. I'd then want a version of <code>_nf_rnfeq</code> that:</p>
<ol>
<li>Checks if it's being called on my special case, where better algorithms exist. If so, run that.</li>
<li>Otherwise, run the traditional algorithm.</li>
</ol>
<p>Of course, I'd prefer to make this modification without modifying the source code, as that seems to be an especially ugly solution.</p>
<p>One way to implement this is to change is by modifying the relevant method at run-time, via a technique known as "Monkey-Patching" (see https://stackoverflow.com/questions/47503061/replacing-specific-function-calls/47503146#47503146 (here)).</p>
<p>The issue I'm having now is that attempting to monkey-patch the PARI call gives me the error:</p>
<p><code>TypeError: can't set attributes of built-in/extension type 'sage.libs.cypari2.gen.gen'</code></p>
<p>The code I'm using (in the first cell of my IPython notebook) is below:</p>
<pre><code>import sage.libs.cypari2.gen
orig_nf_rnfeq = sage.libs.cypari2.gen.gen._nf_rnfeq
def _nf_rnfeq(*args, **kwargs):
print("Rnfeq works!")
return orig_nf_rnfeq(*args, **kwargs)
sage.libs.cypari2.gen.gen._nf_rnfeq = _nf_rnfeq
</code></pre>
https://ask.sagemath.org/question/39807/monkey-patching-pari-calls/?answer=39811#post-id-39811Monkey patching does not apply to extension modules (that is compiled Python module from C source code). And `sage.libs.cypari2` is an extension module written in Cython.
The best way to go in your situation is to use a home compiled version of Sage and start modifying its source code. The procedure is described in the [developer manual](http://doc.sagemath.org/html/en/developer/). Note that the cypari2 code is an external package of Sage (see https://github.com/defeo/cypari2) that you clearly do *not* want to modify.Mon, 27 Nov 2017 10:10:24 +0100https://ask.sagemath.org/question/39807/monkey-patching-pari-calls/?answer=39811#post-id-39811Comment by orangejake for <p>Monkey patching does not apply to extension modules (that is compiled Python module from C source code). And <code>sage.libs.cypari2</code> is an extension module written in Cython.</p>
<p>The best way to go in your situation is to use a home compiled version of Sage and start modifying its source code. The procedure is described in the <a href="http://doc.sagemath.org/html/en/developer/">developer manual</a>. Note that the cypari2 code is an external package of Sage (see <a href="https://github.com/defeo/cypari2">https://github.com/defeo/cypari2</a>) that you clearly do <em>not</em> want to modify.</p>
https://ask.sagemath.org/question/39807/monkey-patching-pari-calls/?comment=39813#post-id-39813Could something like [forebidden fruit](https://github.com/clarete/forbiddenfruit) let me avoid modifying source? That'd make it more difficult to distribute my code later.Mon, 27 Nov 2017 10:23:46 +0100https://ask.sagemath.org/question/39807/monkey-patching-pari-calls/?comment=39813#post-id-39813Comment by vdelecroix for <p>Monkey patching does not apply to extension modules (that is compiled Python module from C source code). And <code>sage.libs.cypari2</code> is an extension module written in Cython.</p>
<p>The best way to go in your situation is to use a home compiled version of Sage and start modifying its source code. The procedure is described in the <a href="http://doc.sagemath.org/html/en/developer/">developer manual</a>. Note that the cypari2 code is an external package of Sage (see <a href="https://github.com/defeo/cypari2">https://github.com/defeo/cypari2</a>) that you clearly do <em>not</em> want to modify.</p>
https://ask.sagemath.org/question/39807/monkey-patching-pari-calls/?comment=39815#post-id-39815No. Forebidden fruit would allow you to use monkey patching on C objects. To modify the source code you just need a text editor.Mon, 27 Nov 2017 10:37:46 +0100https://ask.sagemath.org/question/39807/monkey-patching-pari-calls/?comment=39815#post-id-39815Comment by orangejake for <p>Monkey patching does not apply to extension modules (that is compiled Python module from C source code). And <code>sage.libs.cypari2</code> is an extension module written in Cython.</p>
<p>The best way to go in your situation is to use a home compiled version of Sage and start modifying its source code. The procedure is described in the <a href="http://doc.sagemath.org/html/en/developer/">developer manual</a>. Note that the cypari2 code is an external package of Sage (see <a href="https://github.com/defeo/cypari2">https://github.com/defeo/cypari2</a>) that you clearly do <em>not</em> want to modify.</p>
https://ask.sagemath.org/question/39807/monkey-patching-pari-calls/?comment=39834#post-id-39834Does monkey patching work for purely sage libraries?Wed, 29 Nov 2017 07:53:37 +0100https://ask.sagemath.org/question/39807/monkey-patching-pari-calls/?comment=39834#post-id-39834Comment by vdelecroix for <p>Monkey patching does not apply to extension modules (that is compiled Python module from C source code). And <code>sage.libs.cypari2</code> is an extension module written in Cython.</p>
<p>The best way to go in your situation is to use a home compiled version of Sage and start modifying its source code. The procedure is described in the <a href="http://doc.sagemath.org/html/en/developer/">developer manual</a>. Note that the cypari2 code is an external package of Sage (see <a href="https://github.com/defeo/cypari2">https://github.com/defeo/cypari2</a>) that you clearly do <em>not</em> want to modify.</p>
https://ask.sagemath.org/question/39807/monkey-patching-pari-calls/?comment=39854#post-id-39854The distinction between "pure Sage library" and "external library" is just a matter of distribution (Sage is directly responsible of its library but not directly to the external ones). They are the very same from Python point of view.Thu, 30 Nov 2017 21:13:17 +0100https://ask.sagemath.org/question/39807/monkey-patching-pari-calls/?comment=39854#post-id-39854