Software">
UNAM IntroduccionALaProgramacion
UNAM IntroduccionALaProgramacion
UNAM IntroduccionALaProgramacion
1
Con…namiento 2020, Versión 1.0
Índice
1 Introducción 4
2 Lenguajes de Programación 12
2.1 Conceptos Transversales . . . . . . . . . . . . . . . . . . . . . 21
2.2 Algo de Programación . . . . . . . . . . . . . . . . . . . . . . 28
2.3 Introducción a los Paradigmas de Programación . . . . . . . . 40
2.4 Errores de Redondeo y de Aritmética en la Programación . . 49
2.5 Trabajando con Punto Flotante . . . . . . . . . . . . . . . . . 60
2.6 Documentación del Código Fuente . . . . . . . . . . . . . . . . 69
2.6.1 Documentar en C, C++ y Java . . . . . . . . . . . . . 70
2.6.2 Documentar en Python . . . . . . . . . . . . . . . . . . 79
9 Ejemplitos 302
9.1 Sistemas Dinámicos Discretos . . . . . . . . . . . . . . . . . . 305
9.2 Fractales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307
9.3 Derivadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
13 Bibliografía 396
1 Introducción
A lo largo de la historia de las Ciencias de la Computación han ido surgiendo
herramientas, reglas, conceptos y otros elementos que permitieron la creación
de los más variados lenguajes de programación.
Algunos nacieron y al poco tiempo desaparecieron, mientras que otros
hace años ya que se diseñaron y siguen vigentes. Muchos se fueron adaptando
y renovándose para subsistir tanto que sus orígenes son casi irreconocibles
y en cambio otros permanecen …eles a sus principios fundamentales y casi
inalterables, más allá de ciertos cambios super…ciales.
Si algo caracteriza al panorama actual del desarrollo de sistemas de cóm-
puto es su complejidad y heterogeneidad. No existe una sola forma de pensar
y encarar las soluciones, los conceptos que fundamentan los lenguajes no son
uniformes, no es única la manera de programar. Los modelos de datos, estruc-
turas de control, mecanismos de evaluación, sentencias, enlaces, expresiones,
declaraciones y otros tantos elementos que conforman los lenguajes de progra-
mación actuales son muy diferentes entre unos y otros, hasta opuestos, pero
es posible detectar cuáles son los conceptos que marcan diferencias mayores o
menores, muestran puntos de contacto o de in‡exión, establecen criterios de
clasi…caciones, y así, aportan elementos teóricos para sistematizar el análisis
de la programación.
De esta manera, tiene sentido hablar de la existencia de diferentes "para-
digmas" de programación que aportan los fundamentos teóricos y concep-
tuales para desarrollar sistemas de una manera en particular, incluso po-
dríamos decir con una "…losofía" especial, que los caracterizan, identi…can y
a la vez diferencian de los otros paradigmas.
La materia "Programación" brinda, para la formación de estudiantes uni-
versitarios, un conjunto de conceptos fundamentales de la programación que,
relacionados entre sí, con sus diferencias, similitudes e in‡uencias recípro-
cas, conforman paradigmas de programación. El objetivo es dar un marco
teórico conceptual que permita analizar y construir soluciones informáticas,
y la práctica de analizar una herramienta técnica o conceptual, ya sea un
lenguaje de programación u otro producto, a la luz de estos conceptos.
Se vislumbran los principales paradigmas de programación, recuperando
los conceptos principales que los asemejan y distinguen entre sí, el sentido y
utilidad de cada uno y el impacto que generan en la con…guración y uso de los
lenguajes de programación. El conocimiento de la sintaxis y herramientas
propias de cada lenguaje no es el foco, sino un medio para comprender el
Sin embargo, es importante remarcar que también son muchos los puntos
de contacto en la formas de construcción de soluciones y principalmente en
los objetivos que persiguen y en los criterios de lo que se puede denominar
una buena programación:
Paradigma Lógico
Paradigma Funcional
Paradigma de Objetos
ron otras premisas desde las cuales se desarrollan los programas. En conse-
cuencia, se crearon nuevos lenguajes de programación, que en la actualidad
se les puede conceptualizar en el marco de los paradigmas declarativos, in-
cluyendo al paradigma lógico y al paradigma funcional.
Lo que los diferenció de los otros lenguajes de la época, y que constituye
hoy su principal propiedad, es poder desentenderse de los detalles de su imple-
mentación un programa en cuanto al control de ejecución, las asignaciones de
memoria y la secuencia de sentencias imperativas, o sea todo lo que implique
"cómo" se resuelve el problema, y concentrarse en la declaración o descrip-
ción de "qué" es la solución de un problema, creando programas de un nivel
más alto. Por lo tanto, su principal característica es la declaratividad, por
la que sus programas especi…can un conjunto de declaraciones, que pueden
ser proposiciones, condiciones, restricciones, a…rmaciones, o ecuaciones, que
caracterizan al problema y describen su solución. A partir de esta informa-
ción el sistema utiliza mecanismos internos de control, comúnmente llamado
"motores", que evalúan y relacionan adecuadamente dichas especi…caciones,
en la manera de obtener la solución. En general, las variables son usadas en
expresiones, funciones o procedimientos, en los que se uni…can con diferentes
valores mediante el "encaje de patrones" (Pattern Matching) manteniendo la
transparencia referencial. En ellas no se actualizan los estados de información
ni se realizan asignaciones destructivas.
Que se denomine a algunos paradigmas como declarativos, no implica
que no exista declaratividad en lo demás paradigmas, como tampoco que no
haya ningún rasgo procedural o imperativo en estos. Signi…ca que dichos
conceptos son característicos, identi…cadores y que se presentan con mayor
claridad en los respectivos lenguajes. Tampoco quiere decir que sea esa la
única diferencia.
Simplemente es un modelo teórico para relacionar los grupos de paradig-
mas que tienen mayor a…nidad conceptual entre ellos. La noción de declara-
tividad en mayor o menor medida está presente en cualquier paradigma, por
lo que se pueden construir soluciones muy diferentes que la apliquen a su
manera.
a aspectos, etc.
Una buena heurística debe ser simple, con velocidad de búsqueda que
no se incremente exponencialmente, precisa y robusta.
Las especi…caciones del problema deben ser claras y pueden ser de op-
timización de soluciones previas o de satisfacción de nuevos problemas,
y por otro lado, pueden producir una o múltiples soluciones.
2 Lenguajes de Programación
Hay muchas aplicaciones a las herramientas computacionales, pero nos in-
teresan aquellas que permitan resolver problemas concomitantes en Ciencia
e Ingeniería. Muchas de estas aplicaciones caen en lo que comúnmente se
llama cómputo cientí…co. La computación cientí…ca es el campo de estudio
relacionado con la construcción de modelos matemáticos, técnicas numéricas
para resolver problemas cientí…cos y de ingeniería; y su respectiva imple-
mentación computacional.
Este campo es distinto a las ciencias de la computación y el procesamiento
de información, también es diferente a la teoría y experimentación, que son
las formas tradicionales de la ciencia y la ingeniería. El enfoque de la com-
putación cientí…ca es para ganar entendimiento, principalmente a través del
análisis de modelos matemáticos implementados en computadoras.
Los programas de aplicación de la computación cientí…ca a menudo mode-
lan cambios en las condiciones del mundo real, tales como el tiempo atmos-
férico, el ‡ujo de aire alrededor de un avión, el movimiento de las estre-
llas en una galaxia, el comportamiento de un dispositivo explosivo, entre
otros. Estos programas deberían crear una ’malla lógica’en la memoria de
la computadora, donde cada ítem corresponda a un área en el espacio y con-
tenga información acerca del espacio relevante para el modelo. Por ejemplo,
en modelos para el tiempo atmosférico, cada ítem podría ser un kilómetro
cuadrado, con la altitud del suelo, dirección actual del viento, humedad am-
biental, temperatura, presión, etc. El programa debería calcular el siguiente
estado probable basado en el estado actual, simulado en medidas de tiempo,
resolviendo ecuaciones que describen cómo operan los sistemas mediante el
uso de un algoritmo1 , y repetir el proceso para calcular el siguiente estado.
Este código o programa se escribe en un lenguaje de programación que sigue
algún paradigma de programación2 , que posteriormente puede ser ejecutado
por una unidad central de procesamiento — computadora— .
1
Un algoritmo es un conjunto preescrito de instrucciones o reglas bien de…nidas, orde-
nadas y …nitas que permiten llevar a cabo una actividad mediante pasos sucesivos que no
generen dudas a quien deba hacer dicha actividad. Dados un estado inicial y una entrada,
siguiendo los pasos sucesivos se llega a un estado …nal y se obtiene una solución.
2
Este representa un enfoque particular o …losofía para diseñar soluciones e implemen-
tarlas en algún lenguaje de programación.
Facilidad de implementar
Facilidad de entender
Facilidad de modi…car
If: Indica una condición para que se ejecute una parte del programa.
Else if: Siempre va precedido de un "If" e indica una condición para que
se ejecute una parte del programa siempre que no cumpla la condición
del if previo y sí se cumpla con la que el "else if" especi…que.
Hay que decir que a pesar de que existan distintos tipos de bucles, todos
son capaces de realizar exactamente las mismas funciones. El empleo de uno
u otro depende, por lo general, del gusto del programador.
a algún tipo de dato que puede ser tanto simple como compuesto.
Su utilidad consiste en que se pueden procesar en su conjunto como una
unidad o se pueden descomponer en sus partes y tratarlas en forma indepen-
diente. En otras palabras, las estructuras de datos son conjuntos de valores.
e…ciencia.
La evaluación diferida es utilizada en cierto tipo de situaciones que serían
consideradas erróneas o imposibles de resolver con la evaluación ansiosa,
como por ejemplo los bucles o las listas in…nitas.
Ejemplo en Python:
if x % 2 == 0:
x=x*x
else:
x=x*2
Si <condición> entonces
<acción>
else if
<acción>
else
<acción>
if (x < y) {
z = x;
} else if (x > y) {
z = y;
} else {
z = 0;
}
Ejemplo en Python:
if x < y:
z=x
elif13 x > y:
z=y
else:
z=0
13
elif es una contracción de "else if", sirve para enlazar varios "else if", sin tener que
aumentar las tabulaciones en cada nueva comparación.
if (x % 2 == 0 jj x > 0) x = x * x;
else x = x * 2;
if (x % 2 == 0 && x > 0) {
x = x * x;
} else {
x = x * 2;
}
Ejemplo en Python:
if x % 2 == 0 and x > 0:
x=x*x
else:
x=x*2
Ejemplo en Python:
Ejemplo en Python:
do
<acción>
while <condición>
do {
z = z + x;
} while (z < 20);
switch(expresion) {
case constante:
<acción>
break;
case constante:
<acción>
break;
.
.
.
default:
<acción>
}
switch(i) {
case 1:
x=23;
case 2:
x ++;
break;
default:
x=0;
}
#include <stdio.h>
int main(void) {
printf("Hello Worldnn");
return 0;
}
y lo ejecutamos con:
$ ./hola
Ejemplo en C++:
#include <iostream>
int main() {
std::cout << "Hello World!nn";
}
y lo ejecutamos con:
$ ./hola
14
La extensión depende del lenguaje de programación, para el lenguaje C la extensión
es .c, para el lenguaje C++ la extensión es .cpp, para el lenguaje Java la extensión es
.java, para el lenguaje Python la extensión es .py.
Ejemplo en Java:
class hola {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}
$ javac hola.java
y lo ejecutamos con:
$ java hola
Ejemplo en Python 2:
$ python2 hola.py
Ejemplo en Python 3:
$ python3 hola.py
Ejemplo en C y C++:
#include <stdio.h>
// NPB Numero de primos a buscar
#de…ne NPB 1000
int main ()
{
int n, i, np;
int p[NPB];
// Guarda los primeros 2 primos
p[0] = 2;
p[1] = 3;
np = 2;
// Empieza la busqueda de primos a partir del numero 4
n = 4;
// Ciclo para buscar los primeros NPB primos
while (np < NPB)
{
for (i = 0; i < np; i++)
{
if((n % p[i]) == 0) break;
}
if(i == np)
{
p[i] = n;
np++;
}
n++;
}
// Visualiza los primos encontrados
printf("nnVisualiza los primeros %d primosnn", NPB);
for (i = 0; i < NPB; i++)
printf("%dnn", p[i]);
return 0;
}
Ejemplo en Java:
n++;
}
// Visualiza los primos encontrados
System.out.println("Visualiza los primeros " + NPB + "
primos");
for (i = 0; i < NPB; i++) System.out.println(p[i]);
}
}
def cribaEratostenes(N):
p = [] # inicializa el arreglo de primos encontrados
# Guarda los primeros 2 primos
p.append(2)
p.append(3)
np = 2
# Empieza la busqueda de primos a partir del numero 4
n=4
#Ciclo para buscar los primeros N primos
while np < N:
xi = 0
for i in p:15
xi = xi + 1
if (n % i) == 0:
break
if xi == np:
p.append(n)
np = np + 1
n=n+1
# Visualiza los primos encontrados
15
En este código, al usar el for sobre los elementos del arreglo de primos, es necesario
usar un contador para saber si ya se recorrieron todos los primos existentes y así determinar
si es un nuevo primo y agregarlo a la lista.
16
Aquí, se hace el recorrido sobre el arreglo de primos usando la indexación sobre sus
elementos, usando el número de elementos que se tiene mediante el uso del for con un
range.
Los programas son más fáciles de entender, pueden ser leídos de forma
secuencial y no hay necesidad de tener que rastrear saltos de líneas
dentro de los bloques de código para intentar entender la lógica interna.
datos. Los programadores que emplean POO, en cambio, primero de…nen ob-
jetos para luego enviarles mensajes solicitándoles que realicen sus métodos
por sí mismos.
Estado interno: Es una variable que se declara privada, que puede ser
únicamente accedida y alterada por un método del objeto, y que se
utiliza para indicar distintas situaciones posibles para el objeto (o clase
de objetos). No es visible al programador que maneja una instancia de
la clase.
cada una de las cuales debe ser tan independiente como sea posible de
la aplicación en sí y de las partes restantes. Estos módulos se pueden
compilar por separado, pero tienen conexiones con otros módulos. Al
igual que la encapsulación, los lenguajes soportan la modularidad de
diversas formas.
Sin embargo hay otra forma de hacerlo sin necesidad de usar ninguna
estructura de bucle que es mediante recursividad. Esta versión de la función
hace exactamente lo mismo, pero es más corta, más simple y más elegante:
long factorial(int n)
{
long fact;
if (n <= 1) return 1;
return n*factorial(n-1);
}
ax2 + bx + c = 0
Chicharronera 1
Raiz (-0.2679491924311228), evaluacion raiz: -4.4408920985006262e-16
Raiz (-3.7320508075688772), evaluacion raiz: 0.0000000000000000e+00
Chicharronera 2
Raiz (-0.2679491924311227), evaluacion raiz: 0.0000000000000000e+00
Raiz (-3.7320508075688759), evaluacion raiz: -5.3290705182007514e-15
Metodo Newton-Raphson
Valor inicial aproximado de X1 = -1.2679491924311228
Raiz (-0.2679491924311227), evaluacion raiz: 0.0000000000000000e+00
Valor inicial aproximado de X2 = -4.7320508075688759
Raiz (-3.7320508075688772), evaluacion raiz: 0.0000000000000000e+00
#include <stdio.h>
#include <math.h>
// Funcion cuadratica
double f(double x, double a, double b, double c) {
return (x * x * a + x * b + c);
}
// Metodo Newton-Raphson
// x = x - f(x)/f’(x)
double metodoNewtonRapson(double x, int ni, double a, double
b, double c) {
int i;
for (i = 0; i < ni; i++) {
x = x - (f(x, a, b, c) / df(x, a, b));
}
return x;
}
#include <stdio.h>
#include <math.h>
#include<iostream>
using namespace std;
class cuadratica {
private:
// Coe…cientes del polinomio
double A, B, C;
// Funcion cuadratica
double f(double x, double a, double b, double c) {
return (x * x * a + x * b + c);
}
// Metodo Newton-Raphson
// x = x - f(x)/f’(x)
double metodoNewtonRapson(double x, int ni, double a, double
b, double c) {
int i;
for (i = 0; i < ni; i++) {
x = x - (f(x, a, b, c) / df(x, a, b));
}
return x;
}
public:
// Constructor de la clase
cuadratica(double a, double b, double c) {
A = a;
B = b;
C = c;
}
// calculo de raices
void raices() {
// Raices del polinomio
double X1, X2, x;
// Calculo del discriminante
double d = B * B - 4.0 * A * C;
// Raices reales
if (d >= 0.0) {
printf("nnPolinomio (%f) X^2 + (%f )X + (%f) = 0nn",
A, B, C);
printf("nnChicharronera 1");
X1 = (-B + sqrt(d)) / (2.0 * A);
X2 = (-B - sqrt(d)) / (2.0 * A);
evalua(X1, A, B, C);
evalua(X2, A, B, C);
printf("nnnnChicharronera 2");
X1 = (-2.0 * C) / (B + sqrt(d));
X2 = (-2.0 * C) / (B - sqrt(d));;
evalua(X1, A, B, C);
evalua(X2, A, B, C);
// Metodo Newton-Raphson
printf("nnnnMetodo Newton-Raphson");
x = X1 - 1.0;
printf("nnValor inicial aproximado de X1 = %f", x);
x = metodoNewtonRapson(x, 6, A, B, C);
evalua(x, A, B, C);
x = X2 - 1.0;
printf("nnValor inicial aproximado de X2 = %f", x);
x = metodoNewtonRapson(x, 6, A, B, C);
evalua(x, A, B, C);
printf("nn");
} else {
// Raices complejas
printf("Raices Complejas ...");
}
}
};
int main(void)
{
cuadratica cu1 = cuadratica(1.0, 4.0, 1.0);
cu1.raices();
return 0;
}
import java.lang.Math;
public class cuadratica {
// Coe…cientes del polinomio
double A, B, C, d;
// Constructor de la clase
public cuadratica(double a, double b, double c) {
A = a;
B = b;
C = c;
}
// Funcion cuadratica
public double f(double x) {
return (x * x * A + x * B + C);
}
// Metodo Newton-Raphson
// x = x - f(x)/f’(x)
public double metodoNewtonRapson(double x, int ni) {
for (int i = 0; i < ni; i++) {
x = x - (f(x) / df(x));
}
return x;
}
X2 = (-2.0 * C) / (B - Math.sqrt(d));;
evalua(X1);
evalua(X2);
System.out.println("");
// Metodo Newton-Raphson
System.out.println("Newton-Rapson");
X1 = Math.round(X1);
System.out.print("Valor inicial aproximado de X1 = " +
X1);
x = metodoNewtonRapson(X1, 8);
evalua(x);
X2 = Math.round(X2);
System.out.print("Valor inicial aproximado de X2 = " +
X2);
x = metodoNewtonRapson(X2, 8);
evalua(x);
} else {
// Raices complejas
System.out.println("Raices Complejas ...");
}
}
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import math
class Ejemplo:
# Constuctor
def __init__(self, a, b ,c):
self.A = a;
self.B = b;
self.C = c;
# Funcion cuadratica
def f(self, x, a, b, c):
return (x * x * a + x * b + c);
# Derivada de la funcion cuadratica
def df(self, x, a, b):
return (2.0 * x * a + b);
# Evalua el valor X en la funcion cuadratica
def evalua(self, x, a, b, c):
print(’Raiz (%1.16f), evaluacion raiz: %1.16e’% (x, (a * x *
x + b * x + c)))
# Metodo Newton-Raphson
# x = x - f(x)/f’(x)
def metodoNewtonRapson(self, x, ni, a, b, c):
for i in range(ni):
x = x - (self.f(x, a, b, c) / self.df(x, a, b))
return x
# Calculo de raices
def raices(self):
# Calculo del discriminante
d = self.B * self.B - 4.0 * self.A * self.C
# Raices reales
if d >= 0.0:
if __name__ == ’__main__’:
ej = Ejemplo(1.0, 4.0, 1.0)
ej.raices()
double x;
double y;
...
if (x == y) {...}
1:778636e 015
double x = 10;
double y = sqrt(x);
y *= y;
if (x == y)
cout << "La reaiz cuadrada es exactann";
else
cout << x-y << "nn";
Aquí está la salida del código anterior. Para que la salida sea más fácil de
entender, los dígitos después del primer dígito incorrecto se han reemplazado
por puntos.
0.4...........
0.53..........
0.53..........
0.5402........
0.5402........
0.540301......
0.5403022.....
0.540302302...
0.54030235....
0.5403022.....
0.540301......
0.54034.......
0.53..........
0.544.........
0.55..........
0
0
0
0
El verdadero resultado es: 0.54030230586814
Los números de punto ‡otante tienen rangos …nitos Todos saben que
los números de punto ‡otante tienen rangos …nitos, pero esta limitación puede
aparecer de manera inesperada. Por ejemplo, puede encontrar sorprendente
la salida de las siguientes líneas de código
‡oat f = 16777216;
cout << f << " " << f+1 << "nn";
Este código imprime el valor 16777216 dos veces. ¿Que pasó? De acuerdo
con la especi…cación IEEE para aritmética de punto ‡otante, un tipo ‡otante
tiene 32 bits de ancho. Veinticuatro de estos bits están dedicados al signi…-
cado (lo que solía llamarse la mantisa) y el resto al exponente. El número
16777216 es 224 y, por lo tanto, a la variable ‡otante f no le queda precisión
para representar f + 1. Ocurriría un fenómeno similar para 253 si f fuera
del tipo double porque un doble de 64 bits dedica 53 bits al signi…cado. El
siguiente código imprime 0 en lugar de 1.
x = 9007199254740992; // 2^53
cout << ((x+1) - x) << "nn";
También podemos quedarnos sin precisión al agregar números pequeños a
números de tamaño moderado. Por ejemplo, el siguiente código imprime "¡Lo
siento!" porque DBL_EPSILON (de…nido en ‡oat.h) es el número positivo
más pequeño e tal que 1 + e! = 1 cuando se usan tipos dobles.
21
Los resultados anteriores se calcularon con Visual C ++ 2008. Cuando se compiló con
gcc 4.2.3 en Linux, los resultados fueron los mismos, excepto los últimos cuatro números.
Donde VC ++ produjo ceros, gcc produjo números negativos: -0.017 ..., - 0.17 ..., -1.7 ...
y 17 ....
x = 1.0;
y = x + 0.5*DBL_EPSILON;
if (x == y)
cout << "¡Lo siento!nn";
double logFactorial(int n)
{
double sum = 0.0;
for (int i = 2; i <= n; ++i) sum += log((double)i);
return sum;
}
x = DBL_MAX;
cout << 2*x << "nn";
if (x - x == 0)
// hacer algo
y así
200!=(190!10!) = 200 199 198 ::: 191=10!
esto ciertamente funciona, pero está limitado a factoriales.
Una técnica más general es usar logaritmos para evitar el desbordamiento:
tome el logaritmo de la expresión que desea evaluar y luego exponga el re-
sultado. En este ejemplo
double x = 1e-16;
double y = log(1 + x)/x;
¿Qué salió mal? los números de doble precisión tienen una precisión
de aproximadamente 15 decimales, por lo que 1 + x equivale a 1 para la
precisión de la máquina. El registro de 1 es cero, por lo que y se establece
en cero. Pero para valores pequeños de x, log(1 + x) es aproximadamente x,
por lo que log(1 + x)=x es aproximadamente 1. Eso signi…ca que el código
anterior para calcular log(1 + x)=x devuelve un resultado con 100% de error
relativo. Si x no es tan pequeño que 1 + x es igual a 1 en la máquina, aún
podemos tener problemas. Si x es moderadamente pequeño, los bits en x
no se pierden totalmente al calcular 1 + x, pero algunos sí. Cuanto más se
acerca x a 0, más bits se pierden. Podemos usar la siguiente regla: Utilice
aproximaciones analíticas para evitar la pérdida de precisión.
La forma favorita de aproximación de los analistas numéricos es la serie
de potencia. ¡La serie de potencia para
double x = 1000;
double t = exp(x);
double y = t/(1.0 + t);
/*
Este ciclo se realiza 10 veces
*/
for (int i = 0; i < 10; i ++) xp += 10 + i;
"""
Este ciclo se realiza tantas veces como elementos en Array
"""
for i in Array:
xp = xp + i
$ doxygen -g
$ doxygen
$ cd html
$ xpdf index.html
$ cd latex
$ make pdf
$ xpdf refman.pdf
#ifndef __test__
#de…ne __test__
/// Descripcion breve de la clase.
/**
* Descripcion detallada de la clase ...
*
* @author Antonio Carrillo
* @date Winter 2010
* @version 0.0.1
* @bug No errors detected
* @warning No warnings detected
* @todo Exception handling
*/
class test
{
private:
public:
/**
* Descipcion breve.
*
* Descripcion detallada ...
*
* Algo de LaTeX ...
*
* nf[
* jI_2j=nleftj nint_{0}^T npsi(t)
* nleftn{
* u(a,t)-
* nint_{ngamma(t)}^a
* nfrac{dntheta}{k(ntheta,t)}
* nint_{a}^ntheta c(nxi)u_t(nxi,t)n,dnxi
* nrightn} dt
* nrightj
* nf]
*
*
* @param[out] clas Descripcion del parametro de salida
* @param[in] fun Descripcion del parametro de entrada
*/
test(const char *clas, const char *fun)
{
nameClassFunct(clas, fun);
}
/**
* Descripcion breve.
*
* Descripcion detallada
*
* @param nVert Descripcion del parametro
* @param[in] g Descripcion del parametro
* @param[in] me Descripcion del parametro
/**
* Proposito y Metodo:
* Entradas:
* Salidas:
* Entradas TDS:
* Salidas TDS:
* Dependencias:
* Restricciones y advertencias"
*/
/**
* @…le release.notes
* @brief Package TkrRecon
* @verbatim
* Coordinator: Leon Rochester
*
* v4r4p8 09-Mar-2002 LSR Remove GFxxxxx and SiRecObjs,
no longer used
* v4r4p7 07-Mar-2002 TU Mainly, add a combo vertexing to
the TkrRecon sequence
* @endverbatim
*/
#ifndef __ErrorControl__
#de…ne __ErrorControl__
#include <new>
using namespace std;
#include <stdlib.h>
#include "Printf.hpp"
#ifdef USE_HYPRE
#include <mpi.h>
#endif
/// Error Control, this class handles errors for the system
RESSIM
/**
* @author Antonio Carrillo and Gerardo Cisneros
* @date Winter 2010
* @version 0.0.2
* @verbatim
Coordinator: Robert Yates
v0.0.1 Junuary 2011 Antonio Carrillo generates the …rst ver-
sion of the class
v0.0.2 March 2011 Gerardo Cisneros add HYPRE errors con-
trol
Inputs: Name of class and function
Outputs: Exit of program
TDS Inputs: none
TDS Outputs: none
Dependencies: #ifdef USE_HYPRE, MPI package
Restrictions and Caveats: Non exception handling still
@endverbatim
* @bug No errors detected
* @warning No warnings detected
* @todo Exception handling
*/
class ErrorControl {
private:
/// Name of class
const char *nmClass;
/// Name of function generating the error
const char *nmFunction;
public:
/**
* Class Constructor
*/
ErrorControl(void) {
nameClassFunct(" ", " ");
}
/**
* Class Constructor
* @param clas Class name
*/
ErrorControl(const char *clas) {
nameClassFunct(clas, " ");
}
/**
* Class Constructor
* @param clas Class name
* @param fun Name of function generating the error
*/
ErrorControl(const char *clas, const char *fun) {
nameClassFunct(clas, fun);
}
/**
* Name of class and function
* @param clas Class name
* @param func Name of function generating the error
*/
void nameClassFunct(const char * clas, const char *func) {
nameClass(clas);
nameFunct(func);
}
/**
* No memory for this request
* @param var Var name
*/
void memoryError(const char * var) {
Afprintf(stderr, "nnnnNo memory for %s request in %s of class
%snnnn", var, nmFunction, nmClass);
fatalError(1);
}
/**
* No memory for this request
* @param var Var name
* @param i Index number
*/
void memoryError(const char * var, int i) {
Afprintf(stderr, "nnnnNo memory for %s request %d in %s of
class %snnnn", var, i, nmFunction, nmClass);
fatalError(1);
}
/**
* No memory for this request
* @param var Var name
* @param func Name of function generating the error
*/
void memoryError(const char * var, const char *func) {
Afprintf(stderr, "nnnnNo memory for %s request in %s of class
%snnnn", var, func, nmClass);
fatalError(1);
}
/**
* Fatal error.
* @param cod Error code
*/
void fatalError(int cod) {
Afprintf(stderr, "nnFatal ErrornnEnd programnn");
#ifdef USE_HYPRE
MPI_Abort(MPI_COMM_WORLD, cod);
#else
exit(cod);
#endif
}
/**
* Fatal error.
* @param cod Error code
*/
#!/usr/bin/env python
# -*- coding: utf-8 -*-
ax^2 + bx + c = 0.
Utiliza la formula general (tambien conocida
coloquialmente como el "chicharronero").
Parametros:
a –coe…ciente cuadratico (debe ser distinto de 0)
b –coe…ciente lineal
c –termino independiente
Excepciones:
ValueError –Si (a == 0)
"""
if a == 0:
raise ValueError(
’Coe…ciente cuadratico no debe ser 0.’)
from cmath import sqrt
discriminante = b ** 2 - 4 * a * c
x1 = (-b + sqrt(discriminante)) / (2 * a)
x2 = (-b - sqrt(discriminante)) / (2 * a)
return (x1, x2)
>>> promedio.__doc__
’Calcula el promedio de dos numeros.’
>>> formula_cuadratica.__doc__
’Resuelve una ecuación cuadratica.nnnn Devuelve en una
tupla las dos raices que resuelven lann ecuacion
cuadratica:nn nn ax^2 + bx + c = 0.nnnn
>>> help(promedio)
Help on function promedio in module __main__:
promedio(a, b)
Calcula el promedio de dos numeros.
>>> help(formula_cuadratica)
Help on function formula_cuadratica in module __main__:
formula_cuadratica(a, b, c)
Resuelve una ecuacion cuadratica.
Devuelve en una tupla las dos raices que resuelven la
ecuacion cuadratica:
ax^2 + bx + c = 0.
Utiliza la formula general (tambien conocida
coloquialmente como el "chicharronero").
Parametros:
a –coe…ciente cuadratico (debe ser distinto de 0)
b –coe…ciente lineal
c –termino independiente
Excepciones:
ValueError –Si (a == 0)
pydoc -w ejemplos
Ejemplo: evaluar/grado/integrar.
Ciclo de vida de un objeto Todos los objetos tienen una vida, se puede
decir que nacen cuando son instanciados y mueren cuando se elimina de la
memoria. No obstante, existen dos formas de eliminar de memoria a un
objeto dependiendo del lenguaje de programación. Los mecanismos son:
Recolector de Basura (Garbage Collector) y Destructores.
¿Qué es una clase? Podemos de…nir a una clase utilizando dos de…ni-
ciones complementarias: una clase es un molde, a partir del cual se crean
los objetos. Cuando instanciamos un objeto, el ambiente le pregunta a dicha
clase que características y métodos debe tener el objeto. La otra de…nición
es: una clase es un ente que determina el comportamiento y el tipo al que
pertenecen sus instancias.
Clase Persona:
22
El análisis orientado a objetos (Object-oriented Analysis OOA) es el proceso de
analizar un problema, un sistema o una tarea — que alguien quiere convertir en una
aplicación— e identi…car los objetos y las interacciones entre esos objetos. La etapa de
análisis tiene que ver con lo que se necesita hacer. La salida de la etapa de análisis es un
conjunto de requisitos. Si tuviéramos que completar el análisis paso a paso, habríamos
convertido una tarea, en un conjunto de requisitos. En cierto modo, el análisis es un
nombre inapropiado. En su lugar, explora su entorno, manipula formas y ve dónde se
podrían contener. Una mejor interpretación de la frase podría ser la exploración orientada
a objetos. En desarrollo de Software, las etapas iniciales de análisis incluyen entrevistar a
los clientes, estudiando sus procesos, y eliminando posibilidades.
El diseño orientado a objetos (Object-oriented Design OOD) es el proceso de convertir
tales requisitos en una especi…cación de implementación. El diseñador debe nombrar los
objetos, de…nir los comportamientos, y especi…car formalmente qué objetos pueden acti-
var comportamientos especí…cos en otros objetos. La etapa de diseño tiene que ver con
cómo se deben hacer las cosas. La salida de la etapa de diseño es una especi…cación de
implementación. Si fuéramos a completar la etapa de diseño en un solo paso, habríamos
cumplido los requisitos de…nidos durante análisis orientado a objetos en un conjunto de
clases e interfaces que podrían implementarse en (idealmente) cualquier lenguaje de pro-
gramación orientado a objetos.
La programación orientada a objetos (Object-oriented Programming OOP) es el pro-
ceso de conversión del diseño en un programa de trabajo que haga exactamente lo que
el solicitante del mismo originalmente solicitó. ¡Sí claro!, sería encantador si el mundo se
encontrara con este ideal y pudiéramos seguir estas etapas una por una, en perfecto orden,
como todos los antiguos libros de texto nos decían. Como de costumbre, el mundo real
es mucho mas turbio, no importa cuánto intentemos separar estas etapas, siempre encon-
traremos cosas que necesitan más análisis mientras estamos diseñando. Cuando estamos
programando, encontramos características que necesitan aclaración en el diseño.
// Constructor de la clase
public Vector() {
Dim = 0;
}
// Asigna coe…cientes
public Vector(double []coef) {
int i, n = coef.length;
C = new double[n];
Dim = n;
for (i = 0; i < n; i++) C[i] = coef[i];
}
// Retorna los coe…cientes
double coe…ciente(int i) {
if (i >= Dim) {
System.out.print("Error");
return 0;
}
return C[i];
}
// Retorna la dimension del arreglo de coe…cientes
int dimension() {
return Dim;
}
// Visualiza el vector
public void visualiza() {
int i;
System.out.print("(");
for (i = 0; i < Dim; i++) {
System.out.print(C[i]);
if(i < Dim-1) System.out.print(", ");
}
System.out.print(")");
}
// Visualiza el vector
public void visualizaLN() {
visualiza();
System.out.println("");
}
A.visualizaLN();
C.suma(A);
C.visualizaLN();
System.out.println("Suma con dos operandos:");
A.visualizaLN();
B.visualizaLN();
C.suma(A, B);
C.visualizaLN();
}
}
los que se compone son realmente sus partes, es decir, no tienen existencia
independiente.
Clase Profesor:
¿Cómo funciona?
p1.visualiza();
m1.visualiza();
}
}
Reusa código.
LookUp "empieza desde uno más arriba". Es decir, que no busca la imple-
mentación en la clase donde está ejecutando el método, sino en la inmediata
superior (puede que eso desemboque en que siga subiendo niveles). En el 99%
de los casos, sólo deberíamos llamar a super/parent para ejecutar el mismo
método que estamos ejecutando.
Ejemplo de código:
Contratos
Diseño por contratos El diseño por contratos asume que todos los
componentes del cliente que invocan una operación en un componente del
servidor van a encontrar las precondiciones (y postcondiciones) especi…cadas
como obligatorias para esa operación.
Muchas veces podemos tener algunas cosas para validar en nuestro sis-
tema. Esto es:
Pre condiciones
Post condiciones
https://es.wikipedia.org/wiki/SOLID
plantea que donde uso una clase, debería poder usar cualquier subclase de
ella y que siga funcionando todo correctamente.
Para que dos objetos sean polimór…cos, debo explicitarlos (por una interfaz
o por heredar de la misma clase).
Estructural o nominal
Implícito y dinámico
import java.util.*;
public class TestHerencia {
public static void main (String [ ] Args) {
Profesor p1 = new Profesor ("Juan", "Nadrie Garcia",
33, "Prof 22-387-11");
Medico m1 = new Medico ("Roberto", "Gonzalez Gar-
cia", 33, "Cirujano", "328943784");
Persona p = new Persona ("Mauro", "Ruiz Perez", 36);
List<Persona> tlist = new ArrayList<Persona>();
tlist.add(p1);
tlist.add(m2);
tlist.add(p);
for (int i = 0; i < tlist.size(); i++) tlist.get(i).visualiza();
}
}
Hay que ser muy cuidadosos al usar el casteo, porque podría llevar a
"confundir" al compilador y hacer que falle en tiempo de ejecución (perdiendo
el bene…cio que nos da el chequeo estático), por ejemplo si en el objetotlist que
recibe objetos de las clases Medico, Profesor y Persona, al llamar a métodos
no comunes indicados en la clase base Persona nuestro programa lanzará una
excepción.
Desventajas:
Agregación Es cuando una o más clases son parte de otra clase. En este
caso el objeto no es creado dentro del objeto compuesto, es adherido mediante
algún método que lo permita.
Diferencia entre Agregación y Composición
// Suma
abstract void suma(Numero a, Numero b);
// Suma
abstract void suma(Numero a);
// Visualiza sin cambiar de linea
abstract void visualiza();
// Visualiza cambiando de linea
void visualizaLN() {
visualiza();
System.out.println("");
}
}
P = p;
Q = q;
calculaPrimos();
}
// Genera un nuevo miembro de la clase
public Numero nuevo() {
Numero c = new Fraccion();
return c;
}
// Calcula los primeros nPr primos
private void calculaPrimos() {
int n, i, np;
Pr = new long[nPr];
// Guarda los primeros 2 primos
Pr[0] = 2;
Pr[1] = 3;
np = 2;
// Empieza la busqueda de primos a partir de 4
n = 4;
// Ciclo para buscar los primeros NPB primos
while (np < nPr) {
for (i = 0; i < np; i++) {
if((n % Pr[i]) == 0) break;
}
if(i == np) {
Pr[i] = n;
np++;
}
n++;
}
}
// Visualiza los primos encontrados
public void visArregloPrimos() {
System.out.println("Visualiza los primeros " + nPr + "
primos");
for (int i = 0; i < nPr; i++) System.out.println(Pr[i]);
}
// Simpli…ca el numerador y denominador de la fraccion
I = a.parteImaginaria();
}
// Genera un nuevo miembro de la clase
public Numero nuevo() {
Numero c = new Complejos();
return c;
}
// Retorna la parte real del complejo
public double parteReal() {
return R;
}
// Retorna la parte imaginaria del complejo
public double parteImaginaria() {
return I;
}
// Regresa verdadero si el complejo es cero
public boolean esCero() {
if (parteReal() == 0.0 && parteImaginaria() == 0.0)
return true;
return false;
}
// Suma con dos operandos
public void suma(Numero A, Numero B) {
Complejos a = new Complejos( (Complejos) A);
Complejos b = new Complejos( (Complejos) B);
R = a.parteReal() + b.parteReal();
I = a.parteImaginaria() + b.parteImaginaria();
}
// Suma con un operando
public void suma(Numero A) {
Complejos a = new Complejos( (Complejos) A);
R = parteReal() + a.parteReal();
I = parteImaginaria() + a.parteImaginaria();
}
// Visualiza el complejo
public void visualiza() {
System.out.print(R + " + " + I + "i");
}
};
}
// Retorna la parte real del complejo
public Fraccion parteReal() {
return R;
}
// Retorna la parte imaginaria del complejo
public Fraccion parteImaginaria() {
return I;
}
// Regresa verdadero si el complejo es cero
public boolean esCero() {
if (parteReal().numerador() == 0.0 && parteImaginaria().numerador()
== 0.0) return true;
return false;
}
// Suma con dos operandos
public void suma(Numero A, Numero B) {
ComplejoFraccionario a = new ComplejoFraccionario(
(ComplejoFraccionario) A);
ComplejoFraccionario b = new ComplejoFraccionario(
(ComplejoFraccionario) B);
R.suma(a.parteReal(), b.parteReal());
I.suma(a.parteImaginaria(), b.parteImaginaria());
}
// Suma con un operando
public void suma(Numero A) {
ComplejoFraccionario a = new ComplejoFraccionario(
(ComplejoFraccionario) A);
R.suma(parteReal(), a.parteReal());
I.suma(parteImaginaria(), a.parteImaginaria());
}
// Visualiza el complejo
public void visualiza() {
R.visualiza();
System.out.print("+");
I.visualiza();
System.out.print("i");
}
};
Pero, ¿podemos de…nir algún objeto Número o todos van a ser Frac-
cionario/Complejo/ComplejoFraccionario/etc.?
En este caso, la clase Número no debería ser instanciable, solo quiero
utilizarla para que las clases que heredan de esta puedan usar el código
de…nida en ella.
A esto se lo llama una clase abstracta. Al contrario de las abstractas, las
clases que sí son instanciables, se les denomina concretas. Una clase abstracta
de…ne sólo la interfaz o …rma — el nombre, los parámetros del método y lo
que retorna— de algunos de sus métodos. Podemos tener:
Manteniendo el concepto, una clase abstracta puede obligar a que sus sub-
clases implementen cierto método, pero sin de…nir ningún comportamiento
por omisión. A estos métodos, naturalmente, se los denomina métodos abs-
tractos.
Si una clase tiene al menos un método abstracto, entonces debe ser abs-
tracta, porque no tiene sentido que haya un objeto que sea instancia de ella.
A …nes de comprensión de concepto, podría decirse que una interfaz es una
clase abstracta con todos sus métodos abstractos.
xX.visualizaLN();
System.out.println("+");
xY.visualizaLN();
xZ.suma(xX, xY);
System.out.println("=====================");
xZ.visualizaLN();
System.out.println("");
System.out.println("");
}
}
Este concepto se conoce como polimor…smo. Es la capacidad de inter-
cambiar un objeto con otro, abstrayendo al que se conoce desde su imple-
mentación.
clase Polinomio genérico y que soporta los tipos de números que extienden a
la clase Numero desarrollados anteriormente y otros más.
de clases.
Para ello, primero desarrollamos una clase abstracta pura que de…na los
comportamientos que harán la manipulación de cada componente (registro)
de nuestro sistema de Altas, Bajas y Cambios, mediante el siguiente código:
import java.io.Serializable;28
/// Clase Base para manipular registros
public abstract class Registro implements Serializable {
private static …nal long serialVersionUID = 1L;
abstract int visualizaRegistro();
abstract int modi…carRegistro();
abstract int adicionaRegistro();
};
import java.util.Scanner;29
/// Clase para manipular registros telefonicos
public class RegTelefonico extends Registro {
private String Nombre;
private String Direccion;
private String Telefonos;
/// Visualiza el contenido del registro
int visualizaRegistro() {
System.out.println("Nombre: " + Nombre);
System.out.println("Direccion: " + Direccion);
System.out.println("Telefonos: " + Telefonos);
return 0; //Ok
}
/// Adiciona un registro
int adicionaRegistro() {
Scanner teclado = new Scanner(System.in);
28
Para usar ArrayList y que nos permite leer y grabar al conjunto de registros de forma
uni…cada, necesitamos usar java.io.Serializable. E implementar la clase Registro a partir
de la clase Serializable, además de de…nir:
private static …nal long serialVersionUID = 1L;
29
En nuestro ejemplo, usaremos la clase Scanner, para solicitar en consola la captura de
los datos en modo texto.
System.out.print("Nombre: ");
Nombre = teclado.nextLine();
System.out.print("Direccion: ");
Direccion = teclado.nextLine();
System.out.print("Telefonos: ");
Telefonos = teclado.nextLine();
return 0; // Ok
}
/// Modi…ca el contenido del registro
int modi…carRegistro() {
Scanner teclado = new Scanner(System.in);
// Visualiza el nombre y permite su modi…cacion
System.out.println("Nombre: " + Nombre);
System.out.print("Nuevo Nombre: ");
Nombre = teclado.nextLine();
System.out.println("Direccion: " + Direccion);
System.out.print("Nueva Direccion: ");
Direccion = teclado.nextLine();
System.out.println("Telefonos: " + Telefonos);
System.out.print("Nuevos Telefonos: ");
Telefonos = teclado.nextLine();
return 0; // Ok
}
};
import java.util.Scanner;30
/// Clase para manipular registros de Cds
public class RegCDs extends Registro {
private String Titulo;
private String Artista;
private int NumCanciones;
private String Canciones;
/// Visualiza el contenido del registro
public int visualizaRegistro() {
30
En nuestro ejemplo, usaremos la clase Scanner, para solicitar en consola la captura de
los datos en modo texto.
Canciones = teclado.nextLine();
return 0; // Ok
}
};
import java.io.*;31
import java.util.*;32
/// Clase base para manipular Altas-Bajas-Cambios.
public abstract class EstructuraABC {
/// Lista
public ArrayList<Registro> lista;
public EstructuraABC() {
lista = new ArrayList<Registro>();
}
/// Borra todo el contenido de la lista
private void borrarTodo() {
lista.clear();
}
/// Adiciona un registro al …nal de la lista
abstract int adicionar();
/// Visualiza el contenido del registro solicitado
public int visualiza(int pos) {
if (pos >= 0 && pos < lista.size()) {
lista.get(pos).visualizaRegistro();
return 0;
31
Para permitir leer y grabar archivos.
32
Para de…nir ArrayList.
}
return 1;
}
/// Visualiza todo el contenido de la lista
public int visualizaTodos() {
Iterator<Registro> iter = lista.iterator();
while (iter.hasNext()) {
iter.next().visualizaRegistro();
}
return 0;
}
/// Visualiza el registro de la lista solicitado
int borrar(int pos) {
if (pos >= 0 && pos < lista.size()) {
lista.remove(pos);
return 0;
}
return 1;
}
/// Modi…ca el registro de la lista solicitado
int modi…car(int pos) {
if (pos >= 0 && pos < lista.size()) {
lista.get(pos).modi…carRegistro();
return 0;
}
return 1;
}
/// Leer una lista de disco
@SuppressWarnings("unchecked")
int leer(String arch) {
try {
FileInputStream …leIn = new FileInputStream(arch);
ObjectInputStream in = new ObjectInputStream(…leIn);
Object obj = in.readObject();
lista = (ArrayList<Registro>) obj;
in.close();
…leIn.close();
visualizaTodos();
} catch(Exception e){e.printStackTrace();}
return 0;
}
/// Grabar una lista en disco
int grabar(String arch) {
try {
FileOutputStream …leOut = new FileOutputStream(arch);
ObjectOutputStream out = new ObjectOutputStream(…leOut);
out.writeObject(lista);
out.close();
…leOut.close();
} catch(Exception e){}
return 0;
}
/// Regresa el numero de registros en la lista
int regresaNRegs() {
return lista.size();
}
};
import java.util.Scanner;33
public class Test {
public static void limpiar() {
for (int i = 0; i < 20; i++) System.out.println("");
}
public static void visualizaMenu() {
System.out.println("Menu");
System.out.println("");
System.out.println("1) Agregar");
System.out.println("2) Modi…car");
System.out.println("3) Borrar");
System.out.println("4) Visualizar todos");
System.out.println("8) Leer");
System.out.println("9) Grabar");
System.out.println("0) Salir");
}
// Funcion Principal ....
public static void main(String[] args) {
Scanner teclado = new Scanner(System.in);
33
En nuestro ejemplo, usaremos la clase Scanner, para solicitar en consola la captura de
los datos en modo texto.
import java.util.Scanner;34
public class Test {
public static void limpiar() {
for (int i = 0; i < 20; i++) System.out.println("");
}
public static void visualizaMenu() {
System.out.println("Menu");
System.out.println("");
System.out.println("1) Agregar");
System.out.println("2) Modi…car");
System.out.println("3) Borrar");
System.out.println("4) Visualizar todos");
System.out.println("8) Leer");
System.out.println("9) Grabar");
System.out.println("0) Salir");
}
// Funcion Principal ....
public static void main(String[] args) {
Scanner teclado = new Scanner(System.in);
// Manipulacion del directorio telefonico
CatalogoCDs man = new CatalogoCDs();
limpiar();
int op = 1, reg;
do {
System.out.println("Numero de registros: "
+ man.regresaNRegs());
visualizaManu();
System.out.println("");
System.out.println("Opcion: ");
op = teclado.nextInt();
switch(op) {
case 1:
man.adicionar();
34
En nuestro ejemplo, usaremos la clase Scanner, para solicitar en consola la captura de
los datos en modo texto.
break;
case 2:
System.out.println("Registro: ");
reg = teclado.nextInt();
man.modi…car(reg);
break;
case 3:
System.out.println("Registro: ");
reg = teclado.nextInt();
man.borrar(reg);
break;
case 4:
man.visualizaTodos();
break;
case 8:
man.leer("DirTelefonico.dat");
break;
case 9:
man.grabar("DirTelefonico.dat");
break;
}
} while(op != 0);
}
}
import java.util.Scanner;35
public class Test {
public static String[] Archivo = {"DirTelefonico.dat", "Cat-
alogoCDs.dat"};
public static void limpiar() {
for (int i = 0; i < 20; i++) System.out.println("");
}
35
En nuestro ejemplo, usaremos la clase Scanner, para solicitar en consola la captura de
los datos en modo texto.
System.out.println("Registro: ");
reg = teclado.nextInt();
man[act].borrar(reg);
break;
case 4:
man[act].visualizaTodos();
break;
case 8:
man[act].leer(Archivo[act]);
break;
case 9:
man[act].grabar(Archivo[act]);
break;
case 10:
if (act == 0) act = 1;
else act = 0;
break;
default:
System.out.println("Opcion no reconocidad");
}
} while(op != 0);
}
}
De esta forma, tenemos una clase genérica de Altas, Bajas y Cambios que
nos permite manipular uno o múltiples ejemplos — Directorio Telefónico y el
Catalogo de CDs— para hacer Altas, Bajas y Cambios en un solo sistema
computacional que es ‡exible, extendible y de fácil mantenimiento, además
de permitir el manejo simultáneo de múltiples sistemas de ABC.
... ***
... ***
... ***
... ***
... ***
... ***
... ***
... ***
... ***
... ***
De esta forma, tenemos una clase genérica de Altas, Bajas y Cambios que
nos permite manipular uno o múltiples ejemplos — Directorio Telefónico y el
Catalogo de CDs— para hacer Altas, Bajas y Cambios en un solo sistema
computacional que es ‡exible, extendible y de fácil mantenimiento, además
de permitir el manejo simultáneo de múltiples sistemas de ABC.
3.6 Excepciones
¿Cuántas veces al trabajar con un programa de cómputo, este nos manda
algún mensaje de error poco descriptivo?, esto probablemente se deba a un
bajo nivel de detalle en el manejo de excepciones dentro de nuestro programa.
El manejo de excepciones consiste en controlar los errores que surjan dentro
de nuestro programa para poder tratarlos debidamente.
Tratarlos debidamente implica:
excepción" y tomar las medidas que estime oportunas. Tras capturar la ex-
cepción, el control no vuelve al método en el que se produjo la excepción, sino
que la ejecución del programa continúa en el punto donde se haya capturado
la excepción.
Consecuencia:
Error Subclase de Throwable que indica problemas graves que una apli-
cación no debería intentar solucionar (documentación de Java), ejemplos:
// Bloque 1
try {
// Bloque 2
} catch (Exception error) {
// Bloque 3
}
// Bloque 4
Otro ejemplo:
// Bloque 1
try {
// Bloque 2
} catch (ArithmeticException ae) {
// Bloque 3
} catch (NullPointerException ne) {
// Bloque 4
}
// Bloque 5
Un ejemplo más:
// Bloque1
try {
// Bloque 2
} catch (ArithmeticException ae) {
// Bloque 3
} catch (Exception error) {
// Bloque 4
}
// Bloque 5
// Bloque1
try {
// Bloque 2
} catch (Exception error) {
// Bloque 3
} catch (ArithmeticException ae) {
// Bloque 4
}
// Bloque 5
// Bloque1
try {
// Bloque 2
} catch (ArithmeticException ae) {
// Bloque 3
} …nally {
// Bloque 4
}
// Bloque 5
public DivideByZeroException
extends ArithmeticException {
public DivideByZeroException(String Message) {
super(message);
}
}
Una excepción de este tipo puede entonces lanzarse como cualquier otra
excepción:
Multiplataforma
Reconocimiento de Sintaxis
Depurador
Múltiples idiomas
Componentes
Editor de texto
Compilador.
Intérprete
Herramientas de automatización
Depurador
Algunos de los más usados son: Eclipse, Aptana, NetBeans, Sublime Text,
Geany, Visual Studio, Brackets, Monodevelop, Komodo, Anjuta, CodeLite,
Code::Blocks, PyDev, Eric, PyCharm, PTK, Spyder, Blue…sh, Glade, Kde-
velop, Emacs, QtCreator, Android SDK, WxFormBuilder, etc.
4.1 Java
Java (véase [7]) es un lenguaje de programación de propósito general, con-
currente, orientado a objetos, que fue diseñado especí…camente para tener
tan pocas dependencias de implementación como fuera posible. Su inten-
ción es permitir que los desarrolladores de aplicaciones «escriban el pro-
grama una vez y lo ejecuten en cualquier dispositivo (Write Once, Run Any-
where» o WORA)» , lo que quiere decir que el código que es ejecutado en
una plataforma no tiene que ser recompilado para ejecutarse en otra.
El lenguaje de programación Java fue originalmente desarrollado por
James Gosling, de Sun Microsystems (constituida en 1982 y posteriormente
adquirida el 27 de enero de 2010 por la compañía Oracle), y publicado en 1995
como un componente fundamental de la plataforma Java de Sun Microsys-
tems. Su sintaxis deriva en gran medida de C y C++, pero tiene menos
utilidades de bajo nivel que cualquiera de ellos. Las aplicaciones de Java
son compiladas a bytecode (clase Java), que puede ejecutarse en cualquier
máquina virtual Java (JVM) sin importar la arquitectura de la computadora
subyacente.
empleando diversas técnicas, aunque sigue siendo mucho más lentos que otros
lenguajes.
La primera de estas técnicas es simplemente compilar directamente en
código nativo como hacen los compiladores tradicionales, eliminando la etapa
del bytecode. Esto da lugar a un gran rendimiento en la ejecución, pero tapa
el camino a la portabilidad. Otra técnica, conocida como «compilación al
vuelo JIT (Just In Time)» , convierte el bytecode a código nativo cuando se
ejecuta la aplicación. Otras máquinas virtuales más so…sticadas usan una
"recompilación dinámica" en la que la VM es capaz de analizar el compor-
tamiento del programa en ejecución y recompila y optimiza las partes críticas.
La recompilación dinámica puede lograr mayor grado de optimización que la
compilación tradicional (o estatica), ya que puede basar su trabajo en el
conocimiento que de primera mano tiene sobre el entorno de ejecución y el
conjunto de clases cargadas en memoria. La compilación JIT y la recompi-
lación dinámica permiten a los programas Java aprovechar la velocidad de
ejecución del código nativo sin por ello perder la ventaja de la portabilidad
en ambos.
La portabilidad es técnicamente difícil de lograr, y el éxito de Java en ese
campo ha sido dispar. Aunque es de hecho posible escribir programas para
la plataforma Java que actúen de forma correcta en múltiples plataformas
de distinta arquitectura, el gran número de estas con pequeños errores o
inconsistencias llevan a que a veces se parodie el eslogan de Sun, "Write
once, run anywhere" como "Write once, debug everywhere" (o "Escríbelo
una vez, ejecútalo en cualquier parte" por "Escríbelo una vez, depúralo en
todas partes").
El concepto de independencia de la plataforma de Java cuenta, sin em-
bargo, con un gran éxito en las aplicaciones en el entorno del servidor, como
los Servicios Web, los Servlets, los Java Beans, así como en sistemas empo-
trados basados en OSGi, usando entornos Java empotrados.
# update-java-alternatives -s java-1.14.0-openjdk-amd64
$ java –version
https://netbeans.apache.org/download/index.html
https://www.eclipse.org/downloads/
http://brackets.io/
https://www.jetbrains.com/idea/download/#section=Linux
https://www.oracle.com/tools/downloads/Jdeveloper-12c-downloads.html
http://www.drjava.org/
https://www.jgrasp.org/
https://www.bluej.org/
http://www.jcreator.com/index.htm
https://codenvy.com/
https://atom.io/
https://www.sublimetext.com/
$ nano MiApp.java
$ javac -d . MiApp.java
$ ls
$ jar cvf MiApp.jar MiApp.class
$ ls
$ nano MANIFEST.MF
Main-Class: MiApp
$ man java
$ man javac
$ man jar
Lenguaje Java
4.2 C y C++
C (véase [9]) es un lenguaje de programación originalmente desarrollado por
Dennis Ritchie entre 1969 y 1972 en los Laboratorios Bell, como evolución
del lenguaje anterior B, a su vez basado en BCPL. Es un lenguaje orientado
a la implementación de Sistemas operativos, concretamente Unix, Linux y el
Kernel de Linux. C es apreciado por la e…ciencia del código que produce y
es el lenguaje de programación más popular para crear Software de sistemas,
aunque también se utiliza para crear aplicaciones.
Se trata de un lenguaje de tipos de datos estaticos, débilmente tipi…cado,
de medio nivel, ya que dispone de las estructuras típicas de los lenguajes de
alto nivel pero, a su vez, dispone de construcciones del lenguaje que permiten
un control a muy bajo nivel. Los compiladores suelen ofrecer extensiones
al lenguaje que posibilitan mezclar código en ensamblador con código C o
acceder directamente a memoria o dispositivos periféricos.
Filosofía Uno de los objetivos de diseño del lenguaje C es que sólo sean
necesarias unas pocas instrucciones en lenguaje máquina para traducir cada
elemento del lenguaje, sin que haga falta un soporte intenso en tiempo de
ejecución. Es muy posible escribir C a bajo nivel de abstracción; de hecho,
C se usó como intermediario entre diferentes lenguajes.
En parte, a causa de ser relativamente de bajo nivel y tener un modesto
conjunto de características, se pueden desarrollar compiladores de C fácil-
mente. En consecuencia, el lenguaje C esta disponible en un amplio abanico
de plataformas (más que cualquier otro lenguaje). Además, a pesar de su
naturaleza de bajo nivel, el lenguaje se desarrolló para incentivar la progra-
mación independiente de la máquina. Un programa escrito cumpliendo los
estandares e intentando que sea portátil puede compilarse en muchos com-
putadores.
C se desarrolló originalmente (conjuntamente con el sistema operativo
Unix, con el que ha estado asociado mucho tiempo) por programadores para
Lenguajes C y C++
4.3 Fortran
Fortran (véase [?]) contracción del inglés The IBM Mathematical Formula
Translating System, es un lenguaje de programación de alto nivel de propósito
general, procedimental e imperativo, que está especialmente adaptado al cál-
culo numérico y a la computación cientí…ca. Desarrollado originalmente por
IBM en 1957 para el equipo IBM 704, y usado para aplicaciones cientí…cas y
de ingeniería, el Fortran vino a dominar esta área de la programación desde
el principio y ha estado en uso continuo por más de medio siglo en áreas de
cómputo intensivo tales como la predicción numérica del tiempo, análisis de
elementos …nitos, dinámica de ‡uidos computacional, física computacional y
química computacional. Es uno de los lenguajes más populares en el área de
la computación de alto rendimiento y es el lenguaje usado para programas
que evalúan el desempeño (benchmark) y el ranking de los supercomputa-
dores más rápidos del mundo.
El Fortran abarca un linaje de versiones, cada una de las cuales evolu-
cionó para añadir extensiones al lenguaje mientras que usualmente retenía
compatibilidad con las versiones previas. Versiones sucesivas han añadido
soporte para procesamiento de datos basados en caracteres (Fortran 77),
programación de arreglos, programación modular y programación orientada
a objetos (Fortran 90/95), y programación genérica (Fortran 2003).
Características
Variables y constantes
Fortran no es sensible a mayúsculas y minúsculas. Los nombre de
variables tienen de 6 a 31 caracteres máximo y deben comenzar por
una letra. Los blancos son signi…cativos.
Declaración explicita de variables.
Enteras (I-N), el resto reales. (se modi…ca con IMPLICIT).
Punteros: en los primeros FORTRAN no hay punteros y todas las vari-
ables se almacenan en memoria estática. En FORTRAN 90 se declaran
INTEGER, POINTER::P.
Para memoria dinámica ALLOCATE y DEALLOCATE
Tipos de datos
Arrays, pueden tener hasta 7 dimensiones y se guardan por colummnas.
REAL M(20),N(-5:5)
DIMENSION I(20,20) (tipo por nomenclatura implícita)
Cadenas de caracteres, el primer carácter es el 1, el operador // permite
concatenar cadenas.
CHARACTER S*10, T*25
Almacenamiento de datos. Se usa COMMON para datos compartidos
y EQUIVALENCE cuando almacenamos una variable con dos posibles
tipos en la misma posición de memoria (como union en C). Se usa
DATA para inicializar datos estáticos.
DATA X/1.0/,Y/3.1416/,K/20/
Tipos de…nidos por el usuario, con TYPE <nombre>... END TYPE
<nombre>
Entrada y salida
Tipos de archivos:
Secuenciales
De acceso directo
Subprogramas
Gestión de almacenamiento.
4.4 Python
Python (véase [8]) es un lenguaje de programación interpretado cuya …losofía
hace hincapié en una sintaxis que favorezca un código legible. Se trata de un
lenguaje de programación multiparadigma, ya que soporta orientación a ob-
jetos, programación imperativa y, en menor medida, programación funcional.
Es un lenguaje interpretado, usa tipado dinámico y es multiplataforma.
Es administrado por la Python Software Foundation. Posee una licencia
de código abierto, denominada Python Software Foundation License, que es
compatible con la Licencia pública general de GNU a partir de la versión
2.1.1, e incompatible en ciertas versiones anteriores (véase apéndice 10.1).
Python fue creado a …nales de los ochenta por Guido van Rossum en
el Centro para las Matemáticas y la Informática (CWI, Centrum Wiskunde
& Informatica), en los Países Bajos, como un sucesor del lenguaje de pro-
gramación ABC, capaz de manejar excepciones e interactuar con el sistema
operativo Amoeba. Van Rossum es el principal autor de Python, y su con-
tinuo rol central en decidir la dirección de Python es reconocido, re…riéndose
a él como Benevolente Dictador Vitalicio (en inglés: Benevolent Dictator for
Life, BDFL).
Elementos del lenguaje Python fue diseñado para ser leído con facilidad.
Una de sus características es el uso de palabras donde otros lenguajes uti-
lizarían símbolos. Por ejemplo, los operadores lógicos: !, jj y &&, en Python
se escriben; not, or y and, respectivamente. Curiosamente el lenguaje Pascal
es junto con COBOL uno de los lenguajes con muy clara sintaxis y ambos
son de la década de los 70. La idea del código claro y legible no es algo nuevo.
El contenido de los bloques de código (bucles, funciones, clases, etc.)
es delimitado mediante espacios o tabuladores, conocidos como indentación,
antes de cada línea de órdenes pertenecientes al bloque. Python se diferen-
cia así de otros lenguajes de programación que mantienen como costumbre
declarar los bloques mediante un conjunto de caracteres, normalmente entre
llaves {}. Se pueden utilizar tanto espacios como tabuladores para indentar
el código, pero se recomienda no mezclarlos.
Debido al signi…cado sintáctico de la indentación, cada instrucción debe
estar contenida en una sola línea. No obstante, si por legibilidad se quiere
dividir la instrucción en varias líneas, añadiendo una barra invertida: n al
…nal de una línea, se indica que la instrucción continúa en la siguiente.
…cas basadas en la biblioteca Tk. Otro ejemplo es el módulo: os, que provee
acceso a muchas funciones del sistema operativo. Los módulos se agregan a
los códigos escribiendo la palabra reservada import seguida del nombre del
módulo que queramos usar.
Python tiene una gran biblioteca estandar, usada para una diversidad de
tareas. Esto viene de la …losofía "pilas incluidas" ("batteries included") en
referencia a los módulos de Python37 . Los módulos de la biblioteca estandar
pueden mejorarse por módulos personalizados escritos tanto en C como en
Python. Debido a la gran variedad de herramientas incluidas en la biblioteca
estandar, combinada con la habilidad de usar lenguajes de bajo nivel como C
y C++, los cuales son capaces de interactuar con otras bibliotecas, Python es
un lenguaje que combina su clara sintaxis con el inmenso poder de lenguajes
menos elegantes.
Hug tiene como objetivo hacer que el desarrollar APIs impulsadas por
Python sea lo más simple posible, pero no más simple. Como resultado,
simpli…ca drásticamente el desarrollo de la API de Python.
https://www.jetbrains.com/pycharm/
http://www.pydev.org/
https://wingware.com/
Por otro lado existe Anaconda, una Suite de código abierto que abarca
una serie de aplicaciones, librerías y conceptos diseñados para el desarrollo
de la Ciencia de datos con Python. En líneas generales Anaconda Distribu-
tion es una distribucción de Python que funciona como un gestor de entorno,
También esta SageMath, una Suite de código abierto bajo la licencia GPL
de Software matemático como: NumPy, SciPy, matplotlib, Sympy, Maxi-
ma, GAP, FLINT, R, entre otros. Además combina acceso a una poderosa
combinación del lenguaje basada en Python o directamente vía interfaces o
Wrappers. La misión del proyecto es crear una alternativa de Software libre
a Magma, Maple, Mathematica y Matlab.
Para más información ver: http://www.sagemath.org/.
y para instalar alguna aplicación para todos los usuarios, por ejemplo
ratarmount, usamos:
y para instalar alguna aplicación para todos los usuarios, por ejemplo
ratarmount, usamos:
Sin pérdida de generalidad (usando pip2 o pip3), podemos ver los detalles
de algún paquete, usando:
Lenguaje Python
Editores de Terminal
Diakonos
Jet
Joe
LE
Mined
Nano
Pico
Setedit
Vim
Fte
Gedit
SciTE
JEdit
NEdit
MEdit
KScope
Editra
Kate
KWrite
Leafpad
Mousepad
Anjunta
TEA
Pluma
GVim
Emacs
Atom
Blue…sh
BlueGri¤on
Brackets
Geany
Glade
KompoZer
Light Table
Notepadqq
Scribes
Sublime Text
Aptana
Arduino IDE
Android Studio
CodeLite
Code::Blocks
Eclipse
Gambas
JetBrains Suite
NetBeans
Ninja-IDE
Python IDLE
PyDev
Postman
Qt Creator
Simply Fortran
Spyder
PyCharm
Jupyter
Eric
Android SDK
Java JDK
Meld
Di¤use
DirDi¤
kompare
Numdi¤
colordi¤
wdi¤
xxdi¤
tkdi¤
Ndi¤
Otras Herramientas
Alleyoop
C2HTML
Java2HTML
Code2HTML
c2html
AutoDia
txt2html
html2text
Git https://git-scm.com/
Mercurial https://www.mercurial-scm.org/
Subversion https://subversion.apache.org/
Perforce
Bazaar
CVS
LibreSource
Monotone
SmartGit
GitKraken
Git Cola
Doxygen http://www.doxygen.org/
JavaDoc
UML https://www.uml.org/
Depuradores de programas
ddd https://www.gnu.org/Software/ddd/
gdb https://www.gnu.org/Software/gdb/
kdbg http://www.kdbg.org/
Valgrind http://valgrind.org/
DUMA http://duma.sourceforge.net/
gprof https://sourceware.org/binutils/docs/gprof/
Callgrind http://valgrind.org/docs/manual/cl-manual.html
kCachegrind http://kCachegrind.sourceforge.net/html/Home.html
time https://www.cyberciti.biz/faq/unix-Linux-time-command-examples-
usage-syntax/
En este apartado, solo tocaremos las más usadas, pero abunda la docu-
mentación de estas y otras importantes herramientas en línea de comandos
(véase ??). Iniciaremos por las de compilar40 y depurar41 programas compi-
lables en C, C++, Fortran, entre otros.
$ …le -i Car.java
$ …le -i input.…le
$ cat input.…le
$ iconv -f ISO-8859-1 -t UTF-8//TRANSLIT input.…le -o
out.…le
$ cat out.…le
$ …le -i out.…le
o mediante:
meld nos muestra grá…camente las diferencias entre dos archivos o tam-
bién, entre todos los archivos de dos directorios utilizando distintos colores,
y nos permite editar estos archivos desde el propio programa, actualizando
dinámicamente las diferencias. El programa incluye …ltros y distintas ayudas
para hacer la edición más sencilla, como ‡echas al lado de los cambios para
aplicar cambio en cualquiera de los archivos con un simple clic. Este pro-
grama se puede utilizar como un sencillo cliente de control de cambios para
Git, CVS, Subversion, etc.
kdi¤3 nos muestra grá…camente las diferencias entre tres archivos uti-
lizando distintos colores, y nos permite editar estos archivos desde el propio
programa, actualizando dinámicamente las diferencias. El programa incluye
…ltros y distintas ayudas para hacer la edición más sencilla, como ‡echas al
lado de los cambios para aplicar cambio en cualquiera de los archivos con un
simple clic.
4.5.4 Astyle
Para dar uniformidad a la codi…cación de los programas fuente, se puede usar
un formateador automático de código, Astyle soporta una gran variedad de
http://astyle.sourceforge.net/astyle.html
https://en.wikipedia.org/wiki/Programming_style
https://en.wikipedia.org/wiki/Indent_style
$ ./ejemp
o de forma alternativa:
Por otro lado, también podemos hacer una revisión estática del código,
por ejemplo en C++ usamos:
$ time ejecutable
$ time ls
real 0m0.004s
user 0m0.001s
sys 0m0.004s
Pero podemos instalar una versión optimizada de este comando que pro-
porciona información adicional, para ello instalar:
y su ejecución mediante:
45
El tiempo total de ejecución de un programa (tiempo real) es la suma del tiempo de
ejecución del programa del usuario (tiempo de usuario) más el tiempo de ejecución del
sistema necesario para soportar la ejecución (tiempo de sistema).
$ /usr/bin/time ejecutable
por ejemplo para el comando ls, entrega una salida del tipo:
$ /usr/bin/time -v ls
Command being timed: "ls"
User time (seconds): 0.00
System time (seconds): 0.00
Percent of CPU this job got: 66%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.00
Average shared text size (kBytes): 0
Average unshared data size (kBytes): 0
Average stack size (kBytes): 0
Average total size (kBytes): 0
Maximum resident set size (kBytes): 2360
Average resident set size (kBytes): 0
Major (requiring I/O) page faults: 0
Minor (reclaiming a frame) page faults: 110
Voluntary context switches: 1
Involuntary context switches: 1
Swaps: 0
File system inputs: 0
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (Bytes): 4096
Exit status: 0
$ ./a.out
LeelaChessZero:
C-Ray v1.1:
Flat pro…le:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls s/call s/call name
23.25 0.60 0.60 40656734 0.00 0.00 re to rn a (int, int)
14.85 0.98 0.38 27627674 0.00 0.00 re to a N u m C o lu (int, int)
12.89 1.31 0.33 91126931 0.00 0.00 Ve c to r::re to rn a (int)
10.94 1.59 0.28 31 0.01 0.03 R e sJ a c o b i::re su e lve ()
...
que permite conocer en que parte del código se consume más tiempo de
ejecución.
GPROF
versión actual del CPU o haber intentado tener acceso a memoria protegida
o no disponible.
Típicamente, los depuradores también ofrecen funciones más so…sticadas
tales como correr un programa paso a paso (un paso o animación del pro-
grama), parar el programa (Breaking), es decir, pausar el programa para ex-
aminar el estado actual en cierto evento o instrucción especi…cada por medio
de un Breakpoint, y el seguimiento de valores de algunas variables. Algunos
depuradores tienen la capacidad de modi…car el estado del programa mientras
que está corriendo, en vez de simplemente observarlo. También es posible
continuar la ejecución en una posición diferente en el programa pasando un
estrellamiento o error lógico.
La importancia de un buen depurador no puede ser exagerada. De he-
cho, la existencia y la calidad de tal herramienta para un lenguaje y una
plataforma dadas a menudo puede ser el factor de decisión en su uso, incluso
si otro lenguaje/plataforma es más adecuado para la tarea.
Para hacer depuración del código mediante el depurador grá…co ddd usar:
Puede usarse también los depuradores xxgdb, gdb, kdbg cada uno tiene
sus pros y contras, depende del usuario cual es el más adecuado para usar.
Fugas de memoria.
Otros.
VALGRIND
http://valgrind.org/
http://alleyoop.sourceforge.net/usage.html
http://kCachegrind.sourceforge.net/html/Home.html
y ejecutar mediante:
$ python modulo.pyc
$ python modulo.pyo
Como puede ver, hay una gran diferencia entre Python 2 y 3 (cuanto
más Pystones por segundo, mejor). En los siguientes desgloses, todos los
compiladores de Python se compararon con Python 3.
48
El rendimiento rápido no es la única razón para compilar; Posiblemente la mayor
desventaja de los lenguajes de Scripting como Python es que se proporciona de manera
implícita su código fuente a los usuarios …nales.
49
Si está interesado en los compiladores de Python en general, tenga en cuenta que hay
mucho debate y controversia sobre los "mejores" compiladores y la rapidez general del
lenguaje.
$ nuitka pystone.py
$ nuitka pystone.py –clang
$ nuitka pystone.py –lto
$ ./pystone.exe 500000
PyPy Guido van Rossum dijo una vez: "Si quieres que tu código se
ejecute más rápido, probablemente debas usar PyPy". Para instalarlo en
Debian usar:
$ pypy pystone.py
Después de todo eso, Cython solo dio 228,527 pystones / sec. Sin embargo,
Cython necesita que hagas un poco de trabajo especi…cando los tipos de
variables. Python es un lenguaje dinámico, por lo que no se especi…can los
tipos; Cython utiliza la compilación estática y el uso de variables de tipo C
le permite producir un código mucho mejor optimizado. (La documentación
es bastante extensa y requiere lectura).
4.5.8 Git
Git es un programa de control de versiones que sirve para la gestión de los
diversos cambios que se realizan sobre los elementos de algún proyecto de
Software y sus respectivos programas fuente o con…guración del mismo. Fue
diseñado por Linus Torvalds y es usado para controlar los cambios de diversos
proyectos como los fuentes del Kernel de Linux (véase ??) que tiene decenas
de millones de líneas de código (en la versión 4.12 cuenta con 24,170,860
líneas de código repartidos en 59,806 archivos) y es trabajado por miles de
programadores alrededor del mundo.
# apt install git git-all gitk gitg git-cola git-gui qgit tig lighttpd
vim-fugitive
# apt install mercurial
# apt install subversion rapidsvn
# apt install cvs
$ git init
Ahora para agregar los archivos (todos los de este directorio), usar:
$ git add .
$ git status
$ gitk
$ mkdir example.git
$ cd example.git
Es buena opción limitar el acceso a la cuenta via ssh, por ello es mejor
cambiar en /etc/passwd, la línea del usuario predeterminada:
tlahuiz:x:1005:1005:Tlahuizcalpan„,:/home/tlahuiz:/bin/bash
a esta otra:
tlahuiz:x:1005:1005:Tlahuizcalpan„,:/home/tlahuiz:/usr/bin/git-
Shell
$ mkdir tmp
$ cd tmp
$ git init
$ git add .
Para usar el repositorio en cualquier otra máquina hay que bajar el repo-
sitorio por primera vez del servidor:
$ git pull
$ git status
o en un solo paso:
$ git branch
$ branch –no-merged
$ git log
$ git pull
$ git gc
https://git-scm.com/book/es/v1
http://git-scm.com/documentation
https://coderwall.com/p/kucyaw/protect-secret-data-in-git-repo
http://www.iexplain.org/using-git-with-google-drive-a-tutorial/
https://techstreams.github.io/2016/09/07/google-drive-as-simple-git-Host/
Git
Git-crypt El paquete git-crypt es una solución que usa GPG por debajo
de Git que permite encriptación y desencriptación transparente de archivos
en un repositorio git.
Los archivos que se requieran proteger serán encriptados al hacer commit
y desencriptados al hacer checkout y permite compartir libremente un repo-
sitorio que contenga contenido tanto público como privado. De esta forma,
permite trabajar de manera transparente con el contenido desencriptado, de
forma que desarrolladores que no tengan la clave secreta podrán clonar y
hacer commit en un repositorio con archivos encriptados.
Esto te permite almacenar tu material secreto (como pueden ser claves)
en el mismo repositorio que tu código sin tener que bloquearlo. Solo un
usuario autorizado puede dar permisos a otros usuarios.
Para instalar el paquete git-crypt usamos:
$ cd repo
$ git-crypt init
$ cat .gitattributes
$ vi .gitattributes
Indicamos que se cifren, por ejemplo, los archivos .html, .org, directo-
rio:secretdir/**secreto y archivo, con cualquier extensión o palabra que le
preceda.
ahora cada vez que hagamos un commit, los archivos .html y .org, subirán
cifrados.
Ya podemos usar la llave para encriptar los archivos indicados por .gitat-
tributes mediante:
y agregar los archivos que deseamos encriptar, usando git add, revisando
el estado de los archivos encriptados mediante:
$ git-crypt status -f
Seguridad
Limitaciones y Trucos
El di¤ del commit varía cuando el vault está abierto vs cuando está cer-
rado. Cuando está abierto, los contenidos del archivo están en formato
plano, es decir, desencriptados. En consecuencia puedes ver el di¤.
Cuando el vault está cerrado, no se puede apreciar un di¤ efectivo ya
que el texto cifrado cambia, pero el ojo humano no puede distinguir los
contenidos.
GitLab (https://about.gitlab.com/)
Para con…gurar:
cd existing_folder
git init
git remote add origin https://gitlab.com/antoniocarrillo69/MDF.git
git add .
git commit -m "Initial commit"
git push -u origin master
cd existing_repo
git remote rename origin old-origin
git remote add origin https://gitlab.com/antoniocarrillo69/MDF.git
git push -u origin –all
git push -u origin –tags
Github (https://github.com/)
Para con…gurar:
$ touch README.md
$ git init
$ git add .
$ git commit -m "mi primer commit"
$ git remote add origin https://github.com/antoniocarrillo69/ejemploPruebas.git
$ git push -u origin master
https://www.jdoodle.com/
https://repl.it/
http://browxy.com
https://jupyter.org/try
https://tio.run/
https://www.compilejava.net/
http://codepad.org/
https://code.hackerearth.com/
https://www.remoteinterview.io/online-c-compiler
https://ideone.com/
https://hackide.herokuapp.com/
https://www.codechef.com/ide
http://cpp.sh/
51
Cuando se trabaja desde la Web es recomendable usar el modo Privado o Incógnito
para no guardar el historial de navegación, información introducida en los formularios y
borrar al cerrar el navegador los datos de los sitios visitados. Pero recuerda que los sitios
Web que visitamos sí guardan información de nuestra visita, nuestro proveedor de Internet
también guarda constancia de nuestra visita y si descargamos algo, esto no se borra al igual
que el historial de descargas, además de las marcas de páginas o favoritos se conservarán
al cerrar al navegador.
https://codebunk.com/
https://rextester.com/
https://www.tutorialspoint.com/codingground.htm
https://www.compileonline.com
http://python…ddle.com/
https://trinket.io/python
https://www.pythonanywhere.com/try-ipython/
https://www.rollapp.com/
https://godbolt.org/
https://www.codiva.io/
https://paiza.io/en
https://wandbox.org/
http://coliru.stacked-crooked.com/
http://quick-bench.com/
https://cppinsights.io/
https://ideone.com/
http://cpp.sh/
https://ide.geeksforgeeks.org/
https://www.codechef.com/ide
https://visualstudio.microsoft.com/services/visual-studio-online/
https://gitduck.com/
https://codeshare.io/
https://www.tutorialspoint.com/codingground.htm
http://ideone.com
https://codebunk.com
https://visualstudio.microsoft.com/services/visual-studio-online/
https://ace.c9.io/build/kitchen-sink.html
https://coderpad.io/
https://peerpad.net/
https://aws.amazon.com/cloud9/
https://codeanywhere.com/
https://stekpad.com/home/
https://colab.research.google.com/notebooks/intro.ipynb
La implementación de algoritmos
Integración de funciones
Manipulación de polinomios
Gra…cación de funciones en 2D y 3D
R (véase [29])
Maple (véase [41])
Mathematica (véase [42])
Maxima (véase [43])
Por otro lado existe Anaconda, una Suite de código abierto que abarca
una serie de aplicaciones, librerías y conceptos diseñados para el desarrollo
de la Ciencia de Datos con Python. En líneas generales Anaconda Distri-
bution es una distribucción de Python que funciona como un gestor de en-
torno, un gestor de paquetes y que posee una colección de más de 720 pa-
quetes de código abierto. Anaconda Distribution se agrupa en 4 sectores
o soluciones tecnológicas, Anaconda Navigator, Anaconda Project, las li-
brerías de Ciencia de Datos y Conda. Todas estas se instalan de manera
automática y en un procedimiento muy sencillo. Para más información ver:
https://www.anaconda.com/.
También esta SageMath, una Suite de código abierto bajo la licencia GPL
de Software matemático como: NumPy, SciPy, Matplotlib, Sympy, Maxi-
ma, GAP, FLINT, R, entre otros. Además combina acceso a una poderosa
combinación del lenguaje basada en Python o directamente vía interfaces
o Wrappers. La misión del proyecto es crear una alternativa de Software
libre a Magma, Maple, Mathematica y Matlab. Para más información ver:
http://www.sagemath.org/.
octave:1> (12+15+20)/3
octave:1> 2^8
octave:1> a=[1,3,5]
octave:2> b=[1;2;3]
octave:3> e=[a ; b ; 2, 4 6]
octave:1> E=eye(3)
octave:1> y=E(:,1)
v=E*v
octave:1> A=ones(3)
octave:1>A=ones(3)+eye(3)
octave:2> C=inv(A)
octave:1> A=ones(3)+eye(3)
octave:2> b=A(:,3)
octave:3> x=inv(A)*b
octave:3> x=Anb
Para sustituir los valores de una …la o columna por los de un vector,
hacemos:
octave:1> A(3,:)=v
octave:2> A(:,2)=w
ones(n) genera una matriz de n n con todos los valores iguales a uno
zeros(n) genera una matriz de n n con todos los valores iguales a cero
octave:1> 1:10
también podemos usar la notación p:q:r para crear una secuencia que ini-
cia en p, …naliza en r con intervalos de q. En el siguiente caso almacenaremos
en una variable b una secuencia partiendo de cero y …nalizando en diez, con
un intervalo de dos entre cada número, ejemplo:
octave:1> b=0:2:10
octave:1> sin(90*pi/180)
6x-7y=5
8x-9y=7
function s = sind(x)
%SIND(X) Calcula seno(x) en grados
s = sin(x*pi/180);
endfunction
y ejecutamos:
octave:j> sind(45)
Para que Octave ejecute un archivo o script, este debe tener extensión .m
y debe encontrarse en el directorio desde donde estemos ejecutando Octave.
También podemos agregar rutas adicionales con el comando addpath(’ruta’),
donde ruta es el camino al directorio que contiene los scripts. Para borrar la
ruta usamos rmpath(’ruta’).
Por ejemplo, el cálculo de las raíces de la ecuación cuadrática (véase 2.4),
podemos de…nir en el archivo cuadratica.m, el siguiente código:
Ejemplo en Octave/MatLab:
x1 = (-b+sqrt(b*b-4*a*c))/(2*a);
r = f(a, b, c, x1);
fprintf(’Raiz(%1.16f), evaluacion raiz: (%e)nn’,x1,r);
x2 = (-b-sqrt(b*b-4*a*c))/(2*a);
r = f(a, b, c, x2);
fprintf(’Raiz(%1.16f), evaluacion raiz: (%e)nn’,x2,r);
fprintf(’nnChicharronera 2nn’)
x1 = (-2*c)/(b+sqrt(b*b-4*a*c));
r = f(a, b, c, x1);
fprintf(’Raiz(%1.16f), evaluacion raiz: (%e)nn’,x1,r);
x2 = (-2*c)/(b-sqrt(b*b-4*a*c));
r = f(a, b, c, x2);
fprintf(’Raiz(%1.16f), evaluacion raiz: (%e)nn’,x2,r);
fprintf(’nnMetodo Newton-Raphsonnn’)
x = x1 -1;
fprintf(’Valor inicial aproximado de X1 = %1.16fnn’,x);
for i = 1:10
x = x - (f(a, b, c, x) / df(a, b, c, x));
end
r = f(a, b, c, x);
fprintf(’Raiz (%1.16f), evaluacion raiz: (%e)nn’,x,r);
x = x2 -1;
fprintf(’Valor inicial aproximado de X2 = %1.16fnn’,x);
for i = 1:10
x = x - (f(a, b, c, x) / df(a, b, c, x));
end
r = f(a, b, c, x);
fprintf(’Raiz (%1.16f), evaluacion raiz: (%e)nn’,x,r);
end
% Funcion cuadratica
function r = f(a, b, c, x)
r = x * x * a + x * b + c;
end
% Derivada de la funcion cuadratica
function r = df(a, b, c, x)
r = 2.0 * x * a + b;
end
53
Cuando se trabaja desde la Web es recomendable usar el modo Privado o Incógnito
para no guardar el historial de navegación, información introducida en los formularios y
borrar al cerrar el navegador los datos de los sitios visitados. Pero recuerda que los sitios
Web que visitamos sí guardan información de nuestra visita, nuestro proveedor de Internet
también guarda constancia de nuestra visita y si descargamos algo, esto no se borra al igual
que el historial de descargas, además de las marcas de páginas o favoritos se conservarán
al cerrar al navegador.
Álgebra diferencial
Números
Listas, arreglos y matrices
Transformaciones algebraicas
Resolución de ecuaciones
Límites, derivadas e integrales
Conjuntos
Vectores y campos
Grá…cos
Ecuaciones diferenciales
Interpolación numérica
Inecuaciones racionales
Series de potencias
Transformada de Laplace
Ecuaciones recurrentes
Programación
(34*6)/34;
200!;
Maxima devuelve los resultados de forma exacta sin aproximaciones de-
cimales, por ejemplo para resolver la siguiente operación:
" #3
1
37 7
+
4 + 35 9
escribimos:
((3^7/(4+3/5)^(-1)+7/9)^3;
y obtenemos el resultado de forma simpli…cada. Si lo necesitamos podemos
pedir el resultado en forma decimal; por ejemplo si queremos la expresión
decimal del último resultado, escribimos:
‡oat(%);
Maxima puede trabajar con precisión arbitraria. Para calcular el valor
del cociente e con cien cifras decimales, debemos especi…car primero la pre-
cisión requerida asignándole a la variable fpprec el valor 100 y a continuación
realizar el cálculo, solicitando la expresión decimal con una llamada a la
función b‡oat, de esta forma:
fpprec:100$ b‡oat(%e / %pi);
aquí se usa el símbolo de $ como delimitador entre instrucciones.
z1:3+5*%i$ z2:1/2-4*%i$
z1+z2;
factorial(3)
permutations([1,2,3]);
minfactorial(n!/(n+2)!);
q: (x+3)^5-(x-a)^3+(x+b)^(-1)+(x-1/4)^(-5);
expand(q);
expand(q,3,2);
%,a=2,b=2*c;
1/(x+y)-(y+x)/z+(x+y)^2;
subst(k,x+y,%);
subst(sqrt(k),x+y,(x+y)^2+(x+y));
ratsubst(sqrt(k),x+y,(x+y)^2+(x+y));
expand((a-2)*(b+1)^2*(a+b)^5);
factor(%);
p1: x^7-4*x^6-7*x^5+8*x^4+11*x^3-4*x^2-5*x;
p2: x^4-2*x^3-4*x^2+2*x+3;
gcd(p1,p2);
load(functs)$
lcm(p1,p2);
es posible que deseemos disponer del mcd factorizado, por lo que hacemos:
factor(%);
solve((2-a)/x-3=b*x+1/x,x);
M : matrix([sqrt(3),2/5],[3,sin(2)]);
y resolverla:
linsolve_by_lu(M,M.M,’‡oat…eld);
limit(1/sqrt(x),x,inf);
di¤(x^log(a*x),x);
la segunda derivada:
di¤(x^log(a*x),x,2);
integrate(cos(x)^3/sin(x)^4,x);
integrate(2*x/((x-1)*(x+2)),x,3,5);
‡oat(%);
http://www.wolframalpha.com/
http://www.quickmath.com/
http://maxima-online.org
http://maxima.cesga.es/
55
Cuando se trabaja desde la Web es recomendable usar el modo Privado o Incógnito
para no guardar el historial de navegación, información introducida en los formularios y
borrar al cerrar el navegador los datos de los sitios visitados. Pero recuerda que los sitios
Web que visitamos sí guardan información de nuestra visita, nuestro proveedor de Internet
también guarda constancia de nuestra visita y si descargamos algo, esto no se borra al igual
que el historial de descargas, además de las marcas de páginas o favoritos se conservarán
al cerrar al navegador.
Tablas Cruzadas
Reordenamiento de Datos
Frecuencias
Estadística Descriptiva
Estadística Lineal
Estadística no Lineal
Estadística Biestadística
Modelos de Regresión
Clasi…cación
Fiabilidad
Categorías
Clustering
Validación de Datos
Tendencias
Grá…cos y Diagramas
R (véase [29])
mean(x)
a los alumnos de sexto de primaria de todos los colegios sobre varias materias.
Los datos que vamos a utilizar corresponden a las notas medias obtenidas
por los colegios en los años 2009 y 2010 (fuente: diario El País) junto con el
tipo de colegio (concertado, privado o público).
Para ello, hay que bajar los datos y generar un …chero de R, el comando
read.table lee un …chero de datos de texto y crea un …chero con el que R ya
puede trabajar. En nuestro ejemplo vamos a usar los siguientes argumentos:
names(notas)
chero$variable
Por ejemplo, las medias de las notas de 2009 y 2010 se obtienen con los
comandos:
mean(notas$nota09)
las desviaciones típicas de las notas de 2009 y 2010 se obtienen con los
comandos:
sd(notas$nota09)
sd(notas$nota10)
summary(notas)
hist(notas$nota09)
boxplot(notas$nota09, notas$nota10)
vemos que en 2010 las notas tienden a ser más bajas. También podemos
comparar las notas de 2010 para cada tipo de colegio. Aunque las diferencias
no son muy grandes, los centros privados tienden a tener notas más altas que
los concertados, y éstos más altas que los públicos.
boxplot(notas$nota10 ~notas$tipo)
plot of chunk boxplot2
para estudiar si hay relación entre las notas de los dos años podemos
representar la nube de puntos correspondiente:
plot(notas$nota09, notas$nota10)
cov(notas$nota09, notas$nota10)
cor(notas$nota09, notas$nota10)
Además de analizar datos, R se puede usar para llevar a cabo todo tipo
de representaciones grá…cas y cálculos matemáticos. Por ejemplo, la función
cos(x^2) se puede representar entre 0; 2 mediante:
curve(cos(x^2), 0, 2 * pi)
2
la integral de la función anterior entre 0; se calcula con:
integrate(function(x) cos(x^2), 0, pi)
una derivada de la función se obtiene de la siguiente forma:
D(expression(cos(x^2)), "x")
para representar la función de densidad de una variable aleatoria normal
de media = 3 y desviación típica = 1 escribimos:
curve(dnorm(x, mean = 3, sd = 1), -1, 7)
hemos usado el comando dnorm, con los argumentos adecuados, para
evaluar la función de densidad normal. Si lo que queremos es generar 1000
números aleatorios que sigan esta distribución y después representar el his-
tograma correspondiente:
x <- rnorm(1000, mean = 3, sd = 1)
hist(x)
7.2.1 R y Python
El paquete R es un lenguaje y entorno de programación para análisis es-
tadístico y grá…co poderoso, pero es posible exteder su uso al lenguaje de
programación de Python, logrando una amalgama aún en proceso de desa-
rrollo que permite tener lo mejor de ambos mundos con muy poco trabajo
extra.
Para iniciar, se debe importar las funciones y demás que componen la
parte del paquete R para poder usarse en Python, mediante:
from R_functions import *
y se esta listo para usar R en Python, ejemplo:
lst=[20,12,16,32,27,65,44,45,22,18]
…venum(lst)
obteniendo:
> array([12. , 18.5, 24.5, 41. , 65. ])
Por otro lado existe Anaconda, una Suite de código abierto que abarca
una serie de aplicaciones, librerías y conceptos diseñados para el desarrollo
de la Ciencia de datos con Python. En líneas generales Anaconda Distribu-
tion es una distribucción de Python que funciona como un gestor de en-
torno, un gestor de paquetes y que posee una colección de más de 720 pa-
quetes de código abierto. Anaconda Distribution se agrupa en 4 sectores
o soluciones tecnológicas, Anaconda Navigator, Anaconda Project, Las li-
brerías de Ciencia de datos y Conda. Todas estas se instalan de manera
automática y en un procedimiento muy sencillo. Para más información ver:
https://www.anaconda.com/.
También esta SageMath, una Suite de código abierto bajo la licencia GPL
de Software matemático como: NumPy, SciPy, matplotlib, Sympy, Maxi-
ma, GAP, FLINT, R, entre otros. Además combina acceso a una poderosa
combinación del lenguaje basada en Python o directamente vía interfaces
o Wrappers. La misión del proyecto es crear una alternativa de Software
libre a Magma, Maple, Mathematica y Matlab. Para más información ver:
http://www.sagemath.org/.
Para R https://nclab.com/free-portal/
Para R https://cdn.datacamp.com/dcl-react-prod/example.html
56
Cuando se trabaja desde la Web es recomendable usar el modo Privado o Incógnito
para no guardar el historial de navegación, información introducida en los formularios y
borrar al cerrar el navegador los datos de los sitios visitados. Pero recuerda que los sitios
Web que visitamos sí guardan información de nuestra visita, nuestro proveedor de Internet
también guarda constancia de nuestra visita y si descargamos algo, esto no se borra al igual
que el historial de descargas, además de las marcas de páginas o favoritos se conservarán
al cerrar al navegador.
8 El Cómputo en Paralelo
Los sistemas de cómputo con procesamiento en paralelo surgen de la necesi-
dad de resolver problemas complejos en un tiempo razonable, utilizando las
ventajas de memoria, velocidad de los procesadores, formas de interconexión
de estos y distribución de la tarea, a los que en su conjunto denominamos ar-
quitectura en paralelo. Entenderemos por una arquitectura en paralelo a un
conjunto de procesadores interconectados capaces de cooperar en la solución
de un problema.
Así, para resolver un problema en particular, se usa una arquitectura o
combinación de múltiples arquitecturas (topologías), ya que cada una ofrece
ventajas y desventajas que tienen que ser sopesadas antes de implementar
la solución del problema en una arquitectura en particular. También es
necesario conocer los problemas a los que se enfrenta un desarrollador de
programas que se desean correr en paralelo, como son: el partir e…cientemente
un problema en múltiples tareas y como distribuir estas según la arquitectura
en particular con que se trabaje.
unidades de control del sistema -ejemplo de estos sistemas son las máquinas
paralelas actuales-.
Los sistemas fuertemente acoplados son aquellos en los que los proce-
sadores dependen unos de otros.
Los sistemas débilmente acoplados son aquellos en los que existe poca
interacción entre los diferentes procesadores que forman el sistema.
Sistema Asimétrico
Los Clusters pueden formarse de diversos equipos; los más comunes son los
de computadoras personales, pero es creciente el uso de computadoras multi-
procesador de más de un procesador de memoria compartida interconectados
por red con los demás nodos del mismo tipo, incluso el uso de computadoras
multiprocesador de procesadores vectoriales Pipeline. Los Clusters armados
con la con…guración anterior tienen grandes ventajas para procesamiento
paralelo:
Sin lugar a duda los Clusters presentan una alternativa importante para
varios problemas particulares, no sólo por su economía, si no también porque
pueden ser diseñados y ajustados para ciertas aplicaciones. Las aplicaciones
que pueden sacar provecho de Clusters son en donde el grado de comunicación
entre procesos es de bajo a medio.
Bioinformática
Cálculo …nanciero
Defensa e Inteligencia
Aprendizaje automático
Ciencia de los materiales
Medios audiovisuales y entretenimiento
Imágenes médicas
Dinámica molecular
Análisis numérico
Física
Química cuántica
Exploración sísmica
Mecánica estructural computacional
Visualización e interacción de proteínas
Modelos meteorológicos y climáticos
Lenguajes de programación:
CUDA C/C++
CUDA Fortran
Python
.NET
Compiladores disponibles:
Fortran
Wrapper de Java
JaCUDA
F# para CUDA
MATLAB
Mathematica
8.3 Escalabilidad
Se entiende por escalabilidad a la capacidad de adaptación y respuesta de
un sistema con respecto al rendimiento del mismo a medida que aumentan
de forma signi…cativa la carga computacional del mismo. Aunque parezca
un concepto claro, la escalabilidad de un sistema es un aspecto complejo e
importante del diseño.
La escalabilidad esta íntimamente ligada al diseño del sistema. In‡uye en
el rendimiento de forma signi…cativa. Si una aplicación esta bien diseñada,
la escalabilidad no constituye un problema. Analizando la escalabilidad, se
deduce de la implementación y del diseño general del sistema. No es atributo
del sistema con…gurable.
La escalabilidad supone un factor crítico en el crecimiento de un sistema.
Si un sistema tiene como objetivo crecer la carga computacional -en el número
de usuarios o procesos- manteniendo su rendimiento actual, tiene que evaluar
dos posibles opciones:
Unión de Hardware
Clusters de Software
Alto rendimiento
Alta disponibilidad
Equilibrio de carga
Escalabilidad
Tipos de Cluster
T (1) s
e= = : (8.2)
pT (p) p
Cp = p Tp :
0 p0 p0 p0 Tp0
Epp = Sp = :
p p Tp
Haciendo uso del mismo número de Cores base para el Cluster A que para
Cluster B, se tiene que:
32
S100 = 5178=2661 = 1:94
60 0 Tp0 0 p
Aceleración relativa es Spp = Tp para p p0 , en la cual se espera que Spp ' p0 y
0 p0 p0 p0 Tp0
e…ciencia relativa es Epp = p Sp = p Tp :
Cp = P Tp ;
y en Cluster A es:
C100 = 266; 100
que representa una disminución de 27%; además de un factor muy impor-
tante, el Cluster A tuvo un costo monetario mucho menor con respecto del
Cluster B.
ello nos interesa trabajar en computadoras que nos puedan satisfacer estas
demandas.
La computación de alto rendimiento (véase 8) -High performance Com-
puting o HPC en inglés- es la agregación de potencia de cálculo para re-
solver problemas complejos en Ciencia e Ingeniería o gestión. Para lograr
este objetivo, la computación de alto rendimiento se apoya en tecnologías
computacionales como los Clusters, las supercomputadoras o la computación
paralela. La mayoría de las ideas actuales de la computación distribuida se
han basado en la computación de alto rendimiento.
La computación paralela o de alto rendimiento es una forma de cómputo
en la que muchas instrucciones se ejecutan simultáneamente, operando sobre
el principio de que problemas grandes, a menudo se pueden dividir en unos
más pequeños, que luego son resueltos simultáneamente (en paralelo). Hay
varias formas diferentes de computación paralela: paralelismo a nivel de bits,
paralelismo a nivel de instrucción, paralelismo de datos y paralelismo de
tareas. El paralelismo se ha empleado durante muchos años, sobre todo
en la computación de altas prestaciones, pero el interés en ella ha crecido
últimamente debido a las limitaciones físicas que impiden el aumento de la
frecuencia. Como el consumo de energía –y por consiguiente la generación de
calor–de las computadoras constituye una preocupación en los últimos años,
la computación en paralelo se ha convertido en el paradigma dominante en
la arquitectura de computadoras, principalmente en forma de procesadores
multinúcleo.
Las computadoras paralelas pueden clasi…carse según el nivel de paralelismo
que admite su Hardware: equipos con procesadores multinúcleo y multi-
procesador que tienen múltiples elementos de procesamiento dentro de una
sola máquina, procesadores masivamente paralelos, Cluster y cúmulos de
Clusters (Grids) que utilizan varios equipos para trabajar en la misma tarea.
Muchas veces, para acelerar tareas especí…cas, se utilizan arquitecturas es-
pecializadas de computación en paralelo junto a procesadores tradicionales.
Computo Paralelo
que los hilos pueden continuar ejecutando tareas disponibles sin necesidad
de esperar a que todo el equipo de hilos acabe un bloque paralelo. El uso
de tareas con dependencias crea un grafo, pudiéndose aplicar propiedades de
grafos a la hora de escoger tareas para su ejecución.
Salvo el uso de implementaciones de Hardware de la biblioteca de tiempo
de ejecución OpenMP (p.ej. en una matriz de puertas programables FPGAs),
los sobrecostes de las tareas es mayor, este sobrecoste ha de ser amortizado
mediante el potencial paralelismo adicional que las tareas exponen.
#include <stdio.h>
// Indica si se carga lo referente a OpenMP
#ifdef _OPENMP
#include <omp.h>
int threads=omp_get_num_threads();
#else
int threads=0;
#endif
#de…ne STEPCOUNTER 1000000000
int main (void)
{
long i;
double pi=0;
printf("threads %d", threads);
#pragma omp parallel for reduction(+:pi)
for (i=0; i < STEPCOUNTER; i++)
{
pi += 1.0/(i*4.0 +1.0);
pi -= 1.0/(i*4.0 +3.0);
}
pi = pi*4.0;
printf("PI = %2.16lf ",pi);
return 0;
}
$ g++ pi.cpp -o pi
$ time ./pi
$ export OMP_NUM_THREADS=2
Ejecutar:
$ time ./pi
62
Compilar fuentes en C++ solicitando que el ejecutable tenga el nombre ejemp:
$ time ./ejemp
en este caso no se usa ninguna directiva para optimizar el ejecutable generado. Para
compilar usando diversas optimizaciones (O1, -O2 o -O3) usar por ejemplo:
$ time ./a.out
OpenMP
Es decir:
Send(dir, lg, td, dest, etiq, com)
#include <stdio.h>
#include <mpi.h>
int main(int argc, char *argv[])
{
int rank, size;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
#include <iostream>
#include <iomanip>
#include <mpi.h>
using namespace std;
int main(int argc, char ** argv){
int mynode, totalnodes;
int sum = 0,startval,endval,accum;
MPI_Status status;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD, &totalnodes);
MPI_Comm_rank(MPI_COMM_WORLD, &mynode);
startval = 1000*mynode/totalnodes+1;
endval =1000*(mynode+1)/totalnodes;
for(int i=startval;i<=endval;i=i+1) sum = sum + i;
if(mynode!=0)
MPI_Send(&sum, 1, MPI_INT, 0, 1, MPI_COMM_WORLD);
else
for(int j=1;j<totalnodes;j=j+1){
MPI_Recv(&accum, 1, MPI_INT, j, 1,
MPI_COMM_WORLD, &status);
sum = sum + accum;
}
if(mynode == 0)
cout << "The sum from 1 to 1000 is: "<< sum << endl;
MPI_Finalize();
}
$ lamboot -v
$ lamhalt -v
MPI
Esquema Maestro-Esclavo
MPI::Init(argc,argv);
ME_id = MPI::COMM_WORLD.Get_rank();
MP_np = MPI::COMM_WORLD.Get_size();
if (ME_id == 0) {
// Operaciones del Principal
} else {
// Operaciones del Subordinado con identi…cador ME_id
}
MPI::Finalize();
}
https://www.jdoodle.com/
https://repl.it/
http://browxy.com
https://jupyter.org/try
https://tio.run/
https://www.compilejava.net/
http://codepad.org/
https://code.hackerearth.com/
63
Cuando se trabaja desde la Web es recomendable usar el modo Privado o Incógnito
para no guardar el historial de navegación, información introducida en los formularios y
borrar al cerrar el navegador los datos de los sitios visitados. Pero recuerda que los sitios
Web que visitamos sí guardan información de nuestra visita, nuestro proveedor de Internet
también guarda constancia de nuestra visita y si descargamos algo, esto no se borra al igual
que el historial de descargas, además de las marcas de páginas o favoritos se conservarán
al cerrar al navegador.
https://www.remoteinterview.io/online-c-compiler
https://ideone.com/
https://hackide.herokuapp.com/
https://www.codechef.com/ide
http://cpp.sh/
https://codebunk.com/
https://rextester.com/
https://www.tutorialspoint.com/codingground.htm
https://www.compileonline.com
http://python…ddle.com/
https://trinket.io/python
https://www.pythonanywhere.com/try-ipython/
https://www.rollapp.com/
https://godbolt.org/
https://www.codiva.io/
https://paiza.io/en
https://wandbox.org/
http://coliru.stacked-crooked.com/
http://quick-bench.com/
https://cppinsights.io/
https://ideone.com/
http://cpp.sh/
https://ide.geeksforgeeks.org/
https://www.codechef.com/ide
https://visualstudio.microsoft.com/services/visual-studio-online/
https://gitduck.com/
https://codeshare.io/
https://www.tutorialspoint.com/codingground.htm
http://ideone.com
https://codebunk.com
https://visualstudio.microsoft.com/services/visual-studio-online/
https://ace.c9.io/build/kitchen-sink.html
https://coderpad.io/
https://peerpad.net/
https://aws.amazon.com/cloud9/
https://codeanywhere.com/
https://stekpad.com/home/
https://colab.research.google.com/notebooks/intro.ipynb
9 Ejemplitos
Hay muchas aplicaciones a las herramientas computacionales, pero nos in-
teresan aquellas que permitan resolver problemas concomitantes en Ciencia
e Ingeniería. Muchas de estas aplicaciones caen en lo que comúnmente se
llama cómputo cientí…co. La computación cientí…ca es el campo de estudio
relacionado con la construcción de modelos matemáticos, técnicas numéricas
para resolver problemas cientí…cos y de ingeniería; y su respectiva imple-
mentación computacional.
Este campo es distinto a las ciencias de la computación y el procesamiento
de información, también es diferente a la teoría y experimentación, que son
las formas tradicionales de la ciencia y la ingeniería. El enfoque de la com-
putación cientí…ca es para ganar entendimiento, principalmente a través del
análisis de modelos matemáticos implementados en computadoras.
Los programas de aplicación de la computación cientí…ca a menudo mo-
delan cambios en las condiciones del mundo real, tales como el tiempo at-
mosférico, el ‡ujo de aire alrededor de un avión, el movimiento de las es-
trellas en una galaxia, el comportamiento de un dispositivo explosivo, entre
otros. Estos programas deberían crear una ’malla lógica’en la memoria de
la computadora, donde cada ítem corresponda a un área en el espacio y con-
tenga información acerca del espacio relevante para el modelo. Por ejemplo,
en modelos para el tiempo atmosférico, cada ítem podría ser un kilómetro
cuadrado, con la altitud del suelo, dirección actual del viento, humedad am-
biental, temperatura, presión, etc. El programa debería calcular el probable
siguiente estado basado en el estado actual, simulado en medidas de tiempo,
resolviendo ecuaciones que describen cómo operan los sistemas; y repetir el
proceso para calcular el siguiente estado.
El término cientí…co computacional es usado para describir a alguien
experto en computación cientí…ca. Esta persona es generalmente un cien-
tí…co, un ingeniero o un matemático aplicado que aplica computación de
alto rendimiento en diferentes formas para avanzar en el estado del arte de
su respectiva disciplina de la física, química o ingeniería. Cientí…cos com-
putacionales han impactado cada vez más en otras áreas como la economía,
biología y medicina. La computación cientí…ca es hoy en día considerada
como el tercer modo de ciencia, complementando y añadiendo a la experi-
mentación/observación y teoría.
La computación cientí…ca es más estudiada por medio de la matemática
aplicada o programas de las ciencias de la computación, o dentro de un
Análisis numérico
Métodos de integración sobre una malla uniforme: regla del rectángulo, regla
del trapecio, regla del punto medio, regla de Simpson
Método de Montecarlo
Factorización de Cholesky
Método de Newton
xn+1 = kxn (1 xn )
donde n denota los pasos discretos del tiempo y x es la variable que cambia
con éste.
Si el tiempo es medido en forma continua, el sistema dinámico continuo
resultante es expresado como una ecuación diferencial ordinaria; por ejemplo:
dx
= ax (1 x)
dt
donde x es la variable que cambia con el tiempo t. La variable cambiante x
es normalmente un número real, aunque también puede ser un vector en Rk .
hold on
N = 500
X = zeros(N,1);
Y = zeros(N,1);
for p=0:0.005:4
x=0.1;
for i=1:300
y = p*x*(1.0-x);
x = y;
end
for i=1:N
y = p*x*(1.0-x);
x = y;
X(i) = p;
Y(i) = x;
end
plot(X,Y,’.’)
end
hold o¤
Sistemas dinámicos
9.2 Fractales
Un fractal es un objeto geométrico cuya estructura básica, fragmentada o
aparentemente irregular, se repite a diferentes escalas. El término fue pro-
puesto por el matemático Benoît Mandelbrot en 1975 y deriva del latín frac-
tus, que signi…ca quebrado o fracturado. Muchas estructuras naturales son
de tipo fractal. La propiedad matemática clave de un objeto genuinamente
fractal es que su dimensión métrica fractal es un número racional no entero.
Curva de Koch en 1904, Helge von Koch de…nió una curva con propiedades
similares a la de Weierstrass: el copo de nieve de Koch, también llamado es-
trella de Koch, es una curva cerrada continua pero no diferenciable en ningún
punto descrita por el matemático sueco Helge von Koch en 1904 en un artículo
titulado "Acerca de una curva continua que no posee tangentes y obtenida
por los métodos de la geometría elemental".
En lenguaje actual, diríamos que es una curva fractal. Su construcción
más simple se realiza mediante un proceso iterativo que se inicia partiendo en
tres un segmento de recta e insertando dos más en el tercero medio a manera
de un triángulo equilátero, el proceso se repite in…nidad de veces. La curva
de Koch es un caso particular de curva de De Rham.
Veamos el proceso que lleva a sustituir cada lado por la llamada curva de
Koch: Se toma un segmento, se divide en tres partes iguales, se remplaza la
parte central por dos partes de igual longitud haciendo un ángulo de 60 gra-
dos. Luego, con los cuatro segmentos, se procede de la misma manera, lo que
da lugar a 16 segmentos más pequeños en la segunda iteración. Y así suce-
sivamente. La …gura representa las seis primeras etapas de la construcción.
La última curva es una buena aproximación de la curva …nal.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from math import sin, cos, pi
import matplotlib.pyplot as plt
import matplotlib
plt.…gure("Koch snow‡ack")
kochSnowFlake(200,4) # range 1 -6
plt.show()
fc (z) = z 2 + c
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import numpy as np
def mandelbrot_set(xmin, xmax, ymin, ymax, xn, yn, maxiter, hori-
zon=2.0):
X = np.linspace(xmin, xmax, xn)
Y = np.linspace(ymin, ymax, yn)
C = X + Y[:, None]*1j
N = np.zeros(C.shape, dtype=int)
Z = np.zeros(C.shape, np.complex64)
for n in range(maxiter):
I = np.less(abs(Z), horizon)
N[I] = n
Z[I] = Z[I]**2 + C[I]
N[N == maxiter-1] = 0
return Z, N
if __name__ == ’__main__’:
import time
import matplotlib
from matplotlib import colors
import matplotlib.pyplot as plt
xmin, xmax, xn = -2.25, +0.75, 3000/2
ymin, ymax, yn = -1.25, +1.25, 2500/2
maxiter = 200
horizon = 2.0 ** 40
log_horizon = np.log(np.log(horizon))/np.log(2)
Fractal
https://www.youtube.com/watch?v=pCpLWbHVNhk&app=desktop#menu
9.3 Derivadas
La derivación numérica es una técnica de análisis numérico para calcular
una aproximación a la derivada de una función en un punto utilizando los
valores y propiedades de la misma. Para ello usamos la expansión en Series
de Taylor.
(x xi ) df (x xi )2 d2 f (x xi )k dk f
f (x) = f (xi )+ + +:::+ (9.1)
1! dx xi 2! dx2 xi k! dxk "
df x2 d2 f
f (xi + x) = f (xi ) + x + (9.2)
dx xi 2! dx2 "p
df f (xi + x) f (xi ) x d2 f
= (9.3)
dx xi x 2! dx2 "p
x2 00 x3 000 x4 (4)
f (xi + x) = f (xi ) + xf 0 (xi ) + f (xi ) + f (xi ) + f ( p)
2! 3! 4!
(9.21)
y
x3 000
x2 00 x4 (4)
f (xi x) = f (xi ) xf 0 (xi ) + f (xi )
f (xi ) + f ( r)
3!2! 4!
(9.22)
eliminando las primeras derivadas, sumando las ecuaciones anteriores y des-
pejando se encuentra que
format short e
a % Visualiza el resultado
Generado la siguiente salida (la primera columna es h, las demás son los
errores para los esquemas de aproximación de diferencias …nitas progresiva,
regresiva y centrada respectivamente):
9.4 Integrales
En análisis numérico, la integración numérica constituye una amplia gama
de algoritmos para calcular el valor numérico de una integral de…nida y, por
extensión, el término se usa a veces para describir algoritmos numéricos para
resolver ecuaciones diferenciales. El término cuadratura numérica (a menudo
abreviado a cuadratura) es más o menos sinónimo de integración numérica,
especialmente si se aplica a integrales de una dimensión a pesar de que para
el caso de dos o más dimensiones (integral múltiple) también se utiliza.
El problema básico considerado por la integración numérica es calcular
una solución aproximada a la integral de…nida
Zb
f (x)dx
a
de una integral nos arrojaría una solución exacta, mientras que la solución
numérica nos daría una solución aproximada. El error de la aproximación,
que depende del método que se utilice y de qué tan …no sea, puede llegar a
ser tan pequeño que es posible obtener un resultado idéntico a la solución
analítica en las primeras cifras decimales.
Z1 Z1 X
n
f (x)dx = W (x)g(x)dx wi g(xi )
1 1 i=1
1 X n
n 2
Pn (x) = n (x + 1)n k
(x 1)k
2 k=0 k
n Pn (x)
0 1
1 x
2 21 (3x2 1)
3 12 (5x3 3x)
4 18 (35x4 30x2 + 3)
r 0
q 128
10 225p
5 2 322+13 70
5 r
7
900p
q 322 13 70
10
5+2 7
900
Zb
aX
n
b b a a+b
f (x)dx wi f xi +
2 i=1
2 2
a
Z1 X
2
2 f (2x + 3) dx 2 wi f (2x + 3) =
1 i=1
Zb Zd
c XX
n n
b ad b a a+b d c c+d
f (x; y)dxdy wi wj f xi + ; yj +
2 2 i=1 j=1
2 2 2 2
a c
{0.932469514203152027812301554494,0.661209386466264513661399595020,
0.238619186083196908630501721681,-0.238619186083196908630501721681
,-0.661209386466264513661399595020,-0.932469514203152027812301554494,
0.0,0.0,0.0,0.0},
{0.949107912342758524526189684048,0.741531185599394439863864773281,
0.405845151377397166906606412077,0.0,-0.405845151377397166906606412077,
-0.741531185599394439863864773281,-0.949107912342758524526189684048,
0.0,0.0,0.0},
{0.960289856497536231683560868569,0.796666477413626739591553936476,
0.525532409916328985817739049189,0.183434642495649804939476142360,
-0.183434642495649804939476142360,-0.525532409916328985817739049189,
-0.796666477413626739591553936476,-0.960289856497536231683560868569,
0.0,0.0},
{0.968160239507626089835576202904,0.836031107326635794299429788070,
0.613371432700590397308702039341,0.324253423403808929038538014643,0.0,
-0.324253423403808929038538014643,-0.613371432700590397308702039341,
-0.836031107326635794299429788070,-0.968160239507626089835576202904,0.0},
{0.973906528517171720077964012084,0.865063366688984510732096688423,
0.679409568299024406234327365115,0.433395394129247190799265943166,
0.148874338981631210884626001130,-0.148874338981631210884626001130,
-0.433395394129247190799265943166,-0.679409568299024406234327365115,
-0.865063366688984510732096688423,-0.973906528517171720077964012084}
};
// Arreglo para los pesos
static double PESOS[][10] = {
{1.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0},
{0.555555555555555555555555555556,0.888888888888888888888888888889,
0.555555555555555555555555555556,0.0,0.0,0.0,0.0,0.0,0.0,0.0},
{0.347854845137453857373063949222,0.652145154862546142626936050778,
0.652145154862546142626936050778,0.347854845137453857373063949222,
0.0,0.0,0.0,0.0,0.0,0.0},
{0.236926885056189087514264040720,0.478628670499366468041291514836,
0.568888888888888888888888888889,0.478628670499366468041291514836,
0.236926885056189087514264040720,0.0,0.0,0.0,0.0,0.0},
{0.171324492379170345040296142173,0.360761573048138607569833513838,
0.467913934572691047389870343990,0.467913934572691047389870343990,
0.360761573048138607569833513838,0.171324492379170345040296142173,0.0,
0.0,0.0,0.0},
{0.129484966168869693270611432679,0.279705391489276667901467771424,
0.381830050505118944950369775489,0.417959183673469387755102040816,
0.381830050505118944950369775489,0.279705391489276667901467771424,
0.129484966168869693270611432679,0.0,0.0,0.0},
{0.101228536290376259152531354310,0.222381034453374470544355994426,
0.313706645877887287337962201987,0.36268378337836198297,
0.362683783378361982965150449277,0.313706645877887287337962201987,
0.222381034453374470544355994426,0.101228536290376259152531354310
,0.0,0.0},
{0.0812743883615744119718921581105,0.180648160694857404058472031243,
0.260610696402935462318742869419,0.312347077040002840068630406584,
0.330239355001259763164525069287,0.312347077040002840068630406584,
0.260610696402935462318742869419,0.180648160694857404058472031243,
0.0812743883615744119718921581105,0.0},
{0.0666713443086881375935688098933,0.149451349150580593145776339658,
0.219086362515982043995534934228,0.269266719309996355091226921569,
0.295524224714752870173892994651,0.295524224714752870173892994651,
0.269266719309996355091226921569,0.219086362515982043995534934228,
0.149451349150580593145776339658,0.0666713443086881375935688098933}
};
// Funcion Principal ....
int main(void)
{
int k, P_I = 8;
int j, i;
double x = 0.0;
{
x += PESOS[P_I-2][k] * (sinl(PUNTOS[P_I-2][k] ));
}
printf("El resultado es %2.18lf, debe de ser 0.0nn",x);
Si, la solicitud de memoria para Dat[i] se hace de tal forma que los datos
del renglón esten continuos — son b números de punto ‡otante— , esto mi-
nimizará los accesos a la memoria principal en cada una de las operaciones
involucradas en el producto, como se explica en las siguientes secciones.
// Creacion
double **Dat;
Dat = new double*[ren];
for (i = 0; i < ren; i++) Dat[i] = new double[b];
int *Ind;
Ind = new int[b];
// Inicializacion
for (i = 0; i < ren; i++)
for (j = 0; j < b; j++) Dat[i][j] = 0.0;
for (i = 0; i < b; i++) Ind[i] = 0;
// Creacion
double **Dat;
Dat = new double*[ren];
for (i = 0; i < ren; i++) Dat[i] = new double[b];
int **Ind;
Ind = new int*[ren];
for (i = 0; i < ren; i++) Ind[i] = new int[b];
// Inicializacion
for (i = 0; i < ren; i++)
for (j = 0; j < b; j++) Dat[i][j] = 0.0, Ind[i][j] = -1;
A(i, i + 1) = Q;
b[i] = P);
}
A(N - 1, N - 2) = R; // Renglon …nal de la matriz A y vector b
A(N - 1, N - 1) = P;
b[N - 1] = P;
// Copia la matriz dispersa a la densa para usarla en LU
gmm::copy(A,AA);
// Visualiza la matriz y el vector
std::cout << "Matriz A"<< AA << gmm::endl;
std::cout << "Vector b"<< b << gmm::endl;
return 0;
}
menor número de pasos que en un método directo (véase [52], [53], [54] y
[56]).
Por lo general, es conveniente usar librerías69 para implementar de forma
e…ciente a los vectores, matrices — bandadas y dispersas— y resolver los
sistemas lineales locales asociados a los métodos de resolución de ecuaciones
diferenciales parciales.
y
Uu = y ,
8
>
< xn =!
yn =unn
X
n
(9.38)
:
1
: xi =
> Aii
yi Aij xj para toda i = n 1; :::; 1
j=i+1
de Krylov
rk = b Axk : (9.45)
Au = f (9.46)
n hpn ;pn i
=
hpn ;Apn i
n+1
u = un + n p n
n+1
r = rn n
Apn
Prueba de convergencia (9.47)
n hrn+1 ;rn+1 i
= hrn ;rn i
pn+1 = rn+1 + n pn
n=n+1
de p
lo anterior se puede esperar un espectro de convergencia del orden de
O( ) iteraciones (véase [56] y [61]).
k+1 rk rk
= (9.57)
pk+1 C 1 pk+1
y
k+1
pk C 1 r k
= k (9.58)
p Apk
generando el método de Gradiente Conjugado precondicionado con precondi-
cionador C 1 . Es necesario hacer notar que los métodos Gradiente Conju-
gado y Gradiente Conjugado Precondicionado sólo di…eren en la elección del
producto interior.
Para el método de Gradiente Conjugado Precondicionado, los datos de
entrada son un vector de búsqueda inicial u0 y el precondicionador C 1 : Cal-
culándose r0 = b Au0 ; p = C 1 r0 ; quedando el método esquemáticamente
como:
k+1
pk C 1 r k
= (9.59)
pk Apk
k+1 k
pk+1 = rk p
k+1 rk rk
=
pk+1 C 1 pk+1
uk+1 = uk + k+1 k+1
p
1 k
rk+1 = C r k+1
Apk+1 :
w = C 1r
1 T
v = (C
Pn ) w2
= j=1 wj
k=1
Mientras que k N
Si kvk1 < " Salir
x = Av
t = Pn
j=1vj xj
u = u + tv
r=r tx
1
w=C r
P
= nj=1 wj2
Si krk1 < " Salir
s=
1 T
v= C w + sv
=
k =k+1
la salida del método será la solución aproximada u = (u1 ; :::; un ) y el
residual r = (r1 ; :::; rn ).
En el caso del método sin precondicionamiento, C 1 es la matriz identi-
dad, que para propósitos de optimización sólo es necesario hacer la asignación
de vectores correspondiente en lugar del producto de la matriz por el vec-
tor. En el caso de que la matriz A no sea simétrica, el método de Gradiente
Conjugado puede extenderse para soportarlas, para más información sobre
pruebas de convergencia, resultados numéricos entre los distintos métodos de
solución del sistema algebraico Au = b generada por la discretización de un
problema elíptico y como extender estos para matrices no simétricas ver [57]
y [58].
Teorema 3 Sean A; B y C tres matrices simétricas y positivas de…nidas
entonces
C 1A C 1B B 1A :
Au = f (9.62)
0
el vector de búsqueda inicial u0 y se calcula r0 = f Au0 ; = kr0 k ;
v 1 = r0 = 0 ; quedando el método esquemáticamente como:
n 0
Para n = 1; 2; :::; Mientras < {
wn+1
0 = Av n
Para l = 1 hasta n {
hl;n = wn+1
l ; vl
wn+1
l+1 = w l
n+1
hl;n v l
} (9.63)
hn+1;n = wn+1 n+1
v n+1 = wn+1
n+1 =hn+1;n
Calcular y n tal que n
= 0
e1 ^ yn
H es mínima
n
g
kV k
donde (V ) = es el número de condicionamiento de V :
kV 1 k
A = D + L + LT (9.70)
(i; j) para las que Aij 6= 0. Este tipo de factorización es conocido como
factorización incompleta LU de nivel cero, ILU(0).
El proceso de factorización incompleta puede ser descrito formalmente
como sigue:
Para cada k; si i; j > k:
8
< Aij Aij Aij1 Akj Si (i; j) 2 S
Sij = (9.72)
:
Aij Si (i; j) 2
= S:
Una variante de la idea básica de las factorizaciones incompletas lo consti-
tuye la factorización incompleta modi…cada que consiste en que si el producto
Aij Aij Aij1 Akj 6= 0 (9.73)
y el llenado no esta permitido en la posición (i; j), en lugar de simplemente
descartarlo, esta cantidad se le substrae al elemento de la diagonal Aij .
Matemáticamente esto corresponde a forzar a la matriz precondicionadora
a tener la misma suma por …las que la matriz original. Esta variante resulta
de interés puesto que se ha probado que para ciertos casos la aplicación de
la factorización incompleta modi…cada combinada con pequeñas perturba-
ciones hace que el número de condicionamiento espectral del sistema pre-
condicionado sea de un orden inferior.
Ventaja: Puede mejorar el condicionamiento y la convergencia
signi…cativamente.
Desventaja: El proceso de factorización es costoso y difícil de
paralelizar en general.
Existen dos razones para esto, primero, la ecuación (9.75) permite ase-
gurar que C 0 no es singular (lema de Banach), y segundo, esta será la base
para construir un algoritmo explícito para mejorar C 0 y resolver la ecuación
Au = b:
La construcción de C 0 se realiza en paralelo, independizando el cálculo
de cada columna. El algoritmo permite comenzar desde cualquier entrada
de la columna k, se acepta comúnmente el uso de la diagonal como primera
aproximación. Sea rk el residuo correspondiente a la columna k-ésima, es
decir
rk = AC k ek (9.76)
y sea Ik el conjunto de índices de las entradas no nulas en rk ; es decir, Ik =
fi = f1; 2; :::; ng j rik 6= 0g : Si Lk = fl = f1; 2; :::; ng j Clk 6= 0g ; entonces la
nueva entrada se busca en el conjunto Jk = fj 2 Lck j Aij 6= 0; 8i 2 Ik g : En
realidad las únicas entradas consideradas en C k son aquellas que afectan
las entradas no nulas de rk : En lo que sigue, asumimos que Lk [ fjg =
ik1 ; ik2 ; :::; ikpk es no vacío, siendo pk el número actual de entradas no nulas
de C k y que ikpk = j, para todo j 2 Jk : Para cada j, calculamos
h i2
2
pk
X det Dkl
AC k ek 2
=1 (9.77)
l=1 det Gkl 2
det Gkl
donde, para todo k; det Gk0 = 1 y Gkl es la matriz de Gram de las columnas
ik1 ; ik2 ; :::; ikpk de la matriz A con respecto al producto escalar Euclidiano; Dkl
es la matriz que resulta de remplazar la última …la de la matriz Gkl por
akik1 ; akik2 ; ; :::; akikl ; con 1 l pk : Se selecciona el índice jk que minimiza el
valor de AC k ek 2 :
Esta estrategia de…ne el nuevo índice seleccionado jk atendiendo sola-
mente al conjunto Lk ; lo que nos lleva a un nuevo óptimo donde se actualizan
todas las entradas correspondientes a los índices de Lk : Esto mejora el cri-
terio de (9.74) donde el nuevo índice se selecciona manteniendo las entradas
Sk = fC k 2 Rn j Cik = 0; 8i 2 Lk [ fjk gg ;
pk
X det Dkl
mk = m
~l (9.78)
l=1 det Gkl 2
det Gkl
xT Ax
c1 c2 8x (9.80)
xT Bx
donde c1 y c2 no dependen del tamaño de la matriz. La importancia de esta
propiedad es que del uso de B como precondicionador resulta un método
iterativo cuyo número de iteraciones no depende del tamaño de la matriz.
Ejemplo 3 Sea
}
int main(void)
{
int M=11; // Particion
int N=M-2; // Nodos interiores
double a=0; // Inicio dominio
double c=1; // Fin dominio
double h=(c-a)/(M-1); // Incremento en la malla
double Y0=1.0; // Condicion inicial en el inicio del dominio
double Y1=-1.0; // Condicion inicial en el …n del dominio
// Matriz densa
gmm::dense_matrix<double> AA(N, N);
// Matriz dispersa
gmm::row_matrix< gmm::rsvector<double> > A(N, N);
// Vectores
std::vector<double> x(N), b(N);
int i;
double P = -2 / (h * h);
double Q = 1 / (h * h);
double R = 1 / (h * h);
A(0, 0) = P; // Primer renglon de la matriz A y vector b
A(0, 1) = Q;
b[0] = LD(a + h) - (Y0 / (h * h));
// Renglones intermedios de la matriz A y vector b
for(i = 1; i < N - 1; i++)
{
A(i, i - 1) = R;
A(i, i) = P;
A(i, i + 1) = Q;
b[i] = LD(a + (i + 1) * h);
}
A(N - 1, N - 2) = R; // Renglon …nal de la matriz A y vector b
A(N - 1, N - 1) = P;
b[N - 1] = LD(a + (i + 1) * h) - (Y1 / (h * h));
// Copia la matriz dispersa a la densa para usarla en LU
gmm::copy(A,AA);
// Visualiza la matriz y el vector
std::cout << "Matriz A"<< AA << gmm::endl;
std::cout << a << " " << abs(Y0 - SA(a)) << gmm::endl;
for(i = 0; i < N; i++)
{
std::cout << (i + 1)*h << " " << abs(x[i] - SA((a + (i + 1)*h))) <<
gmm::endl;
}
std::cout << c << " " << abs(Y1 - SA(c)) << gmm::endl;
return 0;
}
% EQUATIONS
% x’=s*(y-x)
% y’=r*x-y-x*z
% z’=x*y-b*z
%
% s=10
% r=28
% b=2.666667
function xf1=f1(t,x,y,z)
% Parametros
s=10;
r=28;
b=2.666667;
% Ecuacion
xf1=s*(y-x);
endfunction
function yf2=f2(t,x,y,z)
% Parametros
s=10;
r=28;
b=2.666667;
% Ecuacion
yf2=r*x-y-x*z;
endfunction
function zf3=f3(t,x,y,z)
% Parametros
s=10;
r=28;
b=2.666667;
% Ecuacion
zf3=x*y-b*z;
endfunction
N = 20000; % Particion
t0 = 0.0; % Tiempo inicial
t1 = 60.0; % Tiempo …nal
cix = 3.0; % Condicion inicial al tiempo t0
ciy = 3.0;
ciz = 3.0;
h = (t1 - t0) / N; % incremento en el tiempo
t = t0; % Asigna el tiempo inicial
% Asigna la condicion inicial
e1 = cix;
e2 = ciy;
e3 = ciz;
EDO
1. Generar una malla del dominio, i.e. una malla es un conjunto …nito de
puntos en los cuales buscaremos la solución aproximada a la ecuación
diferencial parcial.
2. Sustituir las derivadas correspondientes con alguna de las formulas de
diferencias …nitas centradas (véase 9.3 y 9.3), en cada punto donde la
solución es desconocida para obtener un sistema lineal algebraico de
ecuaciones Au = f .
3. Resolver el sistema lineal algebraico de ecuaciones Au = f (véase 9.6),
y así obtener la solución aproximada en cada punto de la malla.
u u1 u 2 u3 un 2 un 1 u :
Octave corre gran parte del código desarrollado para MatLab sin requerir
cambio alguno, en cuanto a SCILAB es requerido hacer algunos ajustes en
la codi…cación y ejecución. En los siguientes ejemplos77 se mostrará como
implementar la solución computacional.
Ejemplo 4 Sea
u00 (x) = 2
cos( x); xi x xf; u(xi) = vi; u(xf ) = vf
74
MatLab es un programa comercial para el cálculo numérico el cual provee
un poderoso ambiente de cálculo para aplicaciones Cientí…cas y de Ingeniería
[https://www.mathworks.com].
75
GNU OCTAVE es un programa open source para el cálculo numérico el cual
provee un poderoso ambiente de cálculo para aplicaciones Cientí…cas y de Ingeniería
[http://www.gnu.org/software/octave].
76
SCILAB es un programa open source para el cálculo numérico el cual provee
un poderoso ambiente de cálculo para aplicaciones Cientí…cas y de Ingeniería
[http://www.scilab.org].
77
Los ejemplos que se muestran en el presente texto se pueden descargar de la página
Web:
MDF
end
yy(n)=vf; % Condicion inicial
% Gra…ca la solucion de la Ecuacion Diferencial Parcial en 1D
plot(xx,[yy,zz]);
endfunction
function y=LadoDerecho(x)
y=-pi*pi*cos(pi*x);
endfunction
function y=SolucionAnalitica(x)
y=cos(pi*x);
endfunction
EDP
78
En Octave (MatLab) se de…ne a una matriz mediante A = zeros(N,N), este tipo de
matriz no es adecuada para nuestros …nes (véase capítulo 9.6). Para ahorrar espacio y
acelerar los cálculos numéricos que se requieren para resolver el sistema lineal asociado
usamos un tipo de matriz que no guarda valores innecesarios (ceros), esto se hace mediante
la declaración de la matriz como A = sparse(N,N).
Por otro lado, existe el Software libre, desarrollados por usuarios y para
usuarios que, entre otras cosas, comparten los códigos fuente, el pro-
grama ejecutable y dan libertades para estudiar, adaptar y redistribuir
a quien así lo requiera el programa y todos sus derivados.
(véase [16]), el Software libre se re…ere a la libertad de los usuarios para eje-
cutar, copiar, distribuir, y estudiar el mismo, e incluso modi…car el Software
y distribuirlo modi…cado.
Un programa es Software libre si los usuarios tienen las cuatro libertades
esenciales:
Copyleft Hay que hacer constar que el titular de los derechos de autor
(Copyright) de un Software bajo licencia Copyleft puede también realizar
una versión modi…cada bajo su Copyright original, y venderla bajo cualquier
licencia que desee, además de distribuir la versión original como Software
libre. Esta técnica ha sido usada como un modelo de negocio por una serie
de empresas que realizan Software libre (por ejemplo MySQL); esta práctica
no restringe ninguno de los derechos otorgados a los usuarios de la versión
Copyleft.
podría aplicarse tanto para Software libre como Software privativo, ya que
la diferencia entre uno y otro esta en que el dueño del Software privativo lo
licencia como propiedad privada y el de Software libre como propiedad social.
Con la intención de corregir el defecto de la expresión "Software propie-
tario" aparece el llamado "Software con propietario", sin embargo se ar-
gumenta contra del término "con propietario" justamente su similitud con
Proprietary en inglés, que sólo haría referencia a un aspecto del Software
que no es libre, manteniendo una de las principales críticas a éste (de "Soft-
ware sujeto a derechos" o "propiedad"). Adicionalmente, si "propietario"
se re…ere al titular de los derechos de autor — y esta claro que no se puede
referir al usuario, en tanto éste es simplemente un cesionario— , no resuelve
la contradicción: todo el Software libre tiene también titulares de derechos
de autor.
La expresión Software no libre (en inglés Non-Free Software) es usado
por la FSF para agrupar todo el Software que no es libre, es decir, incluye al
llamado en inglés "Semi-Free Software" (Software semilibre) y al "Propietary
Software". Asimismo, es frecuentemente utilizado para referirse al Software
que no cumple con las Directrices de Software libre de Debian GNU/Linux,
las cuales siguen la misma idea básica de libertad en el Software, propugnada
por la FSF, y sobre las cuales esta basada la de…nición de código abierto de
la Open Source Initiative.
Adicionalmente el Software de código cerrado nace como antónimo de
Software de código abierto y por lo tanto se centra más en el aspecto de
ausencia de acceso al código que en los derechos sobre el mismo. éste se
re…ere sólo a la ausencia de una sola libertad por lo que su uso debe enfocarse
sólo a este tipo de Software y aunque siempre signi…que que es un Software
que no es libre, no tiene que ser Software de código cerrado.
La expresión Software privado es usada por la relación entre los conceptos
de tener y ser privado. Este término sería inadecuado debido a que, en una de
sus acepciones, la palabra "privado" se entiende como antónimo de "público",
es decir, que «no es de propiedad pública o estatal, sino que pertenece a par-
ticulares» , provocando que esta categoría se interpretará como no referente
al Estado, lo que produciría la exclusión del Software no libre generado por
el aparato estatal. Además, el "Software público" se asocia generalmente con
Software de dominio público.
Ante este escenario, una alternativa viable podría ser optar por el Soft-
ware Libre, aunque, pese a su incipiente desarrollo es seguro que en un futuro
podría alcanzar a suplir todas las necesidades básicas de los usuarios, dejando
la adquisición de paquetes especializados sólo para los cursos avanzados que
justi…que el uso de Software privativo.
La opción más viable, es una que conjugue las dos anteriores. Pero
además, podríamos emular Hardware del que no disponemos mediante
el uso de máquinas virtuales (véase ??) que nos permitirían en un sólo
equipo de cómputo usar simultáneamente diversos sistemas operativos
para distintas arquitecturas y sus respectivos programas que ahora es
posible instalar en las máquinas virtuales programas de cómputo in-
compatibles de forma aislada unos de otros.
De tal forma que sea posible instalar cada versión de Software solicitada en la
plataforma adecuada, teniendo en cuenta que muchas versiones del Software
son mutuamente excluyentes para ser instaladas en una misma versión del
sistema operativo simultáneamente.
class hola {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}
$ javac hola.java
y lo ejecutamos con:
$ java hola
Asignar en una variable otra variable con tipo de dato diferente: es decir
si tengo una variable String y su valor lo asigno en una variable de tipo
int, en este caso el compilador me va dar un error de conversión de tipos
y esto no va dejar que la aplicación compile, incluso un error parecido
se puede dar en variables de grupos del mismo tipo, por ejemplo asignar
el valor de un tipo int en un tipo short.
Olvidar que los índices en Java empiezan en 0, los índices de los arreglos
de Java y las listas empiezan en 0, myArray[0], o myList.get(0). Asegu-
rarse que su loop for no cause errores por este motivo. Si hacemos más
loops de los que son posibles, entonces obtendremos el error: ArrayIn-
dexOutBounds exception. Si hacemos menos loops de los requeridos,
entonces tendremos un error de lógica.
Errores lógicos Estos son los más difíciles de detectar y corregir y pues
bueno porque digo que son difíciles, es que con este tipo de errores la apli-
cación compila y se ejecuta de forma normal, pero, y entonces dónde está el
error? El error se da porque la aplicación no muestra los resultados espera-
dos digamos que ya hice el algoritmo y el resultado que debo obtener es 10,
pero en la aplicación obtengo 5 o lo peor de todo que de seguro te a pasado,
que escribes el código haces pruebas y los resultados son correctos subes a
producción y resulta que para un caso particular no se obtuvo el resultado
esperado. Pues en estos casos el problema son errores lógicos que a …n de
cuentas estos ocurren por el mal diseño del algoritmo de la aplicación
Para terminar también mencionar que otro error de tipo lógico también
ocurre cuando colocamos punto y coma después de una sentencia if o for y
aunque parezcan errores tan obvios, se dan cuando estamos empezando a
programar.
Por ello, estos son algunos consejos del buen programador:
Tener muy cuenta las divisiones por cero, en cuanto a los arreglos no
acceder a posiciones que no existen.
la aplicación.
Cuando diseñemos un algoritmo tener en cuenta todos los escenarios
posibles que pueda tomar la aplicación durante su ejecución.
Finalmente como dice el dicho divide y vencerás: una buena forma de
contrarrestar los errores de tipo lógico es dividir algoritmos grandes y
complejos en tareas pequeñas de forma que el código se más legible y
cualquier error de tipo lógico se lo pueda depurar fácilmente.
Esta es una lista muy pequeña de los errores más comunes que se pueden
presentar cuando se trabaja con un programa modular.
$ python2 hola.py
Ejemplo en Python 3:
$ python3 hola.py
MapSize = "34x44"
mapsize = "22x34"
Indentación incorrecta
Hay que tener cuidado a la hora de escribir las rutas para encontrar
tus datos. La barra que entiende Python es / ó nn (en esta posición n
posee otro signi…cado para este lenguaje de programación).
Los espacios como guión bajo. Hay ocasiones que escribimos las car-
petas con espacios o recibimos datos que los incluye, es una mala cos-
tumbre al trabajar. A la hora de escribir tenemos que tenerlo muy en
cuenta y poner dicho guión bajo.
Olvidar poner los ":"al …nal de las sentencias tipo: try, if, elif, else, for,
while, class, o def.
print("Hola"
pint("Hola")
l = []
l.pop()
l = []
if len(l) > 0:
l.pop()
13 Bibliografía
Este texto es una recopilación de múltiples fuentes, nues-
tra aportación — si es que podemos llamarla así— es
plasmarlo en este documento, en el que tratamos de dar
coherencia a nuestra visión de los temas desarrollados.
En la realización de este texto se han revisado — en
la mayoría de los casos indicamos la referencia, pero
pudimos omitir varias de ellas, por lo cual pedimos una
disculpa— múltiples páginas Web, artículos técnicos, li-
bros, entre otros materiales bibliográ…cos, los más repre-
sentativos y de libre acceso los ponemos a su disposición
en la siguiente liga:
Herramientas
Referencias
[1] Carreras en la Facultad de Ciencias, UNAM,
http://www.fciencias.unam.mx/licenciatura/resumen/
[3] http://es.wikipedia.org/wiki/Microsoft_Windows
[4] http://es.wikipedia.org/wiki/Linux
[5] http://es.wikipedia.org/wiki/Mac_OS
[6] http://es.wikipedia.org/wiki/Android
[7] https://es.wikipedia.org/wiki/Java_(lenguaje_de_programaci%C3%B3n)
28, 140
[9] https://es.wikipedia.org/wiki/C_(lenguaje_de_programaci%C3%B3n)
28, 148
[22] FreeMat, FreeMat Open Source for rapid engineering and scienti…c pro-
totyping and data processing, http://freemat.sourceforge.net/ 224, 248
[47] Suite de código abierto con más de 700 paquetes para el desarrollo de la
ciencia de datos con Python, https://www.anaconda.com/ 248
[52] M.B. Allen III, I. Herrera & G. F. Pinder; Numerical Modeling in Science
And Engineering. John Wiley & Sons, Inc . 1988. 338, 340, 341
[54] S. Friedberg, A. Insel, and L. Spence; Linear Algebra, 4th Edition, Pren-
tice Hall, Inc. 2003. 338
[55] Y. Saad; Iterative Methods for Sparse Linear Systems. SIAM, 2 ed. 2000.
329, 331, 333, 338, 340, 341
[61] C.T. Keller, Iterative Methods for Linear and Nonlinear Equations, So-
ciete for Industrial and Applied Mathematics, 1995. 341, 344
[65] S.J. Pennycook, S.D. Hammond, S.A. Jarvis and G.R. Mudalige, Per-
formance Analysis of a Hybrid MPI/CUDA Implementation of the NAS-
LU Benchmark. ACM SIGMETRICS Perform. Eval. Rev. 38 (4). ISSN
0163-5999, (2011). 297
[73] Hyper-V,
https://msdn.microsoft.com/es-es/library/mt16937(v=ws.11).aspx