Ask Your Question

Juanjo's profile - activity

2019-04-17 01:22:40 -0500 received badge  Nice Answer (source)
2019-04-15 20:22:58 -0500 answered a question help with graphics_array magic, please

Check the following example:

# Construct the list of plots
p = []
nplots = 8 # number of plots
for i in range(nplots):
    plt = plot([random()*sin(x),random()*cos(x)],(x,-pi,pi), 
    plt.legend(False) # don't display legends

# Get ymin and ymax
ym = 1e+20
yM = 1e-20
for i in range(nplots):
    bounds = p[i].get_minmax_data()
    ym = min(ym, bounds["ymin"])
    yM = max(yM, bounds["ymax"])

# Display legends in the penultimate plot

# Label the plots on the left column
for i in range(0,nplots-2,2):
    p[i].axes_labels(["",r"$\varphi$ in [V]"])

# Label the plots in the last row
p[-2].axes_labels(["$z_c$ in [m]",r"$\varphi$ in [V]"])
p[-1].axes_labels(["$z_c$ in [m]",""])

# Show plots
ga = graphics_array(p,nrows=nplots/2,ncols=2),ymax=yM,frame=True, figsize=[8,10])

I think it satisfies almost all your requirements. Since labels are doubled if printed in the bottom right plot (I don't know why), I have included them in the bottom left plot.

Note to Sage developers: I think there is a bug in the definition of graphics_array. If only the optional argument ncols is given, the other dimension, i.e. nrows is not always correctly computed (same thing if only nrows is given). For example, let us consider the code:

ga = graphics_array([plot(sin)] * 6, ncols=2)
ga.nrows(), ga.ncols()

This yields (4,2) and an array of 8 plots, the last two ones showing an empty frame. However, one could reasonably expect 6 plots arranged in 3 rows and 2 columns.

Edit: This is the graphics I get for the first example image description

2019-04-15 10:40:48 -0500 answered a question same ymin and ymax accross many seperate plots?

You could put your plots in a list or matrix, iterate to get their dimensions, compute the max and min values for the y axis in all the plots and draw together the plots using graphics_array. As a proof of concept, consider the following example:

p = []
for i in range(3):
    plt = plot([random()*sin(x),random()*cos(x)],(x,-pi,pi), color=["red","green"])

ym = 1e+20
yM = 1e-20
for i in range(len(p)):
    bounds = p[i].get_minmax_data()
    ym = min(ym, bounds["ymin"])
    yM = max(yM, bounds["ymax"])

graphics_array(p).show(frame=True) # each plot uses its own vertical scale
graphics_array(p).show(ymin=ym,ymax=yM, frame=True) # same scale for all plots
2019-04-14 19:15:27 -0500 answered a question return lists that do not share all of the same elements

Assume that your array of lists is stored in my_lists. Then, the lines

sets = map(set,my_lists)

do the trick. You get a list of tuples whose elements are unique, as wanted. For example, if

my_lists = Permutations([3,1,2]).list() + Permutations([6,5,4]).list()

then the above two lines yield

[(4, 5, 6), (1, 2, 3)]
2019-04-13 19:11:29 -0500 commented answer contour_plot with several poles

Since you don't provide the exact definition of the function whose contours you try to plot, I can't tell what happens in every pole.

2019-04-08 08:20:05 -0500 received badge  Good Answer (source)
2019-04-08 07:49:54 -0500 received badge  Nice Answer (source)
2019-04-08 05:30:41 -0500 answered a question Plot breaking the y-axis

Yes, there is a way to do so:

plot([12*x+23,15*x+5], (x, 0, 10), aspect_ratio=.05, ymax=160)

In fact, you can combine plot and show to control more precisely the window where the graph is drawn:

graph = plot([12*x+23,15*x+5], (x, 0, 10), aspect_ratio=.05)
show(graph, xmin=3, xmax=9, ymin=40, ymax=160)
2019-04-08 02:59:10 -0500 received badge  Nice Answer (source)
2019-04-07 19:48:26 -0500 answered a question sage interactive disable auto update?

You can add auto_update=False as an argument to the function defining the interact. For example:

def _(a=slider(0,5,step_size=0.2,default=3),
    show(plot(sin(a*x)+cos(b*x), (x,0,4*pi), color=color))

The interact is only updated when you press the button below the interact controls. See this SageMath Cell.

At least in a Jupyter notebook, you can also use an alternative syntax:

def _(a=slider(0,5,step_size=0.2,default=3),
    show(plot(sin(a*x)+cos(b*x), (x,0,4*pi), color=color))

The button text can be customized. If you prefer, say, "Redraw" instead of the default text, just modify the first line in the preceding snippet as follows:

@interact.options(manual=True, manual_name="Redraw")
2019-04-02 07:50:21 -0500 commented answer grad() at glacial speed

Yes, of course. For example, you could replace

var("Hcsm", latex_name=r"H_{cs}^-")


var("Hcsm", latex_name=r"\color{red}{H_{cs}^-}")

to get $\color{red}{H_{cs}^-}$.

2019-04-01 17:47:11 -0500 answered a question grad() at glacial speed

Perhaps you could stick to the symbolic ring and compute the gradient just with phi_ges.gradient([x,z]). It is quite fast. Then you can grasp how the gradient is by displaying both components of the gradient vector. The second component is a bit "terrific", but the first one is quite human readable as shown in the following screen capture:

image description

Please note that $H^+_s$, $H^-_s$ and so on represent Heaviside functions evaluated at different arguments (see the var functions and the subs method in the picture). I wonder if this expression can be really simplified.

2019-04-01 04:07:44 -0500 commented answer How to save combinations of plots?

You can also combine the graphs with just one plot command:

pic = plot([f1,f2,f3], (x,-1,2), color=["red","green", "blue"])

2019-03-25 19:30:17 -0500 answered a question contour_plot with several poles

(I'd tried to write the following lines as comments to @Emmanuel Charpentier's answer, but I had problems with formatting)

In the preceding answer, I think that the correct syntax is lambda x,z: (x^2+z^2.... Perhaps it is clearer to define before the region to be included. In order to color the excluded region, you can also plot it with region_plot and then combine everything in a single figure. Try, for example, the following complete example:

# Variables

# f is a function with poles in (0,0), (1,0), (0,1), (1,1) 
f(x,y) = 1/(x^2+y^2) + 1/((x-1)^2+y^2) + 1/(x^2+(y-1)^2) + 1/((x-1)^2+(y-1)^2)

# Region where contour lines should be plotted
def region_to_include(x,y):
    return x^2+y^2>0.1 and x^2+(y-1)^2>0.1 and (x-1)^2+y^2>0.1 and (x-1)^2+(y-1)^2>0.1

# As an alternative:
#def region_to_include(x,y):
#    return (x^2+y^2-0.1) * (x^2+(y-1)^2-0.1) * ((x-1)^2+y^2-0.1) * ((x-1)^2+(y-1)^2-0.1)

# Region to be excluded
def region_to_exclude(x,y):
    return not region_to_include(x,y)

# Contour plot on the desired region
c = contour_plot(f(x,y), (x,-1,2), (y,-1,2), region=region_to_include, 
                 contours= 30, plot_points=200, cmap=colormaps.jet, colorbar=True)

# Plot of the region to be excluded
r = region_plot(region_to_exclude, (x,-1,2), (y,-1,2), 
                plot_points=300, incol="gray", bordercol="black", borderwidth=3)

# Final plot
show(c + r, frame=True, axes=False)

See this SageCell

2019-03-25 13:30:45 -0500 commented question SUBSTITUTIONS IN SYMBOLIC EXPRESSIONS

I think you should explain a bit more what you are looking for. If, for example, you only want to replace $a$ in the expression by its value from the equality, you can simply do this:

expression = (r+1)*(r+2) + g + a
2019-03-20 05:32:38 -0500 received badge  Enthusiast
2019-03-18 18:59:42 -0500 commented answer solving a system of equations, depending on only a subset of variables

No, there isn't. I have just copied your Sage sheet and successfully evaluated the code, as you can see here. Try to run it again

2019-03-12 11:21:18 -0500 received badge  Nice Answer (source)
2019-03-11 21:06:20 -0500 answered a question dimensions of image

Try,aspect_ratio=10/8) and then adjust the values of figsize and aspect_ratio to fit your needs.

2019-03-08 04:57:04 -0500 received badge  Commentator
2019-03-08 04:57:04 -0500 commented answer Factor a solve output

Just for completeness, to get the expected answer in the OP, it suffices to convert to integer the output of solve :

sage: factor(ZZ(sols[0].right()))
2 * 3
2019-03-07 19:34:51 -0500 commented answer Solving trigonometric equations in interval.

Just to complement my answer, you can also try the solve function given by Sympy, which provides both roots in $[0,2\pi]$:

sage: import sympy as sp
sage: sp.solve(sin(x)==0.8,x)
[0.927295218001612, 2.21429743558818]
2019-03-07 18:34:02 -0500 answered a question Solving trigonometric equations in interval.

Root finding is a difficult subject. In general, you cannot expect an algorithm to yield all the solutions of a given equation $f(x)=0$. It is required some prior knowledge and analysis of the equation.

The solve function tries to obtain exact solutions, if any. For the equation you propose, that is, $\sin x=0.8$, you have already tested


which yields $x=\arcsin(4/5)$ and misses the other solution in $[0,2\pi]$, which is $x=\pi-\arcsin(4/5)$. You have also tried

solve(sin(x)==0.8, x, to_poly_solve = 'force')

and got something like

[x == pi + 2*pi*z103 - arctan(3602879701896397/7301667457314599911469129704407*sqrt(7301667457314599911469129704407)),
 x == 2*pi*z105 + arctan(3602879701896397/7301667457314599911469129704407*sqrt(7301667457314599911469129704407))]

Here, z103 and z105 represent integer constants. Every time you evaluate such a function, you get different numbers after z. In a more mathematical notation, Sage proposes the solutions $$x=-\arctan\Bigl(\frac{a\sqrt{b}}{b}\Bigr)+\pi(2z_{103}+1)\quad\text{and}\quad x=\arctan\Bigl(\frac{a\sqrt{b}}{b}\Bigr)+2\pi z_{105},$$ where $$a=3602879701896397 \quad\text{and}\quad b=7301667457314599911469129704407.$$ Please, note that we have now an infinite number of solutions. If z103 and z105 are replaced by given integers, we get specific solutions. For example,

sol = solve(sin(x)==0.8, x, to_poly_solve = 'force')
print "First solution:", sol[0].rhs().subs(z103=0).n()
print "Second solution:",sol[1].rhs().subs(z105=0).n()


First solution: 2.21429743558818
Second solution: 0.927295218001612

assuming, of course, that z103 and z105 still were the constants appearing in sol. These are the expected roots (up to an error of order $10^{-16}$) in $[0,2\pi]$, since

sage: print N(arcsin(4/5)), N(pi-arcsin(4/5))
0.927295218001612 2.21429743558818

The find_root function applies a numerical algorithm, essentially Brent's method. So each call to find_root will yield, if any, just one approximated root of the equation. Hence, to find all the zeros of a function, you need to know in advance how many they are and where they live and then use find_root as many times as needed, changing the corresponding intervals.

2019-03-06 17:52:58 -0500 answered a question convert .solve output to function

Once you get solns, which is a list, extract the first element and take the right hand side with the .rhs method to define f, that is,

f(t) = solns[0].rhs()
2019-03-06 11:37:30 -0500 commented answer What an efficient way to construct a n by n matrix with all entries -1?

@nbruin Yes, you are right. Now %%timeit yields 10 loops, best of 3: 146 ms per loop. To be fair, an analog time reduction happens in the second alternative:

 a = -1

10 loops, best of 3: 74.2 ms per loop

which is as fast as -ones_matrix(ZZ,m,m).

2019-03-06 10:17:32 -0500 commented answer What an efficient way to construct a n by n matrix with all entries -1?

For the sake of comparison, once done all the imports and set m=1000, let us test the time required by each option:

matrix(m,m,lambda i,j:-1)

1 loop, best of 3: 431 ms per loop


10 loops, best of 3: 98.3 ms per loop


1000 loops, best of 3: 1.79 ms per loop


10 loops, best of 3: 72 ms per loop

In a different computer, results will be different, of course. Except in the case of the Numpy array, the elements of the resulting matrix belong to the Integer Ring.

2019-03-06 09:28:11 -0500 received badge  Editor (source)
2019-03-06 09:25:53 -0500 answered a question What an efficient way to construct a n by n matrix with all entries -1?

As another alternative, you can use ones_matrix, which returns a matrix with all entries equal to 1. So, to build, say, an $1000\times1000$ matrix with all entries being $-1$, you can simply write -ones_matrix(1000,1000).

2019-03-06 09:07:29 -0500 received badge  Nice Answer (source)
2019-03-05 17:59:49 -0500 answered a question Checking that symbolic expression is zero

Try this:

bool(-1/16*sqrt(6)*sqrt(3)*sqrt(2) + 1/16*I*sqrt(6)*sqrt(2) - 1/8*I*sqrt(3) + 3/8==0)

The answer is True.

2019-03-04 22:25:18 -0500 received badge  Good Answer (source)
2019-03-03 18:27:52 -0500 answered a question Defining a relationship between symbolic variables

You can save the equation in a variable and apply it through the .subs method. Try, for example, the following code:

eq = a+b+c==1
print (a^2 + 2*a*b + b^2 + 2*a*c + 2*b*c + c^2).factor().subs(eq)
print (1/a + 1/b + c/(a*b)).simplify_rational().subs(eq)
2019-03-03 08:25:25 -0500 received badge  Nice Answer (source)
2019-03-02 21:24:40 -0500 answered a question How to plot ellipsoid with interact?

The following code may serve as a starting point:

def ellipsoid(a=slider(1,5,step_size=0.2,default=3),
    x1, x2, y1, y2, z1, z2 = -a, a, -b, b, -c, c
    figure = implicit_plot3d(x^2/a^2+y^2/b^2+z^2/c^2==1, (x,x1,x2), (y,y1,y2), (z,z1,z2),
                             color=color, viewer='threejs')

It can be seen in action here. You may want to read this tutorial as well as these examples about the @interact command

2019-03-02 20:14:43 -0500 received badge  Supporter (source)
2019-02-23 16:12:34 -0500 received badge  Nice Answer (source)
2019-02-23 16:07:09 -0500 received badge  Enlightened (source)
2019-02-23 16:07:07 -0500 received badge  Good Answer (source)
2019-02-20 14:55:52 -0500 received badge  Nice Answer (source)
2019-02-20 14:55:31 -0500 received badge  Necromancer (source)
2019-02-20 09:02:01 -0500 commented answer Is there a way to use sage-boolean-values in Latex

In fact, there is no need to switch a and b. You can simply write $\sage{max(a,b)}-\sage{min(a,b)}$.

2019-02-20 08:49:27 -0500 answered a question Is it possible to customize the default behavior of sagetex?

You can follow the strategy given in my answer to this question you made later. For the sake of completeness, I adapt it here.

Write a tex file with all the code you need to config SageTeX:

   latex.matrix_delimiters(left='[', right=']')
   latex.vector_delimiters(left='<', right='>')

Call it, for example, STconfig.tex. Then write a small package mysagetex.sty with the following content:

\ProvidesPackage{mysagetex}[2019/02/20 v.0.1]

Put both files together where TeX can find them. In the source tex file, it suffices to load mysagetex instead of sagetex, e.g., add \usepackage{mysagetex} to the preamble.

2019-02-20 07:19:39 -0500 received badge  Necromancer (source)
2019-02-20 07:19:39 -0500 received badge  Teacher (source)