Banner de Sage

{{{id=222| /// }}}

Sage es software libre

{{{id=286| /// }}}

¿Quién hace Sage?

El proceso de desarrollo

¿Dónde está la comunidad de desarrolladores?

{{{id=288| /// }}} {{{id=287| /// }}} {{{id=5| /// }}}

¿Cómo es Sage por dentro?

Sage usa el lenguaje python para integrar librerías de matemáticas existentes de una forma consistente. También se escribe código nuevo en python, y en cython cuando se necesita más velocidad.

sage builds the car

Paquetes de Matemáticas incluídos en SAGE

Álgebra GAP, Maxima, Singular
Geometría Algebraica
Singular
Aritmética de Precisión Arbitraria GMP, MPFR, MPFI, NTL
Geometría Aritmética PARI/GP, NTL, mwrank, ecm
Cálculo Maxima, SymPy, GiNaC
Combinatoria Symmetrica, Sage-Combinat
Álgebra Linear ATLAS, BLAS, LAPACK, NumPy, LinBox, IML, GSL
Teoría de Grafos NetworkX
Teoría de Grupos GAP
Cálculo Numérico GSL, SciPy, NumPy, ATLAS
Teoría de Números PARI/GP, FLINT, NTL
Estadística
R, SciPy

Otros paquetes incluídos en SAGE

Línea de Comandos IPython
Bases de datos
ZODB, Python Pickles, SQLite
Interfaces gráficas
Sage Notebook, jsmath, jQuery
Gráficos Matplotlib, Tachyon3d, GD, Jmol
Lenguaje de programación

Python, Cython

Networking Twisted
Etcétera Paquetes estándar

 

{{{id=2| /// }}} {{{id=1| /// }}}

Usa python en vez de inventar su propio lenguaje

Usar un lenguaje popular y sofisticado tiene muchas ventajas:

{{{id=290| #La indentación marca el principio y el final de los bloques n = 17 while n != 1: print n, if n%2 == 0: n /= 2 else: n = 3*n + 1 print 1 /// }}} {{{id=289| #python es dinámico: no necesitamos saber el tipo de datos #al escribir el código def suma(a,b): return a + b print suma(1,1) var('x') show( suma(sin(x), exp(x)) ) show( suma(graphs.HouseGraph(), graphs.CubeGraph(3)) ) /// }}} {{{id=257| #python es orientado a objetos #Cada dato tiene un tipo de datos, con sus propios métodos g = graphs.CubeGraph(3) print type(g) show(g,layout='spring') M = g.adjacency_matrix() print type(M) show(M) p = M.characteristic_polynomial() print type(p) show(p) /// }}} {{{id=251| #list comprehension #todos los primos menores que 100 que son de la forma z^2+1 print [p for p in prime_range(100) if (p-1).is_square()] #el numero de lados de cada CubeGraph para k<10 #(número de aristas de un cubo k-dimensional) print [graphs.CubeGraph(k).num_edges() for k in range(2,10) ] /// }}} {{{id=248| #ejemplo con "generator expression" #suma de los inversos de los primos menores que 100 #nota: es un numero racional sum(1/p for p in prime_range(100) ) /// }}} {{{id=237| #hay algun numero primo de la forma 2k+1 con k entre A y B? A = 1000 B = 2000 print any(is_prime(2*k+1) for k in range(A, B)) #Al usar un generador, no se emplea tiempo en comprobar si todos #los números entre A y B son primos. #La ejecución se detiene cuando se encuentra el primer número primo /// }}} {{{id=249| #Jerarquía de errores A = matrix(QQ,[[1,1,0],[2,2,0]]) v = vector(QQ,[1,0]) A.solve_right(v) /// }}} {{{id=239| A = matrix(QQ,[[2,0],[1,3]]) v = vector(CDF,[i,0]) A.solve_right(v) /// }}} {{{id=240| A = matrix(QQ,[[2,0],[1,3]]) v = vector(CDF,[1,0]) try: print A.solve_right(v) except TypeError: print A.base_extend(CDF).solve_right(v) /// }}} {{{id=274| A = matrix(QQ,[[1,1,0],[2,2,0]]) v = vector(QQ,[1,0]) try: print A.solve_right(v) except TypeError: print A.base_extend(CDF).solve_right(v) /// }}}

Documentación en varios formatos útiles

{{{id=375| /// }}} {{{id=234| VectorSpace? /// }}} {{{id=291| is_power_of_two?? /// }}} {{{id=241| /// }}}

La separación de cliente y servidor ofrece muchas posibilidades

{{{id=294| /// }}} {{{id=243| /// }}}

Crea interacciones en el navegador que se pueden usar sin saber programar

{{{id=246| #No es necesario entender el código para usar un "interact" var('x') @interact def mi_taylor(f = ("f(x)=",sin(x)), intervalo = range_slider(0,10,default=(0,1)), a = ("punto",(0,(0,10))), orden = ("Orden del polinomio",(1,(0..10)))#slider(0,10,1,default = 1) ): f_taylor = f.taylor(x,a,orden) x0, x1 = intervalo x0 = min(x0,a) x1 = max(x1,a) show(f) show(f_taylor) (plot(f,x,x0,x1) + plot(f_taylor,x,x0,x1,color='red') + point2d((a,f(x=a)), pointsize= 30, color='green') ).show() /// }}} {{{id=259| #Otro ejemplo, usando el nuevo editor de grafos interactivo g = graphs.HouseGraph() graph_editor(g); /// }}} {{{id=258| #Siguen cálculos relacionados con el número cromático y el polinomio cromático numero_cromatico = g.chromatic_number() K = numero_cromatico + 2 print 'Número cromático: %d'%numero_cromatico #H = g.coloring(hex_colors=True, algorithm="MILP") H = g.coloring(hex_colors=True) p = g.chromatic_polynomial() g.plot(vertex_colors=H).show() vs = [p(x=j) for j in range(K)] print 'Polinomio cromático' show(p) (point([(j,p(x=j)) for j in range(K+1)], pointsize=30, color='red') + plot(p,0,K)).show() for j in range(K+1): print j,':',p(x=j) /// }}} {{{id=282| /// }}} {{{id=226| /// }}}

Una forma rápida de instalar mucho software científico

Instalando Sage instalas octave, maxima, singular, GAP ...

(como consecuencia, Sage es bastante grande (~2.5GB) )

sage -maxima

;;; Loading #P"/home/moriarty/sage/local/lib/ecl/defsystem.fas"
;;; Loading #P"/home/moriarty/sage/local/lib/ecl/cmp.fas"
;;; Loading #P"/home/moriarty/sage/local/lib/ecl/sysfun.lsp"
Maxima 5.20.1 http://maxima.sourceforge.net
using Lisp ECL 10.2.1
Distributed under the GNU Public License. See the file COPYING.
Dedicated to the memory of William Schelter.
The function bug_report() provides bug reporting information.
(%i1)

sage -R


R version 2.10.1 (2009-12-14)
Copyright (C) 2009 The R Foundation for Statistical Computing
ISBN 3-900051-07-0

R es un software libre y viene sin GARANTIA ALGUNA.
Usted puede redistribuirlo bajo ciertas circunstancias.
Escriba 'license()' o 'licence()' para detalles de distribucion.

R es un proyecto colaborativo con muchos contribuyentes.
Escriba 'contributors()' para obtener más información y
'citation()' para saber cómo citar R o paquetes de R en publicaciones.

Escriba 'demo()' para demostraciones, 'help()' para el sistema on-line de ayuda,
o 'help.start()' para abrir el sistema de ayuda HTML con su navegador.
Escriba 'q()' para salir de R.

>

etcetera...

{{{id=262| /// }}}

Interacción via web con otros programas

Puedes usar otros programas desde el notebook.

PARI+GP seleccionando gp en el desplegable de lenguaje:


{{{id=215| %r #Escribiendo %r al principio del cuadro de comandos, #el código que sigue es de R, no de sage a <- c(260, 316, 111, 93, 136, 278, 258, 155, 197, 102) b <- c(530, 657, 243, 195, 286, 559, 546, 348, 430, 233) stem(a) #Para guardar las imagenes en el notebook, usamos los #comandos de R necesarios para guardar la imagen png('rplot.png') plot(a,b) abline(lm(b ~ a)) dev.off() /// }}}

Combinar software muy diverso de forma armoniosa

{{{id=299| var('x y') f = sin(y)*x + e^(-x^2) #Usa maxima assume(x != 0) a = f.integrate(y,0,x^2).integrate(x,0,1) show(a) /// }}} {{{id=301| #Usa PARI a.n().sage /// }}} {{{id=300| #Usa matplotlib show( contour_plot(f,(x,-1,1),(y,-1,1)), aspect_ratio=1 ) /// }}} {{{id=305| #Usa tachyon, un trazador de rayos show( plot3d(f,(x,-1,1),(y,-1,1)), viewer='tachyon') /// }}} {{{id=298| #scipy no está completamente integrado #antes de poder usar alguna funcionalidad muy interesante #hay que importar scipy from scipy.integrate import dblquad dblquad(lambda y0,x0: sin(y0)*x0 + e^(-x0^2), 0, 1, lambda x0:0, lambda x0: x0^2 ) /// }}} {{{id=269| /// }}}

Mejora tu código sin apenas cambiar de lenguaje

{{{id=14| def mysum(N): s = int(0) for k in range(1,N): s += k return s /// }}} {{{id=12| time mysum(10^7) /// }}} {{{id=267| %cython def mysum_cython1(N): s = 0 for k in range(N): s += k return s /// }}} {{{id=266| time mysum_cython1(10^7) /// }}} {{{id=247| %cython def mysum_cython2(int N): cdef int k cdef long long s = 0 for k in range(N): s += k return s /// }}} {{{id=264| time mysum_cython2(10^7) /// }}}

Aprovecha la infraestructura para desarrollar tu propio código

Por ejemplo, sage-combinat (antes mupad-combinat):

{{{id=315| P = Partitions(8) print P.random_element() print P.cardinality() print P.list() /// }}} {{{id=351| #Subconjuntos de [0,1,..,7] de dos elementos Subsets(range(8),2).list() /// }}} {{{id=352| #Todas las formas de sumar 10 euros con "billetes" de 2, 3 y 5 WeightedIntegerVectors(10, [2,3,5]).list() /// }}} {{{id=284| /// }}}

Modificar Sage

Si Sage no es exactamente lo que necesitas, siempre puedes adaptarlo a tus necesidades: FEMhub usa python y el notebook de Sage para compartir y comparar código de elementos finitos.

 

{{{id=316| /// }}}

Ejemplos...

Haz de cónicas. Calculamos el haz de cónicas que pasa por 4 puntos y lo animamos.

{{{id=317| puntos = [(0,0),(0,1),(1,3),(2,1)] K = len(puntos) var('x y') coefs = matrix(QQ, K, 6) for j in range(K): x0, y0 = puntos[j] coefs[j,:] = vector([x0^2, y0^2, x0*y0, x0, y0, 1]) K = coefs.right_kernel() v1 = K.basis()[0] v2 = K.basis()[1] show(K.basis()) graficas = [] for t in srange(0,2*pi,0.3): c1, c2 = sin(t), cos(t) a,b,c,d,e,f = c1*v1 + c2*v2 curva = a*x^2 + b*y^2 + c*x*y + d*x + e*y + f graficas.append( point2d(puntos,color=(1,0,0),pointsize=30) + implicit_plot(curva,(x,-1,4),(y,-1,4)) ) a = animate(graficas) /// }}} {{{id=295| a.show(delay=10) /// }}} {{{id=386| /// }}} {{{id=385| /// }}}

Teorema de la aplicación conforme de Riemann. Recientemente se ha incluído en Sage código para calcular de forma numérica la aplicación conforme desde un dominio del plano al disco unidad.

{{{id=322| ps = polygon_spline([(-1, -1), (1, -1), (1, 1), (-1, 1)]) f = lambda t: ps.value(t) fprime = lambda t: ps.derivative(t) m = Riemann_Map([f], [fprime], 0.25, ncorners=4) m.plot_colored() + m.plot_spiderweb() /// }}} {{{id=359| /// }}}

Singular value decomposition. Comprime una imagen sustituyendo la matriz que representa la imagen por la mejor aproximación de rango k.

{{{id=355| import pylab A_image = pylab.mean(pylab.imread(DATA + 'fractal_donana.jpg'), 2) @interact def svd_image(i = ("Eigenvalues (quality)",(20,(1..100))), display_axes = ("Display Axes", True)): u,s,v = pylab.linalg.svd(A_image) A = sum(s[j]*pylab.outer(u[0:,j], v[j,0:]) for j in range(i)) g = graphics_array([matrix_plot(A),matrix_plot(A_image)]) show(g, axes=display_axes, figsize=(10,4)) html('

Image compressed using %s eigenvalues

'%i) /// }}} {{{id=356| /// }}}

Yoda. Lee un archivo matlab con una figura 3D, y muestra la figura en un marco interactivo.

{{{id=358| from scipy import io x = io.loadmat(DATA + 'yodapose.mat') from sage.plot.plot3d.index_face_set import IndexFaceSet V = x['V']; F3 = x['F3']-1; F4 = x['F4']-1 Y = (IndexFaceSet(F3, V, color = Color('#00aa00')) + IndexFaceSet(F4, V, color = Color('#00aa00'))) Y = Y.rotateX(-1) Y.show(aspect_ratio = [1,1,1], frame = False, figsize = 4) /// }}} {{{id=378| /// }}}

Cambios de coordenadas. Un ejemplo de interact que puede dar mucho juego en una clase de Cálculo Vectorial, sin necesidad de hablar del código.

{{{id=382| #ejemplo de Jason Grout modificado #http://wiki.sagemath.org/interact/calculus#CoordinateTransformations var('u v') from sage.ext.fast_eval import fast_float from functools import partial @interact def trans(x=input_box(u^2-v^2, label="x=",type=SR), \ y=input_box(u*v, label="y=",type=SR), \ u_percent=slider(0,1,0.05,label="u", default=.7), v_percent=slider(0,1,0.05,label="v", default=.7), u_interval = range_slider(-5, 5, default=(0,2), label="u lines"), v_interval = range_slider(-5, 5, default=(0,2), label="v lines"), ticks = ("ticks",(10,(2..20))) ): u_min, u_max = u_interval u_range = srange(u_min, u_max + (u_max - u_min)/ticks, (u_max - u_min)/ticks) v_min, v_max = v_interval v_range = srange(v_min, v_max + (v_max - v_min)/ticks, (v_max - v_min)/ticks) thickness=4 u_val = min(u_range)+(max(u_range)-min(u_range))*u_percent v_val = min(v_range)+(max(v_range)-min(v_range))*v_percent # t_min = -t_val # t_max = t_val g1=sum([parametric_plot((i,v), (v,v_min,v_max), rgbcolor=(1,0,0)) for i in u_range]) g2=sum([parametric_plot((u,i), (u,u_min,u_max), rgbcolor=(0,0,1)) for i in v_range]) vline_straight=parametric_plot((u,v_val), u_min,u_max, rgbcolor=(0,0,1), linestyle='-',thickness=thickness) uline_straight=parametric_plot((u_val, v), v_min,v_max,rgbcolor=(1,0,0), linestyle='-',thickness=thickness) (g1+g2+vline_straight+uline_straight).save("uv_coord.png",aspect_ratio=1, figsize=[5,5], axes_labels=['$u$','$v$']) xuv = fast_float(x,'u','v') yuv = fast_float(y,'u','v') xvu = fast_float(x,'v','u') yvu = fast_float(y,'v','u') g3=sum([parametric_plot((partial(xuv,i),partial(yuv,i)), (v_min,v_max), rgbcolor=(1,0,0)) for i in u_range]) g4=sum([parametric_plot((partial(xvu,i),partial(yvu,i)), (u_min,u_max), rgbcolor=(0,0,1)) for i in v_range]) vline=parametric_plot((partial(xvu,v_val),partial(yvu,v_val)), (u_min,u_max), rgbcolor=(0,0,1), linestyle='-',thickness=thickness) uline=parametric_plot((partial(xuv,u_val),partial(yuv,u_val)), (v_min,v_max),rgbcolor=(1,0,0), linestyle='-',thickness=thickness) (g3+g4+vline+uline).save("xy_coord.png", aspect_ratio=1, figsize=[5,5], axes_labels=['$x$','$y$']) print jsmath("x=%s, \: y=%s"%(latex(x), latex(y))) print "
" /// }}} {{{id=390| /// }}}

Créditos

En esta charla he usado material de:

{{{id=285| /// }}}