Ask Your Question

eric_g's profile - activity

2019-10-12 08:35:52 -0500 commented question jmol stuck at "Initializing 3D display"

For the record, the issue is fixed in SageMath 8.9, thanks to the update of Jmol performed in #25026.

2019-10-10 16:26:48 -0500 answered a question Inverse of the transition map on a Manifold doesn't hold

As said at the end of the message, a failed report can reflect a lack of simplification and not a true failure. This is the case here, because on the intersection domain D, z < 0 and w > 0, so you can conclude that z == -abs(z) and w == abs(w) are both true and that the test is actually passed. Therefore you can go on...

It is a pity though that Sage does not arrive automatically at the same conclusion. This is a weakness of the current simplifying mechanism on subcharts and should be improved in the future.

2019-10-07 03:24:56 -0500 commented answer sage-8.9 fails compilation in Ubuntu 18.04

@dsejas Yes indeed the Ubuntu package python was installed on my computer prior to Sage build.

2019-10-05 15:45:12 -0500 commented answer Changing chart multiple times in sagemanifolds

SageMath 8.9 is out now. You can check that your example works nicely with it.

2019-10-04 10:34:09 -0500 commented answer sage-8.9 fails compilation in Ubuntu 18.04

I've just compiled successfully Sage 8.9 (Python 3 version) from scratch on a Ubuntu 18.04 computer. The only png-related package installed on that computer is libpng16-16 (in particular, libpng-dev is not installed). So I am puzzled by your issue. If this might be helpful, here are the steps of what I've done:

git clone
cd sage
make configure
./configure --with-python=3
MAKE="make -j16" make
2019-10-01 00:59:41 -0500 answered a question sage-8.9 fails compilation in Ubuntu 18.04

On Ubuntu 18.04, you should install the Ubuntu package libpng16-16 prior to SageMath installation.

2019-09-30 08:16:16 -0500 commented answer Transformation of derivative under a change of chart

I am not sure to understand what you want exactly. The $\mathrm{D}_0\Phi$ notation gets rid of expressions like $\partial/\partial(r\sin\theta)$. I agree that the Pynac notation $\mathrm{D}_0\Phi$ is not standard mathematical notation and that $\partial\Phi/\partial x$ would be preferable here. I am afraid there is no simple way to achieve this in SageMath, since symbolic functions, as defined with function(), do not have the notion of given names (e.g. x, y, z) for their arguments.

2019-09-30 05:02:19 -0500 received badge  Nice Answer (source)
2019-09-29 03:46:01 -0500 answered a question Interactive linear programming

According to the documentation returned by


your input code is not correct, since InteractiveLPProblemStandardForm has no keyword argument constraint_type. Moreover, the documentation says:

Unlike "InteractiveLPProblem", this class does not allow you to
adjust types of constraints (they are always ""<="") and variables
(they are always "">=""), and the problem type may only be ""max""
or ""-max"".
2019-09-27 15:41:00 -0500 answered a question Transformation of derivative under a change of chart

You can use

Manifold.options.textbook_output = False

Then $\mathrm{D}_0 \Phi$ stands for $\frac{\partial \Phi}{\partial x}$, etc.

See here for details about the display options.

2019-09-27 05:02:40 -0500 answered a question Display connection coefficients under a change of chart

The issue arises because the transition map from chart Y to chart X_U has not been defined. You must implement it as follows, just after the definition of transit_Y_to_X:

