El ejercicio se presenta como un complemento para la sección 1.4 que permite obtener una gráfica animada.
Esta sección es complementaria y usada solo como referencia para exponer el tema. Normalmente se da una explicación breve en el laboratorio de computadoras.
Ejercicio 1. Taylor para cos(x), tabla y gráfica en Python
Referencia: Burden 7Ed Capítulo 1.1 Ejemplo 3. p11, 10Ed p8. Chapra, 4.1 p80. Taylor Series (Wikipedia)
Continuando con el Ejemplo01, se generaliza el algoritmo para crear una tabla de polinomios de Taylor de diferente grado.
Se complementa el ejercicio con el gráfico de cada polinomio para interpretar los resultados, alrededor de x0 = 0
Sección complementaria, no obligatoria para la parte algorítmica
En el ejercicio presentado requiere resolver con varios grados de polinomio, por lo que se generaliza convirtiendo el procedimiento del algoritmo anterior al formato de función def-return. Cada polinomio intermedio se añade a una tabla de resultados:
# Aproximación Polinomio de Taylor alrededor de x0# f(x) en forma simbólica con sympyimport numpy as np
import sympy as sym
defpolitaylor(fx,x0,n):
k = 0
polinomio = 0
while (k <= n):
derivada = fx.diff(x,k)
derivadax0 = derivada.subs(x,x0)
divisor = np.math.factorial(k)
terminok = (derivadax0/divisor)*(x-x0)**k
polinomio = polinomio + terminok
k = k + 1
return(polinomio)
# PROGRAMA -------------# Capitulo 1 Ejemplo 2, Burden p11, pdf 21# INGRESO
x = sym.Symbol('x')
fx = sym.cos(x)
x0 = 0
n = 10 # Grado polinomio Taylor
a = -5 # intervalo [a,b]
b = 5
muestras = 51
# PROCEDIMIENTO# tabla polinomios
px_tabla = []
for grado inrange(0,n,1):
polinomio = politaylor(fx,x0,grado)
px_tabla.append(polinomio)
# SALIDAprint('grado : polinomio')
for grado inrange(0,n,1):
px = px_tabla[grado]
print(str(grado)+ ' : '+str(px))
# print('polinomio: ')# sym.pprint(px)# print()
Con lo que se obtiene los polinomios para cada grado calculado.
La forma gráfica de cada polinomio se obtiene evaluando cada polinomio para obtener las líneas en el intervalo [a, b] para cada punto del vector xi .
Se utiliza un cierto número de muestrasen cada intervalo [a,b].
El resultado es una matriz, px_lineas, cuya fila representa el gradodel polinomio, y la columna contiene los valores del polinomio de cada grado evaluado en cada punto xi
# GRAFICA - TABLA polinomios ------
xi = np.linspace(a,b,muestras)
# Forma lambda, simplifica evaluación
fxn = sym.utilities.lambdify(x,fx,'numpy')
fi = fxn(xi)
# lineas de cada grado de polinomio
px_lineas = np.zeros(shape=(n,muestras), dtype =float)
for grado inrange(0,n,1):
polinomio = px_tabla[grado]
px = sym.utilities.lambdify(x,polinomio,'numpy')
px_lineas[grado] = px(xi)
los valores se pueden graficar añadiendo las siguientes instrucciones:
# SALIDA - GRAFICAimport matplotlib.pyplot as plt
plt.plot(xi,fi,'r',label=str(fx))
for grado inrange(0,n,2):
etiqueta = 'grado: '+str(grado)
plt.plot(xi, px_lineas[grado],
'-.',label = etiqueta)
ymax = 2*np.max(fi)
plt.xlim([a,b])
plt.ylim([-ymax,ymax])
plt.xlabel('x')
plt.ylabel('y')
plt.title('Aproximación con Polinomios de Taylor')
plt.legend()
plt.show()
La serie de Taylor proporciona un medio simplificar una función f(x) alrededor de punto x0 de referencia mediante un polinomio. Los términos del polinomio p(x) se construyen con el valor de la función y sus derivadas en x0.
Referencia: Burden 7Ed Capítulo 1.1 ejemplo 3 p11, 10Ed ejemplo 3 p8. Chapra, 4.1 p80. Taylor Series (Wikipedia)
Para la siguiente función trigonométrica f(x), alrededor de x0=0, encontrar :
f(x) = \cos (x)
a) el segundo polinomio de Taylor (n=2),
b) el tercer polinomio de Taylor (n=3), para aproximar cos(0.01)
c) con el resultado anterior y su término residuo aproximar
Una forma de obtener el polinomio de Taylor es crear una función que resuelva el polinomio. Por facilidad en el ejercicio, para obtener la expresión de las derivadas, se usan funciones matemáticas expresadas de forma simbólica con Sympy en Python.
El algoritmo usa la forma simbólica de la expresión para crear el polinomio. La variable independiente x se establece como símbolo.
El procedimiento consiste en crear cada término k-ésimo y se añade a la expresión del polinomio. El términok se construye por partes, primero se obtiene la derivada, que luego se evalúa en derivadax0 y se incluye en la expresión del término. Se acumulan los términok y al final se presenta la expresión del polinomio
# Aproximación Polinomio de Taylor alrededor de x0# f(x) en forma simbólica con Sympy# Burden 7Ed Capítulo 1.1 Ejemplo 3.p11,pdf21;9Ed p11.import numpy as np
import sympy as sym
# INGRESO
x = sym.Symbol('x') # variable independiente
fx = sym.cos(x) # f(x) por aproximar
x0 = 0 # x0 de referencia o conocido
grado = 2 # grado>0
n = grado + 1 # Términos de polinomio# PROCEDIMIENTO
k = 0 # contador de términos
polinomio = 0
while (k < n):
derivada = fx.diff(x,k)
derivadax0 = derivada.subs(x,x0)
divisor = np.math.factorial(k)
terminok = (derivadax0/divisor)*(x-x0)**k
polinomio = polinomio + terminok
k = k + 1
# SALIDAprint(polinomio)
Se usa un contador k de términos para el control de la construcción de la expresión final. Un ejemplo de ejecución del algoritmo con n=3:
1 - x**2/2
Se observa que el término 2do es cero. Para una interpretación gráfica del resultado, luego el polinomio se evalúa en el intervalo [a, b] que incluya x0.
3. Ejemplo 2. Polinomio de Taylor y el error de aproximación
Referencia: Burden 7Ed cap 1.1 Ejercicio 8. Burden 10Ed p8
Obtenga el tercer polinomio de Taylor P3(x) para la función f(x), alrededor de x0=0.
f(x) = \sqrt{x+1}
Aproxime el resultado para x=0.5, 0.75, 1.25 y 1.75 usando P3(x) y calcule los errores reales.
3.1 Desarrollo analítico
Las instrucciones requieren calcular los errores reales como la diferencia entre f(x) y el polinomio de Taylor p(x).
Usando los pasos del ejemplo01, se determina el polinomio de Taylor con n=3. Verifique su respuesta con el polinomio mostrado y calcula los valores de la tabla:
Realice las observaciones a los resultados obtenidos.
Al realizar la gráfica con los valores de la tabla, se puede observar que al alejarse x del punto de referencia x0, el error aumenta. El error se marca en amarillo entre las curvas f(x) y el polinomio p(x).
3.2 Desarrollo de Algoritmo como función, instrucciones en Python
Puede reutilizar el algoritmo para el polinomio de Taylor presentado en el Ejemplo01 al convertirlo en una función de programación politaylor(). El procedimiento basico del algoritmo se agrega a una función def-return con el nombre politaylor() que entrega la expresión simbólica del polinomio p(x).
El ejercicio continúa al evaluar p(x) en un nuevo punto xi, para calcular el error_real respecto al valor real de la expresión f(x).
# Aproximación Polinomio de Taylor alrededor de x0# función en forma simbólica con sympyimport numpy as np
import sympy as sym
defpolitaylor(fx,x0,n):
# Calcula n términos del polinomio de Taylor# fx es simbólica, x0 es el punto de referencia.
k = 0
polinomio = 0
while (k <= n):
derivada = fx.diff(x,k)
derivadax0 = derivada.subs(x,x0)
divisor = np.math.factorial(k)
terminok = (derivadax0/divisor)*(x-x0)**k
polinomio = polinomio + terminok
k = k + 1
return(polinomio)
# PROGRAMA -------------# Capitulo 1.1 Ejecicio 8, Burden p15, pdf 25# Calcule el error con polinomio Taylor grado 3# INGRESO
x = sym.Symbol('x') # variable independiente
fx = sym.sqrt(x+1) # f(x) por aproximar
x0 = 0 # x0 de referencia o conocido
xi = 0.5 # donde se evalúa el polinomio para error
n = 3 # Términos de polinomio# PROCEDIMIENTO# Referencia, f(xi) real
fxi = fx.subs(x,xi)
# Aproximado con Taylor
polinomio = politaylor(fx,x0,n)
pxi = polinomio.subs(x,xi)
error_real = fxi - pxi
# SALIDAprint(' Taylor: ', polinomio)
print(' xi: ', xi)
print(' estimado : ', pxi)
print(' real: ', fxi)
print(' error real: ', error_real)
Sympy dispone de la función sym.series(fx,x,x0,n) para generar el polinomio de Taylor. La función tiene parámetros semejantes a los usados en los ejemplos anteriores y los algoritmos. Se muestra un ejemplo del uso de la función como referencia.
>>> import sympy as sym
>>> x = sym.Symbol('x')
>>> fx = sym.cos(x)
>>> polinomio = sym.series(fx,x,x0=0, n=3)
>>> polinomio
1 - x**2/2 + O(x**3)
>>>
El curso de métodos numéricos tiene mayor atención en los pasos o algoritmos que implementan los conceptos. Los ejercicios desarrollan: primero, la parte la analítica/conceptual aplicadas a escribir con papel y lápiz, segundo, busca ejercitar habilidad de convertir los pasos usados en el papel a un algoritmo de computadora. Con ambas partes, se busca ampliar así la capacidad de análisis e interpretación de resultados, errores de aproximación, convergencia, usando gráficas semejantes a la descrita a continuación.
3.3 Gráfica del Error entre f(x) y p(x)
Esta es una sección complementariapara realizar la gráfica mostrada en el ejemplo. Requiere el uso de la librería matplotlib. Para más detalles, puede revisar la sección de Recursos/Resumen Python/Gráficas 2D de línea .
Para evaluar en el intervalo se requiere convertir las expresiones simbólicas a la forma numérica lambda: fxn, pxn
Para la gráfica, se usa el intervalo [a,b] con las muestras necesarias para una buena resolución de imagen. Se obtiene el vector xin
Se evalúa fxn y pxn en el intervalo, obteniendo los valores en los vectores: fxni y pxni.
Se realiza la gráfica entre xin vs fxni y pxni
Para destacar el error de truncamiento, se rellena el espacio en color amarillo entre fxni y pxni, usando plt.fill_between() .
Para resaltar x0, se traza una línea vertical.
El algoritmo del ejercicio se continúa añadiendo las siguientes instrucciones:
# intervalo de gráfica usando xi como referencia
a = x0 # izquierda
b = x0 + 3*xi # derecha
muestras = 51 # para la gráfica# cambia a forma lambda, expresión numérica Numpy
fxn = sym.lambdify(x,fx,'numpy')
pxn = sym.lambdify(x,polinomio,'numpy')
# evaluar en intervalo
xin = np.linspace(a,b,muestras)
fxni = fxn(xin)
pxni = pxn(xin)
# Gráfica
plt.plot(xin,fxni,label='f(x)')
plt.plot(xin,pxni,label='p(x)')
plt.fill_between(xin,pxni,fxni,color='yellow')
plt.axvline(x0,color='green')
plt.title('Polinomio Taylor: f(x) vs p(x)')
plt.legend()
plt.xlabel('xi')
plt.show()
Los valores de la función en los extremos son -1 y 1, existe cambio de signo, y dado que f es contínua, por el teorema del valor intermedio existe un valor de x en el intervalo, tal que se satisface que el valor de la función es cero.
La gráfica de la ecuación muestra el punto o raíz a buscar:
Se pueden dividir en muchas muestras el intervalo x=[a,b] y buscar los puntos xi donde la función f(xi) cambia de signo.
Usando un algoritmo con muestras = 1001 se encuentra que existen dos puntos donde se encuentra la raíz.
raiz entre posiciones i: [ 479. 480.]
entre los valores:
[ xi, fi]
[[ 0.7185 -0.00162876]
[ 0.72 0.00219576]]
Algoritmo en Python
En el intervalo [a,b] se crean nuevos puntos de muestras para realizar la gráfica. Las muestras se usan para buscar un nuevo intervalo entre x[i] y x[i+1] donde ocurre un cambio de signo en f(x[i]).
# Burden Capítulo 1.1 Ejemplo 2 p11, pdf 21# raices del polinomio en [a,b]import numpy as np
import matplotlib.pyplot as plt
funcionx = lambda x: x**5 - 2*(x**3) + 3*(x**2) -1
# INGRESO
a = 0
b = 1.5
muestras = 1001
# PROCEDIMIENTO
xi = np.linspace(a,b,muestras)
fi = funcionx(xi)
# Busca cambios de signo
donde=[] # donde[i,xi,fi]for i inrange(0,muestras-1,1):
antes = fi[i]
despues = fi[i+1]
signo = (np.sign(antes))*(np.sign(despues))
if (signo<0):
donde.append([i,xi[i],antes])
donde.append([i+1,xi[i+1],despues])
donde = np.array(donde)
# SALIDAprint('raiz entre posiciones i: ', donde[:,0])
print('entre los valores: ')
print(' [ xi, fi]')
print(donde[:,1:])
# GRAFICA
plt.plot(xi,fi)
plt.xlabel('x')
plt.ylabel('fx')
plt.axhline(y=0, color='g')
plt.show()
Al observar los resultados, realice sus comentarios y recomendaciones relacionadas con la respuesta obtenida para mejorar la respuesta
Usando Scipy.Optimize
Continuando con el uso de funciones de Scipy se obtiene una de las raíces, empezando la búsqueda desde 0.4.
raiz en : [ 0.71913933]
>>>
para la otra raíz usar un nuevo punto de partida. Compare respuestas con el método anterior.
las instrucciones usadas son:
# Burden Capítulo 1.1 Ejemplo 2 p11, pdf 21# raices del polinomio en [a,b]import numpy as np
import scipy.optimize as opt
fx = lambda x: x**5 - 2*(x**3) + 3*(x**2) -1
# INGRESO
a = 0
b = 1.5
x0 = 0.4
# PROCEDIMIENTO# fx pasa por cero, cerca de x0
donde = opt.fsolve(fx,x0)
# SALIDAprint('raiz en : ', donde)
Demuestre que las siguientes ecuaciones tienen al menos una solución en los intervalos dados
x \cos (x) - 2 x^{2} + 3 x -1 = 0
en el intervalo [0.2, 0.3] y [1.2, 1.3]
2.1 Desarrollo analítico
Del «teorema del valor intermedio«, si hay cambio de signo al evaluar la función en los puntos x=0.2 y x=0.3, debe existir un punto cdonde se cumple la expresión.
Hay cambio de signo de la función en el intervalo, por lo que la ecuación debe pasar por cero, y se cumple la igualdad.
2.2 Desarrollo numérico con Python
Por simplicidad se usa la ventana iterativa. Se evalúa la función en los puntos extremos del intervalo y con los resultados se continúa de forma semejante a la sección de desarrollo analítico.
es decir, por cambio de signo, debe haber un cruce por cero de la función en el intervalo.
2.3 Desarrollo con gráfica
Como existen varios intervalos, [0.2, 0.3] y [1.2, 1.3] se unifican los intervalos entre los extremos x=[0.2, 1.3].
Para la gráfica se crean 100 tramos (pasos o divisiones) en el intervalo que equivalen a 101 muestras en el intervalo
>>> muestras=101
>>> xi = np.linspace(0.2,1.3,muestras)
>>> fi = fx(xi)
>>> xi
array([ 0.2 , 0.211, 0.222, 0.233, 0.244, 0.255, 0.266, 0.277, ... 1.256, 1.267, 1.278, 1.289, 1.3 ])
>>> fi
array([-0.28398668, -0.24972157, -0.21601609, -0.18287411, -0.15029943, ..., -0.13225152])
Una gráfica permite observar mejor la función en el intervalo.
Se necesita llamar a la librería matplotlib.pyplot que se resume como plt.
>>> import matplotlib.pyplot as plt
>>> plt.plot(xi,fi)
[<matplotlib.lines.Line2D object at 0x0000020C67820E80>]
>>> plt.axhline(0,color='g')
<matplotlib.lines.Line2D object at 0x0000020C678204E0>
>>> plt.show()
plt.plot() crea la gráfica con los vectores xi y fi , añadiendo como referencia en este caso una linea horizontal que pasa por cero, usando plt.axhline(). Finalmente se muestra la gráfica con plt.show().
De la gráfica, fácilmente se puede observar que existen dos puntos «c» que cumplen con la igualdad y que se encuentran en los intervalos de evaluación, con lo que se comprueba que existe solución en los intervalos presentados en el problema.
Resumen de instrucciones Python
# Raices en intervalo - Ejemplo02import numpy as np
import matplotlib.pyplot as plt
fx = lambda x: x*np.cos(x) - 2*(x**2) + 3*x -1
# INGRESO
a = 0.2
b = 1.3
muestras = 101
# PROCEDIMIENTO
xi = np.linspace(a,b,muestras)
fi = fx(xi)
# SALIDA - GRAFICA
plt.plot(xi,fi)
plt.axhline(0,color='g')
plt.show()
Tarea: continúe con el ejercicio usando la función de scipy.optimize.fsolve() y compare resultados. Ejemplo: [1. Raíces en intervalo ] [ 2. Raíces en intervalo ]
3. Tarea
Continuar con el ejercicio observando que si el dominio es [-2,2] se tiene que:
gráfica obtenida con:
# Burden Capítulo 1.1 Ejemplo 2 p11, pdf 21# raices del polinomio en [a,b]import numpy as np
import matplotlib.pyplot as plt
funcionx = lambda x: x**5 - 2*(x**3) + 3*(x**2) -1
# INGRESO
a = -2
b = 2
muestras = 1001
# PROCEDIMIENTO
xi = np.linspace(a,b,muestras)
yi = funcionx(xi)
# SALIDA
plt.plot(xi,yi)
plt.axhline(0, color='green')
plt.axvline(0, color='green')
plt.show()
Situación que requiere un poco de trabajo adicional para encontrar el punto buscado…
1.2 Solución numérica
Otra forma es determinar el valor usando un método numérico, cuya precisión dependerá de la cantidad de muestras discreta, o tamaño de paso, que se utilicen para la evaluación.
Una gráfica permite estimar las intersecciones con los ejes y extremos de las funciones.
el máximo se encuentra en: 1.358
con el valor f(x) de: 5.67530054527
El valor máximo de |fx| en magnitud se cumple cuando la derivada es cero en un punto del intervalo.
Algoritmo en Python
Para observar la función, se realiza la gráfica en el rango [0.5, 2].
El algoritmo base corresponde al usado para una gráfica 2D, si no dispones de información previa, consulte el enlace: Gráficas 2D de línea
La función fx se escribe en formato lambda por simplicidad. Si no tiene información previa sobre funciones numéricas en formato lambda revise el enlace: Funciones def-return vs lambda.
La precisión a usar es de mil tramos, o mil uno muestras en el intervalo [a,b], que es (2-0.5)/1000 = 0.0015
Se usa el algoritmo de búsqueda de posición del valor mayor en la función valor absoluto «fxabs».
Las instrucciones usadas en Python son:
# Burden capítulo 1.1-ejemplo 1 p6, pdf16# Determine el maximo entre [a,b] para fximport numpy as np
import matplotlib.pyplot as plt
# INGRESO
fx = lambda x: 5*np.cos(2*x)-2*x*np.sin(2*x)
a = 0.5
b = 2
muestras = 1001
# PROCEDIMIENTO
xi = np.linspace(a,b,muestras)
fi = fx(xi)
fiabs = np.abs(fi)
donde = np.argmax(fiabs)
# SALIDAprint('el máximo se encuentra en: ', xi[donde])
print('con el valor f(x): ', fiabs[donde])
# GRAFICA
plt.plot(xi,fi, label='f(x)')
plt.plot(xi,fiabs, label='|f(x)|')
plt.axhline(y=0, color='g')
plt.xlabel('x')
plt.ylabel('fx')
plt.legend()
plt.title('f(x) y |f(x)|')
plt.show()
1.3 Usando Scipy.Optimize
La librería Scipy dispone de varios algoritmos de optimización que se desarrollarán durante el curso.
valor inicial de x0
La comprensión de cada uno de ellos permite una aplicación efectiva de los algoritmos para obtener el resultado buscado.
Por ejemplo, usando la derivada de la función y un punto de partida x0 donde se supone, intuye o cercano donde se pretende obtener, se busca cuándo su valor es mínimo con la instrucción fsolve() se obtiene:
[ 1.35822987]
>>>
las instrucciones del algoritmo son:
# Burden capítulo 1.1-ejemplo 1 p6, pdf16# Determine el maximo entre [a,b] para fx# Encontrar el máximo cuando f'(x) pasa por ceroimport numpy as np
import scipy.optimize as opt
# INGRESO
fx = lambda x: 5*np.cos(2*x)-2*x*np.sin(2*x)
dfx = lambda x: -12*np.sin(2*x)-4*x*np.cos(2*x)
a = 0.5
b = 2
muestras = 1001
x0 = 1 # punto inicial de búsqueda# PROCEDIMIENTO
dondemax = opt.fsolve(dfx,x0)
# SALIDAprint(dondemax)
Se usa el «teorema de Rolle«, si los extremos del intervalo son iguales, existe un punto intermedio c en el que la derivada es cero, en donde la función tiene un máximo.
Es la magnitud (sin signo) entre el valor «conocido» real X y el valor «estimado» Xk.
E = |X-X_k|
El valor dependerá de la magnitud de X, por ejemplo:
– Al contar monedas de 1 centavo, una persona cuenta Xk = 98 y una máquina contadora de monedas determina que el valor X = 100, el error absoluto es de 2 centavos ó 0.02 dólares.
¿Que pasaría si el conteo fuese con monedas de 1 dólar y se mantienen las mismas cantidades de monedas?
Continuando el tema del ejemplo anterior, se puede mejorar dimensionando proporcionalmente los errores, es decir ponderarlos respecto a la magnitud usada.
e = \frac{|X-X_k|}{X}
Ponderar el error, calculando el error relativo para ambos ejemplos anteriores, se hacen comparables cuando las monedas son de un centavo o un dolar:
Aparece cuando se usa una calculadora o computadora para los cálculos con números reales. La calculadora usa una cantidad finita de dígitos.
Por ejemplo:
el número π tiene un número infinito de dígitos,
si el número resultante de \sqrt{3} se eleva al cuadrado, se debería obtener 3
Sin embargo podemos comprobar que lo enunciado no se cumple al usar el computador, así obtenemos el error de redondeo.
Usando Python se obtiene:
>>> import numpy as np
>>> numeropi=np.pi
>>> numeropi
3.141592653589793
>>> b=np.sqrt(3)
>>> b
1.7320508075688772
>>> b**2
2.9999999999999996
>>>
Resultan al usar una aproximación en lugar de un procedimiento matemático exacto. Es la diferencia entre una respuesta esperada y el valor calculado con una fórmula iterativa.
Ejemplo, al usar un polinomio de Taylor en lugar de la función original f(x).
Para el caso de archivos de audio, disponemos de dos archivos con el mismo contenido.
Escuche como referencia cada uno para realizar sus observaciones:
Luego de escuchar los archivos de sonido, con lo observado respecto a la «calidad» del sonido, comparela con la calidad de radio AM y FM. A partir de sus observaciones describa lo siguiente:
1. Sinónimos de precisión usados en audio de computadora
2.Sinónimos de error usados en audio de computadora
En ésta ocasión, las instrucciones son semejantes a los ejemplos anteriores.
Observe el experimento mostrado, en especial énfasis de lo que pretenden obtener:
Otro ejemplo en un experimento básico. Observe primer minuto (0:00-01:00) del video siguiente. Solo es necesario revisar el primer experimento realizado con la imagen del perro.
Preguntas
Tomando como base los ejercicios anteriores:
1. Escriba su definición de precisión
2. Escriba su definición de error
3. Describa la diferencia entre: precisión y error
4. Para el estudio académico, ¿se enfocaría en la precisión o en el error?.
5. ¿Cómo valora si el error es tolerable o la precisión es buena o suficiente?
«El FORTRAN es un nuevo y emocionante lenguaje, usado por programadores para comunicarse con computadoras. Es emocionante porque es el camino al Futuro.», … , «2400 multiplicaciones por segundo , … , hay que saber programarla.. o ¿quieren quedarse sin empleo?» (en 1960)
Talentos Ocultos (Hidden Figures). 2016. Fox 2000 Pictures.