Tutorial, wiki and assignments related to CTFs and cybersecurity
Point Cloud Library (PCL)
A computer algebra system written in pure Python
pull request commentsympy/sympy
fix(polys): make PolyMatrix use DomainMatrix
I’m not sure if this is finished yet, but at least the commit history can be cleaned up
comment created time in 21 minutes
PR closed sympy/sympy
<! Your title above should be a short description of what was changed. Do not include the issue number in the title. >
References to other Issues or PRs
<! If this pull request fixes an issue, write "Fixes #NNNN" in that exact format, e.g. "Fixes #1234" (see https://tinyurl.com/autoclosing for more information). Also, please write a comment on that issue linking back to this pull request once it is open. >
fixes #21429
Brief description of what is fixed or changed
Simplification of Relationals with denominators of known sign is better handled now so
>>> x = var('x',positive=1)
>>> 1/x < 1
1/x < 1
>>> simplify(_)
x > 1
In addition, floor
and ceiling
now are aware of unit fractions
floor(1/Dummy(prime=True)) == 1
Other comments
Release Notes
<! Write the release notes for this release below between the BEGIN and END statements. The basic format is a bulleted list with the name of the subpackage and the release note for this PR. For example:

solvers
 Added a new solver for logarithmic equations.

functions
 Fixed a bug with log of integers.
or if no release note(s) should be included use:
NO ENTRY
See https://github.com/sympy/sympy/wiki/WritingReleaseNotes for more information on how to write release notes. The bot will check your release notes automatically to see if they are formatted correctly. >
<! BEGIN RELEASE NOTES >
 functions
 floor and ceiling recognize unit fractions whose magnitude is less than 1
 core
 better simplification of Rationals with rational expressions having denominators of known sign <! END RELEASE NOTES >
pr closed time in an hour
pull request commentsympy/sympy
better handling of fractions by floor/ceiling and Relational
working on less evaluation
comment created time in an hour
Pull request review commentsympy/sympy
Modified Heaviside(t) to have a standard value at Heaviside(0)=1/2
def test_DiracDelta(): def test_heaviside(): assert Heaviside(0).func == Heaviside+ assert Heaviside(0,nan).func == Heaviside assert Heaviside(5) == 0 assert Heaviside(1) == 1 assert Heaviside(nan) is nan assert Heaviside(0, x) == x assert Heaviside(0, nan) is nan assert Heaviside(x, None) == Heaviside(x) assert Heaviside(0, None) == Heaviside(0) # we do not want None and Heaviside(0) in the args: assert Heaviside(x, H0=None).args == (x,) assert Heaviside(x, H0=Heaviside(0)).args == (x,)+ assert Heaviside(x, nan) == Heaviside(x, nan)+ assert Heaviside(0, nan) == Heaviside(0, nan)
True, I have tidied up all tests.
I have also added one:
assert Heaviside(x, nan).rewrite(Piecewise) == (
Piecewise((0, x < 0), (nan, Eq(x, 0)), (1, x > 0)))
comment created time in an hour
Pull request review commentsympy/sympy
Modified Heaviside(t) to have a standard value at Heaviside(0)=1/2
class Heaviside(Function): Explanation ===========+Heac Heaviside function has the following properties: 1) $\frac{d}{d x} \theta(x) = \delta(x)$ 2) $\theta(x) = \begin{cases} 0 & \text{for}\: x < 0 \\ \text{undefined} &+ 2) $\theta(x) = \begin{cases} 0 & \text{for}\: x < 0 \\ \frac{1}{2} & \text{for}\: x = 0 \\1 & \text{for}\: x > 0 \end{cases}$ 3) $\frac{d}{d x} \max(x, 0) = \theta(x)$ Heaviside(x) is printed as $\theta(x)$ with the SymPy LaTeX printer.  Regarding to the value at 0, Mathematica defines $\theta(0)=1$, but Maple uses $\theta(0) = \text{undefined}$. Different application areas may have specific conventions. For example, in control theory, it is common practice to assume $\theta(0) = 0$ to match the Laplace transform of a DiracDelta distribution.+ The value at 0 is set differently in different fields. SymPy now uses 1/2,+ which is a convention from electronics and signal processing. (Up to+ SymPy 1.8, the default was that the value at 0 is undefined.)  To specify the value of Heaviside at ``x=0``, a second argument can be given. Omit this 2nd argument or pass ``None`` to recover the default behavior.+ To specify a differnt value of Heaviside at ``x=0``, a second argument+ can be given. Pass ``nan`` as the second argument to get a Heaviside+ function that does not have a defined value at 0.
Thanks ;)
comment created time in an hour
Pull request review commentsympy/sympy
Modified Heaviside(t) to have a standard value at Heaviside(0)=1/2
def test_DiracDelta(): def test_heaviside(): assert Heaviside(0).func == Heaviside+ assert Heaviside(0,nan).func == Heaviside
Never saw this before, thanks ;)
comment created time in 2 hours
Pull request review commentsympy/sympy
Modified Heaviside(t) to have a standard value at Heaviside(0)=1/2
def pw_simp(*args): u = Dummy('u')  def simp_heaviside(arg):+ def simp_heaviside(arg,H0=S.Half):
OK
comment created time in 2 hours
Pull request review commentsympy/sympy
Modified Heaviside(t) to have a standard value at Heaviside(0)=1/2
class is about to be instantiated and it returns either some simplified elif arg.is_extended_positive: return S.One elif arg.is_zero: return H0+ if H0 is not nan:+ return H0
I would prefer that, actually, but then the information is lost that the nan comes from Heaviside's undefined step value. I thought a lot about this and concluded that returning nan must be OK; if anyone wants to maintain the info that the undefined value of Heaviside plays a role in some computation, they can call the function with Heaviside(x,Theta_0).
I'll change this.
comment created time in 2 hours
Pull request review commentsympy/sympy
Modified Heaviside(t) to have a standard value at Heaviside(0)=1/2
class Heaviside(Function): >>> Heaviside(9) 0 >>> Heaviside(0) Heaviside(0) >>> Heaviside(0, S.Half) 1/2+ >>> Heaviside(0, S.Half)+ Heaviside(0, nan)
It was simply wrong.
comment created time in 2 hours
Pull request review commentsympy/sympy
Modified Heaviside(t) to have a standard value at Heaviside(0)=1/2
class Heaviside(Function): Explanation ===========+Heac Heaviside function has the following properties: 1) $\frac{d}{d x} \theta(x) = \delta(x)$ 2) $\theta(x) = \begin{cases} 0 & \text{for}\: x < 0 \\ \text{undefined} &+ 2) $\theta(x) = \begin{cases} 0 & \text{for}\: x < 0 \\ \frac{1}{2} & \text{for}\: x = 0 \\1 & \text{for}\: x > 0 \end{cases}$ 3) $\frac{d}{d x} \max(x, 0) = \theta(x)$ Heaviside(x) is printed as $\theta(x)$ with the SymPy LaTeX printer.  Regarding to the value at 0, Mathematica defines $\theta(0)=1$, but Maple uses $\theta(0) = \text{undefined}$. Different application areas may have specific conventions. For example, in control theory, it is common practice to assume $\theta(0) = 0$ to match the Laplace transform of a DiracDelta distribution.+ The value at 0 is set differently in different fields. SymPy now uses 1/2,+ which is a convention from electronics and signal processing. (Up to+ SymPy 1.8, the default was that the value at 0 is undefined.)
OK!
comment created time in 2 hours
Pull request review commentsympy/sympy
Modified Heaviside(t) to have a standard value at Heaviside(0)=1/2
class Heaviside(Function): Explanation ===========+Heac Heaviside function has the following properties:
Thanks, removed.
comment created time in 2 hours
issue closedsympy/sympy
Need email response from Oscar Benjamin
@oscarbenjamin, @asmeurer and I have been sending emails about the CZI grant. We need you to respond ASAP as there is little time left to finish the proposal.
closed time in 3 hours
moorepantsissue commentsympy/sympy
Need email response from Oscar Benjamin
Got it. thanks.
comment created time in 3 hours
PR closed sympy/sympy
<! Your title above should be a short description of what was changed. Do not include the issue number in the title. >
References to other Issues or PRs
<! If this pull request fixes an issue, write "Fixes #NNNN" in that exact format, e.g. "Fixes #1234" (see https://tinyurl.com/autoclosing for more information). Also, please write a comment on that issue linking back to this pull request once it is open. >
Brief description of what is fixed or changed
CoordinateSymbol
can now be rewritten with respect to another coordnate system. For example, for Cartesian x, y
and Polar r, theta
, x.rewrite(Polar)
returns r*cos(theta)
.
Other comments
For this, Basic.rewrite()
is modified to be able to take instance as rewrite rule. This does not change public API.
Release Notes
<! Write the release notes for this release below between the BEGIN and END statements. The basic format is a bulleted list with the name of the subpackage and the release note for this PR. For example:

solvers
 Added a new solver for logarithmic equations.

functions
 Fixed a bug with log of integers.
or if no release note(s) should be included use:
NO ENTRY
See https://github.com/sympy/sympy/wiki/WritingReleaseNotes for more information on how to write release notes. The bot will check your release notes automatically to see if they are formatted correctly. >
<! BEGIN RELEASE NOTES >
 diffgeom
CoordinateSymbol
now can be rewritten to the expression containing the coordinate symbols of other coordinate system. <! END RELEASE NOTES >
pr closed time in 6 hours
pull request commentsympy/sympy
feat(diffgeom) : introduce rewriting of CoordinateSymbol wrt CoordSystem
Then maybe a function will be suitable instead of method.
comment created time in 9 hours
Pull request review commentsympy/sympy
better handling of fractions by floor/ceiling and Relational
def _n2(a, b): return dif +@dispatch(Rational, Pow)+def _eval_is_ge(lhs, rhs): # noqa:F811+ # i >= b**((+/1)/j)+ if lhs:+ base, exp = rhs.as_base_exp()+ if exp.is_Rational:+ if exp.p == 1 and is_le(base, lhs**exp.q):+ return True+ if exp.p == 1 and is_ge(base, lhs**exp.q):+ return True
For the change above a relevant case would be:
In [11]: a = S(2)
In [12]: b = S(2)**(S(1)/10**1000)
In [13]: is_ge(a, b)
^C
KeyboardInterrupt
comment created time in 10 hours
Pull request review commentsympy/sympy
better handling of fractions by floor/ceiling and Relational
def _n2(a, b): return dif +@dispatch(Rational, Pow)+def _eval_is_ge(lhs, rhs): # noqa:F811+ # i >= b**((+/1)/j)+ if lhs:+ base, exp = rhs.as_base_exp()+ if exp.is_Rational:+ if exp.p == 1 and is_le(base, lhs**exp.q):+ return True+ if exp.p == 1 and is_ge(base, lhs**exp.q):+ return True
Actually that example is just slow in the int
code. Here's a better one:
In [11]: e = 100**100**pi**100
In [12]: e
Out[12]:
⎛ ⎛ 100⎞⎞
⎜ ⎝π ⎠⎟
⎝100 ⎠
100
In [13]: 2 < e
^C
KeyboardInterrupt
comment created time in 10 hours
pull request commentsympy/sympy
I haven't looked through this in detail but it's good to see this coming.
I would put the algorithm in a separate file like ricatti.py
. There can be a solver in single.py
but it should just be a wrapper around the basic algorithm routines from ricatti.py
. The basic routines should each be tested separately from dsolve.
The code needs to give much more explanation about the algorithm. Imagine someone in future who hasn't read the papers on which the algorithm is based trying to fix a simple bug. It's too much for them to go read a PhD thesis to understand what your code is doing. The top of the ricatti.py module should outline the algorithm and should also make it very clear what the reference for the algorithm is. Any assumptions you make and anything that you are not 100% sure about should be clearly documented within the code so that someone in future can understand what you were thinking when you wrote that code (e.g. if the assumption turns out to be incorrect in some cases).
comment created time in 10 hours
Pull request review commentsympy/sympy
better handling of fractions by floor/ceiling and Relational
def _n2(a, b): return dif +@dispatch(Rational, Pow)+def _eval_is_ge(lhs, rhs): # noqa:F811+ # i >= b**((+/1)/j)+ if lhs:+ base, exp = rhs.as_base_exp()+ if exp.is_Rational:+ if exp.p == 1 and is_le(base, lhs**exp.q):+ return True+ if exp.p == 1 and is_ge(base, lhs**exp.q):+ return True
We should try to avoid creating new Basic instances like lhs**exp.q
. I realise that's just a Rational**int
but part of the idea in creating the _eval_is_ge
scheme is because the current code for inequalities and assumptions relies on numerical evaluation which stalls for extremely large/small numbers like:
2 < pi**100**100**100
Here if exp.q
is a very large integer then this would hang as well.
comment created time in 10 hours
pull request commentsympy/sympy
refact(assump) : parametrize the facts
The CI failure is on Travis and is the Sphinx build failing with these warnings:
/home/travis/build/sympy/sympy/sympy/categories/diagram_drawing.py:docstring of sympy.categories.diagram_drawing.DiagramGrid:126: WARNING: more than one target found for crossreference 'Diagram': sympy.categories.Diagram, sympy.categories.baseclasses.Diagram
/home/travis/build/sympy/sympy/sympy/categories/diagram_drawing.py:docstring of sympy.categories.diagram_drawing.XypicDiagramDrawer:3: WARNING: more than one target found for crossreference 'Diagram': sympy.categories.Diagram, sympy.categories.baseclasses.Diagram
/home/travis/build/sympy/sympy/sympy/core/mul.py:docstring of sympy.core.mul.Mul:62: WARNING: more than one target found for crossreference 'MatMul': sympy.matrices.expressions.MatMul, sympy.matrices.expressions.matmul.MatMul
/home/travis/build/sympy/sympy/sympy/core/add.py:docstring of sympy.core.add.Add:78: WARNING: more than one target found for crossreference 'MatAdd': sympy.matrices.expressions.MatAdd, sympy.matrices.expressions.matadd.MatAdd
/home/travis/build/sympy/sympy/doc/src/modules/matrices/immutablematrices.rst:11: WARNING: more than one target found for crossreference 'MatrixExpr': sympy.matrices.expressions.MatrixExpr, sympy.matrices.expressions.matexpr.MatrixExpr
/home/travis/build/sympy/sympy/doc/src/modules/polys/domainsintro.rst:573: WARNING: more than one target found for crossreference 'FiniteField': sympy.polys.domains.FiniteField, sympy.polys.domains.finitefield.FiniteField
/home/travis/build/sympy/sympy/doc/src/modules/polys/domainsintro.rst:573: WARNING: more than one target found for crossreference 'PythonFiniteField': sympy.polys.domains.PythonFiniteField, sympy.polys.domains.pythonfinitefield.PythonFiniteField
/home/travis/build/sympy/sympy/doc/src/modules/polys/domainsintro.rst:573: WARNING: more than one target found for crossreference 'GMPYFiniteField': sympy.polys.domains.GMPYFiniteField, sympy.polys.domains.gmpyfinitefield.GMPYFiniteField
/home/travis/build/sympy/sympy/doc/src/modules/polys/domainsintro.rst:670: WARNING: more than one target found for crossreference 'AlgebraicField': sympy.polys.domains.AlgebraicField, sympy.polys.domains.algebraicfield.AlgebraicField
/home/travis/build/sympy/sympy/doc/src/modules/polys/domainsintro.rst:961: WARNING: more than one target found for crossreference 'PolynomialRing': sympy.polys.domains.PolynomialRing, sympy.polys.domains.polynomialring.PolynomialRing
/home/travis/build/sympy/sympy/doc/src/modules/polys/domainsintro.rst:1026: WARNING: more than one target found for crossreference 'RationalField': sympy.polys.domains.RationalField, sympy.polys.domains.rationalfield.RationalField
/home/travis/build/sympy/sympy/doc/src/modules/polys/domainsintro.rst:1082: WARNING: more than one target found for crossreference 'RationalField': sympy.polys.domains.RationalField, sympy.polys.domains.rationalfield.RationalField
/home/travis/build/sympy/sympy/doc/src/modules/polys/domainsintro.rst:1163: WARNING: more than one target found for crossreference 'PolynomialRing': sympy.polys.domains.PolynomialRing, sympy.polys.domains.polynomialring.PolynomialRing
/home/travis/build/sympy/sympy/doc/src/modules/polys/domainsintro.rst:1163: WARNING: more than one target found for crossreference 'RationalField': sympy.polys.domains.RationalField, sympy.polys.domains.rationalfield.RationalField
/home/travis/build/sympy/sympy/doc/src/modules/polys/domainsintro.rst:1187: WARNING: more than one target found for crossreference 'ExpressionDomain': sympy.polys.domains.ExpressionDomain, sympy.polys.domains.expressiondomain.ExpressionDomain
/home/travis/build/sympy/sympy/doc/src/modules/polys/domainsintro.rst:1187: WARNING: more than one target found for crossreference 'AlgebraicField': sympy.polys.domains.AlgebraicField, sympy.polys.domains.algebraicfield.AlgebraicField
/home/travis/build/sympy/sympy/doc/src/modules/polys/domainsintro.rst:1201: WARNING: more than one target found for crossreference 'PolynomialRing': sympy.polys.domains.PolynomialRing, sympy.polys.domains.polynomialring.PolynomialRing
/home/travis/build/sympy/sympy/doc/src/modules/polys/domainsintro.rst:1201: WARNING: more than one target found for crossreference 'RationalField': sympy.polys.domains.RationalField, sympy.polys.domains.rationalfield.RationalField
/home/travis/build/sympy/sympy/doc/src/modules/polys/domainsintro.rst:1392: WARNING: more than one target found for crossreference 'AlgebraicField': sympy.polys.domains.AlgebraicField, sympy.polys.domains.algebraicfield.AlgebraicField
/home/travis/build/sympy/sympy/doc/src/modules/polys/domainsintro.rst:1538: WARNING: more than one target found for crossreference 'AlgebraicField': sympy.polys.domains.AlgebraicField, sympy.polys.domains.algebraicfield.AlgebraicField
/home/travis/build/sympy/sympy/sympy/polys/domains/domain.py:docstring of sympy.polys.domains.domain.Domain:84: WARNING: more than one target found for crossreference 'PolynomialRing': sympy.polys.domains.PolynomialRing, sympy.polys.domains.polynomialring.PolynomialRing
/home/travis/build/sympy/sympy/sympy/polys/domains/algebraicfield.py:docstring of sympy.polys.domains.algebraicfield.AlgebraicField:155: WARNING: more than one target found for crossreference 'AlgebraicNumber': sympy.polys.numberfields.AlgebraicNumber, sympy.core.numbers.AlgebraicNumber
I don't think this PR changed those. It might be that we are using the wrong kind of crossreference somewhere. I don't understand Sphinx referencing very well though...
comment created time in 10 hours
pull request commentsympy/sympy
feat(diffgeom) : introduce rewriting of CoordinateSymbol wrt CoordSystem
For this,
Basic.rewrite()
is modified to be able to take instance as rewrite rule. This does not change public API.
I'm not sure about this change. Also it seems that _eval_rewrite_as_x
needs to take **kwargs
which wouldn't be backwards compatible for downstream _eval_rewrite
methods.
Changing coordinate system doesn't feel like a "rewrite" to me. I'm reluctant to make any changes to Basic for this.
comment created time in 10 hours
Pull request review commentsympy/sympy
Modified Heaviside(t) to have a standard value at Heaviside(0)=1/2
def pw_simp(*args): u = Dummy('u')  def simp_heaviside(arg):+ def simp_heaviside(arg,H0=S.Half):
That should say: space after comma
comment created time in 10 hours
Pull request review commentsympy/sympy
Modified Heaviside(t) to have a standard value at Heaviside(0)=1/2
def pw_simp(*args): u = Dummy('u')  def simp_heaviside(arg):+ def simp_heaviside(arg,H0=S.Half):
Use a comma after a space
comment created time in 10 hours
Pull request review commentsympy/sympy
Modified Heaviside(t) to have a standard value at Heaviside(0)=1/2
def test_DiracDelta(): def test_heaviside(): assert Heaviside(0).func == Heaviside+ assert Heaviside(0,nan).func == Heaviside assert Heaviside(5) == 0 assert Heaviside(1) == 1 assert Heaviside(nan) is nan assert Heaviside(0, x) == x assert Heaviside(0, nan) is nan assert Heaviside(x, None) == Heaviside(x) assert Heaviside(0, None) == Heaviside(0) # we do not want None and Heaviside(0) in the args: assert Heaviside(x, H0=None).args == (x,) assert Heaviside(x, H0=Heaviside(0)).args == (x,)+ assert Heaviside(x, nan) == Heaviside(x, nan)+ assert Heaviside(0, nan) == Heaviside(0, nan)
These tests are somewhat tautological. Do the args include S.Half
now?
I think it's fine if they do but it probably means these lines should just be removed.
comment created time in 10 hours
Pull request review commentsympy/sympy
Modified Heaviside(t) to have a standard value at Heaviside(0)=1/2
def test_DiracDelta(): def test_heaviside(): assert Heaviside(0).func == Heaviside+ assert Heaviside(0,nan).func == Heaviside
It is better to use unchanged for this e.g.: https://github.com/sympy/sympy/blob/aa96b23bb98f00542101c08d8ea02ef83949310b/sympy/core/tests/test_arit.py#L170
comment created time in 10 hours
Pull request review commentsympy/sympy
Modified Heaviside(t) to have a standard value at Heaviside(0)=1/2
class is about to be instantiated and it returns either some simplified elif arg.is_extended_positive: return S.One elif arg.is_zero: return H0+ if H0 is not nan:+ return H0
Do we not want to just return the nan
?
comment created time in 10 hours
Pull request review commentsympy/sympy
Modified Heaviside(t) to have a standard value at Heaviside(0)=1/2
class Heaviside(Function): >>> Heaviside(9) 0 >>> Heaviside(0) Heaviside(0) >>> Heaviside(0, S.Half) 1/2+ >>> Heaviside(0, S.Half)+ Heaviside(0, nan)
I'm not sure I understand this...
comment created time in 10 hours
Pull request review commentsympy/sympy
Modified Heaviside(t) to have a standard value at Heaviside(0)=1/2
class Heaviside(Function): Explanation ===========+Heac Heaviside function has the following properties: 1) $\frac{d}{d x} \theta(x) = \delta(x)$ 2) $\theta(x) = \begin{cases} 0 & \text{for}\: x < 0 \\ \text{undefined} &+ 2) $\theta(x) = \begin{cases} 0 & \text{for}\: x < 0 \\ \frac{1}{2} & \text{for}\: x = 0 \\1 & \text{for}\: x > 0 \end{cases}$ 3) $\frac{d}{d x} \max(x, 0) = \theta(x)$ Heaviside(x) is printed as $\theta(x)$ with the SymPy LaTeX printer.  Regarding to the value at 0, Mathematica defines $\theta(0)=1$, but Maple uses $\theta(0) = \text{undefined}$. Different application areas may have specific conventions. For example, in control theory, it is common practice to assume $\theta(0) = 0$ to match the Laplace transform of a DiracDelta distribution.+ The value at 0 is set differently in different fields. SymPy now uses 1/2,+ which is a convention from electronics and signal processing. (Up to+ SymPy 1.8, the default was that the value at 0 is undefined.)  To specify the value of Heaviside at ``x=0``, a second argument can be given. Omit this 2nd argument or pass ``None`` to recover the default behavior.+ To specify a differnt value of Heaviside at ``x=0``, a second argument+ can be given. Pass ``nan`` as the second argument to get a Heaviside+ function that does not have a defined value at 0.
differnt > different
Using Heaviside(x, nan)
gives an expression that will evaluate to nan for x=0
.
comment created time in 10 hours
Pull request review commentsympy/sympy
Modified Heaviside(t) to have a standard value at Heaviside(0)=1/2
class Heaviside(Function): Explanation ===========+Heac Heaviside function has the following properties: 1) $\frac{d}{d x} \theta(x) = \delta(x)$ 2) $\theta(x) = \begin{cases} 0 & \text{for}\: x < 0 \\ \text{undefined} &+ 2) $\theta(x) = \begin{cases} 0 & \text{for}\: x < 0 \\ \frac{1}{2} & \text{for}\: x = 0 \\1 & \text{for}\: x > 0 \end{cases}$ 3) $\frac{d}{d x} \max(x, 0) = \theta(x)$ Heaviside(x) is printed as $\theta(x)$ with the SymPy LaTeX printer.  Regarding to the value at 0, Mathematica defines $\theta(0)=1$, but Maple uses $\theta(0) = \text{undefined}$. Different application areas may have specific conventions. For example, in control theory, it is common practice to assume $\theta(0) = 0$ to match the Laplace transform of a DiracDelta distribution.+ The value at 0 is set differently in different fields. SymPy now uses 1/2,+ which is a convention from electronics and signal processing. (Up to+ SymPy 1.8, the default was that the value at 0 is undefined.)
It would be good to use the versionchanged sphinx directive:
https://www.sphinxdoc.org/en/master/usage/restructuredtext/directives.html#directiveversionchanged
comment created time in 10 hours
Pull request review commentsympy/sympy
Modified Heaviside(t) to have a standard value at Heaviside(0)=1/2
class Heaviside(Function): Explanation ===========+Heac Heaviside function has the following properties:
There seems to be a spurious change here
comment created time in 10 hours