transit_Y_to_X.set_inverse(t, atan2(y, x) - Omega*t, atan2(z, sqrt(x^2+y^2)), sqrt(x^2+y^2+z^2), 

Then the display of the connection coefficients w.r.t. Y.frame() works, albeit quite slow (*).

(*) while investing your issue, I've discovered that the computation can be significantly improved by reordering some loops; this is now Trac #28543.

2019-09-25 15:02:41 -0500 commented question Stack overflow in boolean test

Confirmed with Sage 8.9.rc0, as well as with Sage 8.3. So the bug has been there for a while...

2019-09-25 14:01:17 -0500 answered a question Saving notebooks with 3dplots

In the Jupyter notebook:

  1. use the option viewer='threejs' in the 3d plot functions (what follows does not work with the current default 3d viewer (Jmol))
  2. in the File menu, select "Print preview" --> this opens a new tab in the browser
  3. print the preview tab via CTRL+P and select "print in a file" (pdf format)
2019-09-25 06:38:56 -0500 commented question Interaction with a graphics

You can use \frac{R}{x_p} in the plot: you simply need to enter it as a raw string, via the prefix 'r' in front of the quotes. This guarantees that the backslash of \frac is correctly interpreted as part of a LaTeX command:

t5 = text(r"$\frac{R}{p_x}$", (2, -.05), fontsize=12, color="black")

Equivalently, you can use a double backslash:

t5=text("$\\frac{R}{p_x}$", (2, -.05), fontsize=12, color="black")
2019-09-12 16:28:08 -0500 commented answer jmol stuck at "Initializing 3D display"

This bug is another motivation for #22408. @Emmanuel_Charpentier: which "own share of problems" has threejs, given the recent improvements?

2019-09-12 16:25:28 -0500 commented answer jmol stuck at "Initializing 3D display"

Another workaround is to run the code in a Jupyter notebook. There it is the JavaScript version of Jmol that is invoked, note the Java one, and it works (tested with Ubuntu 18.04).

2019-09-12 16:22:46 -0500 commented question jmol stuck at "Initializing 3D display"

Same issue with Ubuntu 18.04 (OpenJDK 11.0.4).

2019-09-09 11:04:25 -0500 received badge  Nice Answer (source)
2019-09-08 14:52:19 -0500 answered a question simplify not working correctly with conjugate?

Well, it seems that when using conjugate, you have to specify that the involved symbolic variables are complex. Indeed one has

sage: (x - conjugate(x)).simplify()
sage: v = var('v')
sage: (v - conjugate(v)).simplify()

(I am a little bit puzzled by this, since I thought Sage's symbolic variables are assumed complex by default)


sage: v = var('v', domain='complex')
sage: (v - conjugate(v)).simplify()
v - conjugate(v)


sage: v = var('v')
sage: assume(v, 'complex')
sage: (v - conjugate(v)).simplify()
v - conjugate(v)

So, regarding your example, you have to use var('a', 'v', domain='complex') in the first line.

2019-09-08 08:49:42 -0500 answered a question Error computing curvature of graph submanifold

Thanks for reporting this issue. This is a bug, which is now fixed in the ticket #28462. Hopefully, this ticket will be merged in Sage 8.9 (to come out soon).

With #28462, your code leads to

sage: K = Q.extrinsic_curvature()
sage: K.display_comp()
K_uu = -4*sqrt(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 3)*(u - v)/(sqrt(2)*u^6 + sqrt(2)*v^6 + 3*(sqrt(2)*u^2 + sqrt(2))*v^4 + 3*sqrt(2)*u^4 + (3*sqrt(2)*u^4 + 6*sqrt(2)*u^2 + 5*sqrt(2))*v^2 + 5*sqrt(2)*u^2 + 3*sqrt(2)) 
K_uv = -4*sqrt(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 3)*(u + v)/(sqrt(2)*u^6 + sqrt(2)*v^6 + 3*(sqrt(2)*u^2 + sqrt(2))*v^4 + 3*sqrt(2)*u^4 + (3*sqrt(2)*u^4 + 6*sqrt(2)*u^2 + 5*sqrt(2))*v^2 + 5*sqrt(2)*u^2 + 3*sqrt(2)) 
K_vu = -4*sqrt(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 3)*(u + v)/(sqrt(2)*u^6 + sqrt(2)*v^6 + 3*(sqrt(2)*u^2 + sqrt(2))*v^4 + 3*sqrt(2)*u^4 + (3*sqrt(2)*u^4 + 6*sqrt(2)*u^2 + 5*sqrt(2))*v^2 + 5*sqrt(2)*u^2 + 3*sqrt(2)) 
K_vv = 4*sqrt(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 3)*(u - v)/(sqrt(2)*u^6 + sqrt(2)*v^6 + 3*(sqrt(2)*u^2 + sqrt(2))*v^4 + 3*sqrt(2)*u^4 + (3*sqrt(2)*u^4 + 6*sqrt(2)*u^2 + 5*sqrt(2))*v^2 + 5*sqrt(2)*u^2 + 3*sqrt(2))

Side note: your declaration of phi_inv is not correct: with your code, we have

sage: phi_inv.display()
P --> Q
   (x, y, z) |--> (u, v) = (u, v)

As you can see, the output is ill-formed, because (u, v) should be a function of (x, y, z).

The correct declaration should be

sage: phi_inv = P.diff_map(Q, {(CP, CQ) : list(CP[1:])})

which leads to

sage: phi_inv.display()
P --> Q
   (x, y, z) |--> (u, v) = (y, z)

Forturnately, phi_inv plays no role in the computation of the extrinsic curvature.

EDIT (14 Sep. 2019): the fix introduced in #28462 has been merged in Sage 8.9.rc0, so the next stable release of Sage will be free from this bug.

2019-09-02 12:52:58 -0500 received badge  Nice Answer (source)
2019-08-30 04:24:58 -0500 commented answer Changing chart multiple times in sagemanifolds

@my_screen_name: you are right: in the current stable version of Sage (8.8), there are unnecessary restrictions in the handling of coordinate changes. This is fixed by the Trac ticket #28072, which has been merged in Sage 8.9.beta2. In particular, with run with Sage 8.9.beta8, your original code gives no error and displays $g = \mathrm{d}z\otimes\mathrm{d}z$ in the last line. I have edited my answer accordingly.

2019-08-29 14:37:08 -0500 answered a question Changing chart multiple times in sagemanifolds

The issue arises because you have not fully defined the transition maps on the manifold: the inverse maps are missing. You have to generate them by invoking


just after the definition of ChangeFirst_to_Second and


just after the definition of ChangeSecond_to_Third. Then everything is OK.

The reason why the inverse transition maps are not automatically evaluated is that in certain cases Sage is not capable to compute them (the method inverse() returns then an error); the user has then to provide them by hand, via the method set_inverse().

EDIT: actually, in the present case, the inverse transition maps should not be required to compute the expression of $g$ in the third frame. This will be fixed in the next release of SageMath, thanks to the Trac ticket #28072, which has been merged in SageMath 8.9.beta2.

2019-08-28 06:24:23 -0500 answered a question How to set a metric tensor inverse?

g._inverse.set_comp(XI.frame())[:] = Ginv[:] should work (notice that it starts with g._inverse, not g.inverse(), and that set_comp must be used instead of comp).

Probably we should implement a method set_inverse() to allow easily for this.

2019-08-26 05:37:23 -0500 received badge  Nice Answer (source)
2019-08-22 15:18:04 -0500 answered a question Setting the components of a differential form systematically.

You should write

sage: d[2][R] = 1

Indeed, when R is the list [eU, 0, 1], as in your example, the above is equivalent to

sage: d[2][eU, 0, 1] = 1

Side note: in your example, the line

sage: d = {(i): var("d_{}".format(i)) for i in range(2*p*q)}

is useless, because the elements of the dictionary d are fully redefined in the two lines that follow:

sage: for i in range(2*p*q):
sage:     d[i] = M.diff_form(i)

If you want to give names to the differential forms d[i], you could write simply

sage: d = {i: M.diff_form(i, name="d_{}".format(i)) for i in range(2*p*q)}


sage: d[2]
2-form d_2 on the 4-dimensional complex manifold M
sage: R = [eU, 0, 1]
sage: d[2][R] = 1
sage: d[2].display()
d_2 = dx_0/\dx_1
2019-08-17 23:01:25 -0500 received badge  Good Answer (source)
2019-08-15 18:09:08 -0500 received badge  Nice Answer (source)
2019-08-14 09:51:40 -0500 answered a question Source for Principal Null Directions Kerr, Example Worksheet

The vectors $\ell$ and $k$ introduced in this notebook correspond to Eqs. (12.3.5) and (12.3.6) of Wald's textbook General Relativity (1984).

You can check that they do define repeated principal null directions, i.e. that they obey the following identity (where $C^a_{\ \ bcd}$ stands for the Weyl tensor) $$ C^a_{\ \ mn[b} k_{c]} k^m k^n = 0,\qquad\qquad\mbox{(1)}$$ with SageMath itself (no need of Mathematica ;-)). It suffices to run (same notations as in the original notebook)

C = g.weyl()
(C.contract(1, 2, k*k, 0, 1) * k.down(g)).antisymmetrize(1, 2).display()

which yields 0.

If you prefer to use index notations (passed as strings in LaTeX format) instead of contract() and antisymmetrize(), SageMath allows for it as well. The check of (1) is then equivalent to

A = C['^a_{mnb}'] * (k*k)['^{mn}']
kf = g['_{am}'] * k['^m']

the outcome of which is 0.

A Jupyter notebook implementing the check of (1) by both methods is posted here.

2019-07-29 03:45:20 -0500 received badge  Nice Answer (source)
2019-07-03 13:23:28 -0500 received badge  Guru (source)
2019-07-03 13:23:28 -0500 received badge  Great Answer (source)
2019-06-27 08:08:41 -0500 answered a question (Update) How to change/set variables?

Once, CH has been computed, changing the values of the forms f[i] has no effect on CH, because they have gone from the expression of CH, which is made only in terms of the symbolic variables g_*, as pointed out by @rburing 's comment 1. What you want to do is a substitution in CH. As stressed in @rburing 's comment 2, substitution of symbolic variables will not work if the computation involves any derivative. You must use instead symbolic functions. Here is an example:

sage: M = Manifold(3, 'M')
sage: X.<x,y,z> = M.chart()
sage: f = M.diff_form(2)
sage: f[0,1] = function('F')(x,y,z)   # an unspecified function of (x,y,z)
sage: f[1,2] = function('G')(x,y,z)
sage: f.display()
F(x, y, z) dx/\dy + G(x, y, z) dy/\dz
sage: df = f.exterior_derivative()
sage: df.display()
(d(F)/dz + d(G)/dx) dx/\dy/\dz
sage: F0(x,y,z) = x*y*z   # a callable symbolic expression
sage: G0(x,y,z) = x^2
sage: df[0,1,2] = df[0,1,2].expr().substitute_function(F, F0)  # NB: substitute_function, not subs
sage: df[0,1,2] = df[0,1,2].expr().substitute_function(G, G0)
sage: df.display()
(x*y + 2*x) dx/\dy/\dz
2019-06-23 10:54:57 -0500 answered a question Tensor ordering

Yes this is the second form, namely $$ S^{abc}_{\quad def} T^{ghi}_{\quad jbk} = R^{acghi}_{\quad \ \ defjk} $$ This is so because in SageMath, the contravariant indices come always before the covariant ones.

2019-06-20 10:18:12 -0500 edited answer Opening "old" Sage Notebooks in Jupyter: not UTF-8 encoded

You cannot open your sws notebooks directly with Jupyter. Rather, you should first convert them to ipynb format. This is easily done by running the Sage notebook exporter, via

sage -n

Under "Convert old notebooks to Jupyter", you will see the list of your sws notebooks. Click on one of them to convert it to Jupyter format.