Ask Your Question

rburing's profile - activity

2020-02-22 17:10:38 -0600 commented question "how to test if two matrices are similar by a signed permutation matrix" code sage

What are the entries of the matrices? Real numbers or integers or?

2020-02-21 10:10:11 -0600 received badge  Nice Answer (source)
2020-02-20 15:11:53 -0600 received badge  Nice Answer (source)
2020-02-20 09:16:36 -0600 answered a question Error in calling a custom function from sage

When you create a Python module and you want to use external code (such as factorial), you have to import it explicitly (another difference is that you do not have the luxury of SageMath's preparser, as mentioned in the linked post). This is for namespace reasons; if it didn't work this way then variables could easily get mixed up across modules, and life would be hell.

So you have to find out where factorial lives. In a SageMath session, entering factorial? will also show you the file it's located in, which is (...)/site-packages/sage/functions/other.py. Since site-packages is always in sys.path, we can import factorial as follows:

from sage.functions.other import factorial

Adding this line to the top of your module will fix your problem.

(By the way, there is already a binomial function.)

2020-02-19 15:44:00 -0600 answered a question continuous Fourier transform

At least you can always take a naive numerical approach:

F = lambda x: exp(-x^2)*sin(x)/x
plot2 = plot(F, xmin = -5, xmax = 5, color = 'red')
### continuous Fourier transform on RR
fhat_real = lambda xi: numerical_integral(lambda x: (F(x)*exp(-2*pi*I*x*xi)).real_part(),-oo,oo, eps_abs=1e-3, eps_rel=1e-3)[0]
import numpy
plot1 = list_plot([(x,fhat_real(x)) for x in numpy.arange(-5,5, step=0.05)], plotjoined=True)
show(plot1 + plot2, xmin = -5, xmax = 5, ymin = -1, ymax = 2)

Output:

fourier transform

2020-02-19 11:31:26 -0600 commented answer Why doesn't show() render latex properly?

Are you using a variable called matrix? That would overwrite the built-in SageMath function called matrix, which you want to use here, so you should use a different name.

2020-02-19 09:33:27 -0600 commented answer Why doesn't show() render latex properly?

Surely if you run only that, there should be no error. What code do you run before that?

2020-02-19 08:46:55 -0600 commented answer Why doesn't show() render latex properly?

What code do you use as input, exactly?

2020-02-19 08:40:55 -0600 commented answer Why doesn't show() render latex properly?

What is the error?

2020-02-19 08:38:28 -0600 received badge  Nice Answer (source)
2020-02-19 08:09:38 -0600 answered a question Unexpected result from r.quantile function

According to the documentation of quantile it takes an optional argument named type which is an integer from 1 to 9. These correspond to different algorithms for calculating quantiles; the default is algorithm 7. You will have to find out which one corresponds to the lecture; my guess is type 5.

sage: r.quantile([89, 90, 86, 96, 84, 100, 85, 96, 88, 89], type=5)
  0%  25%  50%  75% 100% 
  84   86   89   96  100
2020-02-19 06:56:08 -0600 answered a question Why doesn't show() render latex properly?

I don't know how it used to work, but the way I understand it is that NumPy's matrix type is not a SageMath data type, so it doesn't support SageMath's latex rendering (in particular, it doesn't have a _latex_() method).

So just convert to a SageMath data type first:

sage: show(matrix(P))

$$\left(\begin{array}{rrrr} 0 & 0 & 20 & 20 \\ 0 & 20 & 20 & 0 \end{array}\right)$$

2020-02-19 06:49:45 -0600 answered a question Displaying Chessboard Graphs

The range $[0,1,2]$ is obtained by range(0,3) or range(3).

Your pos_dict was too small because you wrote range(0,2) instead, which explains why only a subset of the vertices were fixed.

You can also use set_pos on the graph like this:

sage: G.set_pos(pos_dict)
sage: G.show(vertex_size=1000)

Knight 3x3

2020-02-18 18:26:43 -0600 commented question How do I solve a vector valued equation?

Do you mean you want to substitute $t=0$ into $r(t)$? What have you tried?

2020-02-18 15:50:58 -0600 answered a question intersection of two free submodules

SageMath uses Singular for this, and Singular can compute intersections of modules over polynomial rings.

I don't think this functionality has been exposed to SageMath, but we can easily do that ourselves:

def intersection(M1,M2):
    return singular.intersect(M1.transpose(),M2.transpose()).sage().transpose()

Then we can do:

sage: M3 = intersection(M1,M2); M3
[x*y + x + y + 1 x*z + x + z + 1 y*z + y + z + 1]
sage: M3[0]
(x*y + x + y + 1, x*z + x + z + 1, y*z + y + z + 1)
sage: [f.factor() for f in M3[0]]
[(y + 1) * (x + 1), (z + 1) * (x + 1), (z + 1) * (y + 1)]

Indeed, this single generator lies in the intersection:

sage: sum(a*b for (a,b) in zip(M3[0], I1.gens()))
0
sage: sum(a*b for (a,b) in zip(M3[0], I2.gens()))
0
2020-02-18 07:03:42 -0600 commented question Isogeny from Two Curves
2020-02-16 14:25:00 -0600 received badge  Good Answer (source)
2020-02-16 13:07:25 -0600 received badge  Nice Answer (source)
2020-02-16 11:47:03 -0600 received badge  Good Answer (source)
2020-02-16 09:12:14 -0600 answered a question meta-question: post formatting

You can create a code block by indenting the code by four spaces. A fast way to do this is to select the code and press the 101010 button in the editor, or use its keyboard shortcut Ctrl+K.

There is no quote button which copies the source of an existing post. When you get enough karma you will be able to edit other people's posts, which allows you to see (and copy) the source for easier quoting.

2020-02-16 05:42:15 -0600 answered a question <symbolic matrix>.simplify_rational() accepts no keywords?

These are two different methods, with the same name, on different classes (symbolic expressions and symbolic dense matrices respectively). The documentation for the matrix method does not mention keyword arguments, and indeed none are accepted, as you have seen. As an alternative you can apply the symbolic expression method to each entry:

sage: var('a,b')
sage: m=matrix(SR,2,[[(a*b-a)/a,0],[0,1]])
sage: m.apply_map(lambda z: z.simplify_rational(algorithm='simple'))
[b - 1     0]
[    0     1]

It would be nice if the matrix method accepted the same arguments. If you want, someone could open an enhancement ticket on trac.

2020-02-16 05:02:10 -0600 received badge  Nice Answer (source)
2020-02-15 05:29:47 -0600 answered a question I'm having trouble plotting this population differential equation with five particular solutions all on the same graph. Please help.

You can sum the plots:

show(plot1+sum(plot2(c) for c in [.1,3,6,9,12]),ymin=0,ymax=20)

image description

For a better picture, you can change the colors of the individual solutions, e.g.:

plot2 = lambda c, color:list_plot(soln(c),plotjoined=True,axes_labels=['$Time$','$Fish Pop.$'],thickness=2,color=color)
show(plot1+sum(plot2(c,color=tuple(colormaps.hsv(1-c/13)[:3])) for c in [.1,3,6,9,12]),ymin=0,ymax=20)

fish populations

Personally I would also change it to plot until time 3 or so instead of 10, and then use ticks=1.

2020-02-14 16:26:28 -0600 answered a question Can't substitute H=dot(a)/a in SageMath

I hope you appreciate that this is not such a simple operation to perform in general.

The simplest way is probably to replace $\dot{a}$ by $Ha$.

We can use the class I gave as an answer to Substituting a differential equation into an expression:

sage: eq1 = E1[0,0].expr().expand() == 0
sage: var('h')
sage: pde = diff(a.expr(), t) == h*a.expr()
sage: s = SubstituteEvolutionaryPDE(pde, t)
sage: s(eq1)
3*h^2 - Lambda + 3*k/a(t)^2 == 0

This also works when there are second or mixed derivatives, e.g.:

sage: eq2 = diff(a.expr(), t, t) + 13 == 0
sage: s(eq2)
h^2*a(t) + 13 == 0
2020-02-14 16:18:57 -0600 edited answer Substituting a differential equation into an expression

This is tricky, but it can be done. The idea is to replace (in the expression tree) derivatives of $f$ (with at least one derivative with respect to $t$) by the right-hand side of the equation, substituted into itself as many times as there are derivatives with respect to $t$ minus one, and finally replacing $f$ by the derivative of $f$ with respect to the remaining variables (if any).

My attempt to implement this (based on SubstituteFunction) is below, with an example (your example) in the docstring.

from sage.symbolic.expression_conversions import ExpressionTreeWalker
from sage.symbolic.operators import FDerivativeOperator

class SubstituteEvolutionaryPDE(ExpressionTreeWalker):
    def __init__(self, pde, t):
        """
        A class that walks the tree and replaces derivatives of `f` with
        respect to `t` by the right-hand side of an evolutionary PDE.
        EXAMPLES::
            sage: var('x,t'); f = function('f'); g = function('g')
            sage: pde = diff(f(t,x),t) == 1/2*diff(f(t,x),x,x)
            sage: s = SubstituteEvolutionaryPDE(pde, t)
            sage: h = g(diff(f(t,x),t), diff(f(t,x),t,x))
            sage: s(h)
            g(1/2*diff(f(t, x), x, x), 1/2*diff(f(t, x), x, x, x))

        ASSUMPTION::

        ``pde`` is of the form ``diff(f(t,...),t) == ...`` and the first
        argument of ``f`` is always ``t``.
        """
        f_expr = integrate(pde.lhs(), t)
        self.f = f_expr.operator()
        self.args = f_expr.operands()
        self.rhs = pde.rhs()

    def derivative(self, ex, operator):
        if operator.function() == self.f and 0 in operator.parameter_set(): # f is differentiated with respect to t
            t_derivatives = [p for p in operator.parameter_set() if p == 0] # (assumes t is the first argument)
            result = self.rhs
            for _ in range(len(t_derivatives)-1):
                result = result.substitute_function(self.f, self.rhs.function(*self.args))
            if len(t_derivatives) < len(operator.parameter_set()): # derivatives w.r.t variables other than t
                other_derivatives = [p for p in operator.parameter_set() if not p == 0] # (assumes t is the first argument)
                new_operator = FDerivativeOperator(operator.function(), other_derivatives)
                result = result.substitute_function(self.f, new_operator(*[self(_) for _ in ex.operands()]).function(*self.args))
            return result
        else:
            return operator(*[self(_) for _ in ex.operands()])

Edit: updated to use substitute_function correctly (the second argument should also be a function).

2020-02-14 03:29:29 -0600 received badge  Nice Answer (source)
2020-02-13 16:21:28 -0600 commented question Please include all the codes for solving this problem.

It's advisable not to blatently tell people to do your work. SageMath won't help you write down the differential equation for a given word problem (yet), you have to do that part yourself. Solving and plotting can be done, there are examples of it in the documentation. What have you tried?

2020-02-13 04:14:15 -0600 answered a question Acess bracked elements in free lie algebra element?

There seems to be room for improvement in the design here. Basis elements apparently have the same parent as ordinary elements, and a.monomials() returns them as such, which makes it hard to get at the underlying tree.

From the source code, accessed by a??, we find that we can access the actual monomial by e.g.:

sage: a_tree = a.list()[0][0]; a_tree
[[x0, x1], x1]
sage: isinstance(a_tree, sage.algebras.lie_algebras.lie_algebra_element.LyndonBracket)
True
sage: a_tree._left
[x0, x1]
sage: a_tree._right
x1

You may want to discuss this on sage-devel.

2020-02-13 03:34:31 -0600 answered a question Lie bracket of derivations over polynomial ring

You can do it like this:

E = PolynomialRing(QQ, 2, names='x')
x = E.gens()
M = E.derivation_module()
ddx = M.gens()
f=x[1]*ddx[0]
g=x[0]*ddx[1]
f.bracket(g)

Output:

-x0*d/dx0 + x1*d/dx1

You can pass names a list if you want to be more picky (and then you can omit the number of variables, 2 above, because it will be the length of the list).

2020-02-12 03:52:50 -0600 commented answer Error while creating augmented matrix: TypeError: unable to convert a to an integer

Personally I learned it from lecture notes in Dutch, but I also liked A Book of Abstract Algebra by Pinter. Like most books on abstract algebra it starts with groups and takes a while to get to rings. An example of a "rings first" book is Abstract Algebra: A Geometric Approach by Shifrin; it looks nice but I haven't read it.

2020-02-12 03:04:08 -0600 commented answer Error while creating augmented matrix: TypeError: unable to convert a to an integer

You could start at the Simple English Wikipedia: https://simple.wikipedia.org/wiki/Rin...

2020-02-12 01:54:44 -0600 answered a question Error while creating augmented matrix: TypeError: unable to convert a to an integer

When you defined the matrix u you didn't specify a base ring, so SageMath reasonably guessed it to be the integers ZZ. Hence the error.

The solution is to always specify the base ring, like u = Matrix(SR, [[....

You can also change the base ring later, e.g. u = u.change_ring(SR).

2020-02-11 17:17:16 -0600 answered a question How to rewrite multivariate polynomial as polynomial on one variable?

For this purpose it is more convenient to work in a polynomial ring than in the symbolic ring:

sage: x, y, z = var("x y z")
sage: poly =  x^3*y*z + x^2*y^2 + 3*x^3 + 2*x^2 + x*y + x*z + 1
sage: A = PolynomialRing(QQ, names='y,z')
sage: B = PolynomialRing(A, names='x')
sage: B(poly)
(y*z + 3)*x^3 + (y^2 + 2)*x^2 + (y + z)*x + 1

Or, avoiding the symbolic ring altogether:

sage: A.<y,z> = PolynomialRing(QQ)
sage: B.<x> = PolynomialRing(A)
sage: poly =  x^3*y*z + x^2*y^2 + 3*x^3 + 2*x^2 + x*y + x*z + 1
sage: poly
(y*z + 3)*x^3 + (y^2 + 2)*x^2 + (y + z)*x + 1

You can go back from a polynomial ring element f to the symbolic ring by SR(f).

2020-02-09 11:51:47 -0600 commented question Failing to add a script to sage

Looks like the authors forgot to list some dependencies. Here is one possibility: OrderData. Probably your question is better addressed to the authors.

2020-02-08 06:13:02 -0600 answered a question Tensor Product of Quotient Rings

The two quotient rings are coordinate rings of affine varieties.

The tensor product of coordinate rings is the coordinate ring of the product variety (under some assumptions).

You can construct it like this:

R.<x0,x1> = PolynomialRing(QQ)
IR = R.ideal(x0^2-x1^3)
QR = R.quotient(IR)

S.<y0,y1,y2> = PolynomialRing(QQ)
JS = S.ideal(y0*y1-y2^2)
QS = S.quotient(JS)

T.<a0,a1,b0,b1,b2> = PolynomialRing(QQ)
R_to_T = R.hom([a0,a1])
S_to_T = S.hom([b0,b1,b2])

IT = R_to_T(IR)
JT = S_to_T(JS)

QT = T.quotient(IT + JT)

QR_to_QT = QR.hom(map(QT,[a0,a1]))
QS_to_QT = QS.hom(map(QT,[b0,b1,b2]))

The object you want is QT, which is a quotient of the polynomial ring T.

There are maps from R and S to T, and induced maps from QR and QS to QT.

I used different names for the generators in R and S, but you can also use the same ones as you did, or e.g.:

R = PolynomialRing(QQ, 'x', 2)
IR = R.ideal(R.0^2-R.1^3)
QR = R.quotient(IR)

S = PolynomialRing(QQ, 'x', 3)
JS = S.ideal(S.0*S.1-S.2^2)
QS = S.quotient(JS)

T = PolynomialRing(QQ, 'z', R.ngens() + S.ngens())
R_to_T = R.hom(T.gens()[0:R.ngens()])
S_to_T = S.hom(T.gens()[R.ngens():R.ngens() + S.ngens()])

IT = R_to_T(IR)
JT = S_to_T(JS)

QT = T.quotient(IT + JT)

QR_to_QT = QR.hom([QT(R_to_T(g)) for g in R.gens()])
QS_to_QT = QS.hom([QT(S_to_T(g)) for g in S.gens()])

Here R.0 is shorthand for R.gen(0), the first generator of R, namely x0; R.ngens() is the number of generators of R; R.gens() is the list of generators of R, etc.

2020-02-07 11:55:46 -0600 received badge  Nice Answer (source)
2020-02-07 03:08:51 -0600 answered a question Find order of an Elliptic Curve over Gaussian Integer

While the quotient you constructed is a valid object, it seems to be not the optimal way to construct the respective mathematical object. Apparently, general quotients of the Gaussian integers ZZ[I] currently have only barebones functionality; SageMath doesn't even know when they are finite. However, since p is prime (hence maximal) in ZZ[I] we can compute the residue_field instead (which is a much better implementation of the quotient):

p = 107927
G = ZZ[I]
J = G.ideal(p)
Q.<a> = G.residue_field(J)

A = (95385+100114*a)
B = (18724+61222*a)
E = EllipticCurve(Q,[A, B])
print(E)
print(E.cardinality())

It outputs:

Elliptic Curve defined by y^2 = x^3 + (100114*a+95385)*x + (61222*a+18724) over Residue field in a of Fractional ideal (107927)
11648283482

as you predicted.


Alternatively, making use of the third isomorphism theorem:

p = 107927
Q.<a> = GF(p^2, modulus=x^2+1)

This is possibly even faster.

2020-02-05 13:25:48 -0600 commented answer Sagemath 9.0 Markdown inconsistency Cocalc vs. Local

@eric_g conversely, I posted my comment without seeing yours :)

2020-02-05 13:24:50 -0600 commented answer Sagemath 9.0 Markdown inconsistency Cocalc vs. Local

On cocalc.com if you go to Help → About, it reads:

CoCalc Jupyter notebook is a complete open source rewrite by SageMath, Inc. of the classical Jupyter notebook client from the Jupyter project.

So they are not the same.

2020-02-05 13:10:27 -0600 answered a question Sagemath 9.0 Markdown inconsistency Cocalc vs. Local

This is a bug in Jupyter: #4259 Markdown broken for single-character bold and italics. Hopefully it will be fixed there (although it doesn't seem to be a priority), so eventually the fix will be in SageMath as well.

For now, a workaround is to write 'three' instead of '3' :)

Another idea is to try JupyterLab, where the respective issue is fixed.

2020-02-05 08:40:28 -0600 commented question Weighted adjacency matrix of a graph.

Probably you should create a DiGraph from G. Do you need the weight of (directed) edge (w,v) to be minus the weight of (v,w)?

2020-02-04 17:34:29 -0600 answered a question How are symbolic derivatives composed in quaternions?

Let me summarize the comments:

1) Use symbolic functions, e.g.:

sage: var('y')
sage: f = function('a')(y) + function('b')(y)*i + function('c')(y)*j + function('d')(y)*k
sage: qd(f)
-diff(c(y), y) + diff(d(y), y)*i + diff(a(y), y)*j + (-diff(b(y), y))*k

2) Do the LaTeX yourself (for now), e.g. like this:

def qlatex(u):
    return LatexExpr(' + '.join(r'\bigg[' + latex(u[k]) + r'\bigg]\cdot' + latex(Q.basis()[k]) for k in range(len(Q.basis()))))
show(qlatex(g))

Of course this can be improved (draw parentheses only if necessary, skip zeros, extract signs, etc.)

The documentation of LatexExpr is under LaTeX printing support.

3) Issue #6183 Quaternion algebra latexification has been open for 11 years.

If you want to revive it, you could bring it up (with or without patch) on sage-devel.

The old patch linked in the issue also has the start of a _latex_ method.

2020-02-04 17:18:18 -0600 commented question How are symbolic derivatives composed in quaternions?

Issue #6183 Quaternion algebra latexification has been open for 11 years :) If you want to revive it, you could bring it up (with or without patch) on sage-devel. The old patch linked in the issue also has the start of a _latex_ method.