1 Introducción

Este notebook está organizado en los fundamentos (teoría de conjuntos, axiomas de los números reales e inducción matemática, siguiendo la Parte 2, Parte 3 y Parte 4 de Apostol) Cada paso tiene una breve explicación en texto antes del código.


2 Parte. Conceptos básicos de la teoría de conjuntos

2.1 Introducción a la teoría de conjuntos

Un conjunto es una colección de objetos, llamados elementos. En R podemos representar conjuntos con vectores, teniendo cuidado de no repetir elementos.

Paso 1: Creamos un conjunto en R

A <- c(1, 2, 3, 4, 5)
A
## [1] 1 2 3 4 5

Paso 2: Verificamos si un elemento pertenece al conjunto (relación de pertenencia)

3 %in% A
## [1] TRUE
8 %in% A
## [1] FALSE

2.2 Notaciones para designar conjuntos

Un conjunto puede describirse por extensión (listando sus elementos) o por comprensión (una regla que cumplen sus elementos), por ejemplo \(B = \{x : x \text{ es par}, 1 \le x \le 20\}\).

Paso 1: Definimos el conjunto por extensión

B_extension <- c(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)
B_extension
##  [1]  2  4  6  8 10 12 14 16 18 20

Paso 2: Definimos el mismo conjunto por comprensión usando una condición lógica

x <- 1:20
B_comprension <- x[x %% 2 == 0]
B_comprension
##  [1]  2  4  6  8 10 12 14 16 18 20

Paso 3: Comprobamos que ambas formas generan el mismo conjunto

identical(B_extension, B_comprension)
## [1] FALSE

2.3 Subconjuntos

Un conjunto \(C\) es subconjunto de \(D\) si todo elemento de \(C\) también pertenece a \(D\), lo que se denota \(C \subseteq D\).

Paso 1: Definimos dos conjuntos

C <- c(2, 4, 6)
D <- c(1, 2, 3, 4, 5, 6, 7)

Paso 2: Verificamos si C es subconjunto de D

es_subconjunto <- all(C %in% D)
es_subconjunto
## [1] TRUE

Paso 3: Verificamos la igualdad de conjuntos (doble contención)

E <- c(6, 4, 2) # mismos elementos que C, distinto orden
son_iguales <- setequal(C, E)
son_iguales
## [1] TRUE

2.4 Reuniones, intersecciones, complementos

Paso 1: Definimos dos conjuntos de trabajo

conjunto_F <- c(1, 2, 3, 4, 5)
conjunto_G <- c(4, 5, 6, 7, 8)

Paso 2: Calculamos la union (reunión) F ∪ G

union_FG <- union(conjunto_F, conjunto_G)
union_FG
## [1] 1 2 3 4 5 6 7 8

Paso 3: Calculamos la intersección F ∩ G

interseccion_FG <- intersect(conjunto_F, conjunto_G)
interseccion_FG
## [1] 4 5

Paso 4: Calculamos el complemento de F respecto a un conjunto universal U

U <- 1:10
complemento_F <- setdiff(U, conjunto_F)
complemento_F
## [1]  6  7  8  9 10

Paso 5: Calculamos la diferencia de conjuntos F - G

diferencia_FG <- setdiff(conjunto_F, conjunto_G)
diferencia_FG
## [1] 1 2 3

2.5 Ejercicios

2.5.1 Ejercicio: Verificar las leyes de De Morgan

Las leyes de De Morgan afirman que \((F \cup G)^c = F^c \cap G^c\) y \((F \cap G)^c = F^c \cup G^c\).

Paso 1: Calculamos el lado izquierdo de la primera ley

lado_izq1 <- setdiff(U, union(conjunto_F, conjunto_G))
lado_izq1
## [1]  9 10

Paso 2: Calculamos el lado derecho de la primera ley

lado_der1 <- intersect(setdiff(U, conjunto_F), setdiff(U, conjunto_G))
lado_der1
## [1]  9 10

Paso 3: Comparamos ambos resultados

setequal(lado_izq1, lado_der1)
## [1] TRUE

3 Parte. Un conjunto de axiomas para el sistema de números reales

3.1 Introducción

El sistema de los números reales se construye a partir de un conjunto de axiomas: axiomas de cuerpo, axiomas de orden y el axioma del extremo superior. En esta sección ilustramos cada axioma con ejemplos numericos en R.

3.2 Axiomas de cuerpo

Los axiomas de cuerpo garantizan que la suma y el producto de números reales cumplen propiedades como conmutatividad, asociatividad, existencia de elemento neutro e inverso, y distributividad.

Paso 1: Verificamos la propiedad conmutativa de la suma y el producto

a <- 3.5
b <- 7.2
c(a + b == b + a, a * b == b * a)
## [1] TRUE TRUE

Paso 2: Verificamos la propiedad asociativa

c <- 2.1
c((a + b) + c == a + (b + c), (a * b) * c == a * (b * c))
## [1] FALSE  TRUE

Paso 3: Verificamos la existencia del elemento neutro (0 para la suma, 1 para el producto)

c(a + 0 == a, a * 1 == a)
## [1] TRUE TRUE

Paso 4: Verificamos la existencia del inverso aditivo y multiplicativo

c(a + (-a) == 0, a * (1/a) == 1)
## [1] TRUE TRUE

Paso 5: Verificamos la propiedad distributiva

a * (b + c) == a*b + a*c
## [1] FALSE

3.3 Ejercicios

3.3.1 Ejercicio: Comprobar la ley de cancelación

Si \(a + c = b + c\) entonces \(a = b\).

Paso 1: Definimos valores y verificamos la hipotesis

a <- 5
b <- 5
c <- 3.7
(a + c) == (b + c)
## [1] TRUE

Paso 2: Confirmamos la conclusión

a == b
## [1] TRUE

3.4 Axiomas de orden

El orden de los números reales cumple tricotomia (dado a y b, se tiene a<b, a=b o a>b), transitividad, y compatibilidad con la suma y el producto por positivos.

Paso 1: Verificamos la ley de tricotomia

comparar <- function(x, y) {
  if (x < y) "x < y" else if (x > y) "x > y" else "x = y"
}
comparar(4, 7)
## [1] "x < y"

Paso 2: Verificamos la transitividad (si a<b y b<c, entonces a<c)

a <- 2; b <- 5; c <- 9
(a < b) & (b < c) & (a < c)
## [1] TRUE

Paso 3: Verificamos que el orden se preserva al sumar la misma cantidad

k <- 10
(a < b) == (a + k < b + k)
## [1] TRUE

Paso 4: Verificamos que el orden se preserva al multiplicar por un positivo, y se invierte al multiplicar por un negativo

m_pos <- 3
m_neg <- -3
c((a < b) == (a*m_pos < b*m_pos), (a < b) == (a*m_neg > b*m_neg))
## [1] TRUE TRUE

3.5 Ejercicios

3.5.1 Ejercicio: Resolver una desigualdad

Resolver \(2x - 3 < 7\).

Paso 1: Definimos la desigualdad como función

desigualdad <- function(x) 2*x - 3 < 7

Paso 2: Probamos varios valores para verificar la solución x < 5

valores_prueba <- c(3, 4, 4.9, 5, 5.1, 6)
data.frame(x = valores_prueba, cumple = desigualdad(valores_prueba))
##     x cumple
## 1 3.0   TRUE
## 2 4.0   TRUE
## 3 4.9   TRUE
## 4 5.0  FALSE
## 5 5.1  FALSE
## 6 6.0  FALSE

3.6 Numeros enteros y racionales

Paso 1: Verificamos si un número es entero en R

valores <- c(4, 4.5, -3, 0, 7/2)
son_enteros <- valores == floor(valores)
data.frame(valor = valores, es_entero = son_enteros)
##   valor es_entero
## 1   4.0      TRUE
## 2   4.5     FALSE
## 3  -3.0      TRUE
## 4   0.0      TRUE
## 5   3.5     FALSE

Paso 2: Representamos un número racional como fracción p/q usando la libreria pracma

racional <- 0.75
fraccion <- pracma::rats(racional)
## 3/4
fraccion
## [1] 0.75

3.7 Interpretación geométrica de los números reales como puntos de una recta

Paso 1: Ubicamos varios números reales en la recta numérica

puntos <- c(-3, -1.5, 0, 2, 4.7)
puntos
## [1] -3.0 -1.5  0.0  2.0  4.7

Paso 2: Graficamos estos puntos sobre una recta numérica

plot(puntos, rep(0, length(puntos)), pch = 19, col = "blue",
     yaxt = "n", ylab = "", xlab = "Recta real",
     main = "Interpretación geométrica de los números reales")
abline(h = 0)
text(puntos, 0.05, labels = puntos)


3.8 Cota superior de un conjunto, elemento máximo, extremo superior

Paso 1: Definimos un conjunto acotado superiormente

conjunto_H <- c(1, 2, 3, 3.5, 3.9)

Paso 2: Verificamos que un valor es cota superior (mayor o igual a todos los elementos)

cota_candidata <- 4
es_cota_superior <- all(conjunto_H <= cota_candidata)
es_cota_superior
## [1] TRUE

Paso 3: Calculamos el extremo superior (supremo), que en este caso coincide con el máximo

supremo <- max(conjunto_H)
supremo
## [1] 3.9

3.9 Axioma del extremo superior (axioma de completitud)

Este axioma garantiza que todo conjunto no vacío de números reales acotado superiormente tiene un extremo superior (supremo), aunque dicho supremo no siempre sea alcanzado por el conjunto.

Paso 1: Ilustramos un conjunto cuyo supremo no pertenece al conjunto: valores de 1 - 1/n

n <- 1:20
conjunto_I <- 1 - 1/n
conjunto_I
##  [1] 0.0000000 0.5000000 0.6666667 0.7500000 0.8000000 0.8333333 0.8571429
##  [8] 0.8750000 0.8888889 0.9000000 0.9090909 0.9166667 0.9230769 0.9285714
## [15] 0.9333333 0.9375000 0.9411765 0.9444444 0.9473684 0.9500000

Paso 2: El supremo teórico de este conjunto es 1, aunque ningun elemento lo alcanza

max(conjunto_I) < 1
## [1] TRUE
supremo_teorico <- 1
supremo_teorico
## [1] 1

Paso 3: Graficamos como los elementos se acercan al supremo sin alcanzarlo

plot(n, conjunto_I, type = "b", col = "darkred",
     main = "Elementos acercandose al supremo (1 - 1/n)",
     xlab = "n", ylab = "1 - 1/n")
abline(h = 1, lty = 2, col = "blue")


3.10 La propiedad arquimediana del sistema de los números reales

La propiedad arquimediana establece que para todo número real \(x\), existe un número natural \(n\) tal que \(n > x\).

Paso 1: Definimos un número real grande

x_real <- 1000000.5

Paso 2: Buscamos un número natural que lo supere

n_natural <- ceiling(x_real) + 1
n_natural > x_real
## [1] TRUE

3.11 Propiedades fundamentales del extremo superior

Paso 1: Verificamos que el supremo de la union de dos conjuntos es el máximo de los supremos individuales

conjunto_J <- c(1, 2, 3)
conjunto_K <- c(2, 4, 5)
sup_J <- max(conjunto_J)
sup_K <- max(conjunto_K)
sup_union <- max(union(conjunto_J, conjunto_K))
c(sup_J, sup_K, sup_union, max(sup_J, sup_K) == sup_union)
## [1] 3 5 5 1

3.12 Ejercicios

3.12.1 Ejercicio: Determinar el supremo e infimo de un conjunto

Sea el conjunto \(L = \{x : 2 < x \le 6\}\).

Paso 1: Generamos una muestra densa de puntos del conjunto

L <- seq(2.0001, 6, by = 0.0001)

Paso 2: Calculamos el supremo (que si pertenece al conjunto) y el infimo (que no pertenece)

supremo_L <- max(L)
infimo_L <- min(L)
c(supremo_L = supremo_L, infimo_L = infimo_L)
## supremo_L  infimo_L 
##    6.0000    2.0001

3.13 Existencia de raíces cuadradas de números reales no negativos

Paso 1: Calculamos la raíz cuadrada de un número no negativo

numero <- 7
raiz <- sqrt(numero)
raiz
## [1] 2.645751

Paso 2: Verificamos que el resultado satisface la definición (raíz^2 = número)

isTRUE(all.equal(raiz^2, numero))
## [1] TRUE

Paso 3: Aproximamos la raíz cuadrada mediante el método de Newton, paso a paso

aproximar_raiz <- function(a, iteraciones = 6) {
  x <- a / 2
  historial <- numeric(iteraciones)
  for (i in 1:iteraciones) {
    x <- (x + a/x) / 2
    historial[i] <- x
  }
  historial
}
aproximar_raiz(7)
## [1] 2.750000 2.647727 2.645752 2.645751 2.645751 2.645751

3.14 Raices de orden superior. Potencias racionales

Paso 1: Calculamos una raíz de orden superior, por ejemplo la raíz cubica

raiz_cubica <- 27^(1/3)
raiz_cubica
## [1] 3

Paso 2: Calculamos una potencia racional general, por ejemplo 8^(2/3)

potencia_racional <- 8^(2/3)
potencia_racional
## [1] 4

Paso 3: Verificamos la propiedad (a(p/q))q = a^p

a_val <- 8; p_val <- 2; q_val <- 3
lado_izq <- (a_val^(p_val/q_val))^q_val
lado_der <- a_val^p_val
isTRUE(all.equal(lado_izq, lado_der))
## [1] TRUE

3.15 Representación de los números reales por medio de decimales

Paso 1: Obtenemos la representación decimal de un número racional

fraccion_ejemplo <- 1/3
print(fraccion_ejemplo, digits = 15)
## [1] 0.333333333333333

Paso 2: Identificamos el periodo de un decimal periódico generando varios digitos

options(digits = 15)
1/7
## [1] 0.142857142857143
options(digits = 7) # restauramos el valor por defecto

Paso 3: Aproximamos un número irracional (no periódico) como Pi con muchos decimales

print(pi, digits = 15)
## [1] 3.14159265358979

4 Parte. Inducción matemática, símbolos sumatorios y cuestiones relacionadas

4.1 Ejemplo de demostración por inducción matemática

Queremos comprobar la formula \(1 + 2 + \dots + n = \frac{n(n+1)}{2}\).

Paso 1: Definimos la suma directa y la formula cerrada

suma_directa <- function(n) sum(1:n)
formula_cerrada <- function(n) n*(n+1)/2

Paso 2: Comparamos ambas para varios valores de n

n_vals <- 1:10
data.frame(n = n_vals,
           suma_directa = sapply(n_vals, suma_directa),
           formula = formula_cerrada(n_vals))
##     n suma_directa formula
## 1   1            1       1
## 2   2            3       3
## 3   3            6       6
## 4   4           10      10
## 5   5           15      15
## 6   6           21      21
## 7   7           28      28
## 8   8           36      36
## 9   9           45      45
## 10 10           55      55

4.2 El principio de la inducción matemática

El principio de inducción establece que si una proposición \(P(n)\) es verdadera para \(n=1\) (caso base), y si \(P(k)\) verdadera implica \(P(k+1)\) verdadera (paso inductivo), entonces \(P(n)\) es verdadera para todo \(n \ge 1\).

Paso 1: Verificamos el caso base de la formula de la suma

n <- 1
suma_directa(n) == formula_cerrada(n)
## [1] TRUE

Paso 2: Verificamos el paso inductivo para un valor arbitrario k

k <- 15
paso_inductivo <- (formula_cerrada(k) + (k+1)) == formula_cerrada(k+1)
paso_inductivo
## [1] TRUE

4.3 El principio de buena ordenación

Todo subconjunto no vacío de números naturales tiene un elemento mínimo.

Paso 1: Definimos un subconjunto de números naturales

subconjunto_naturales <- c(15, 3, 42, 7, 99, 3)

Paso 2: Encontramos el elemento mínimo

elemento_minimo <- min(subconjunto_naturales)
elemento_minimo
## [1] 3

4.4 Ejercicios

4.4.1 Ejercicio: Demostrar por inducción que 2^n > n para todo n >= 1

Paso 1: Verificamos el caso base

n <- 1
2^n > n
## [1] TRUE

Paso 2: Verificamos numéricamente el paso inductivo para varios valores

k_vals <- 1:20
cumple <- 2^k_vals > k_vals
data.frame(k = k_vals, cumple_desigualdad = cumple)
##     k cumple_desigualdad
## 1   1               TRUE
## 2   2               TRUE
## 3   3               TRUE
## 4   4               TRUE
## 5   5               TRUE
## 6   6               TRUE
## 7   7               TRUE
## 8   8               TRUE
## 9   9               TRUE
## 10 10               TRUE
## 11 11               TRUE
## 12 12               TRUE
## 13 13               TRUE
## 14 14               TRUE
## 15 15               TRUE
## 16 16               TRUE
## 17 17               TRUE
## 18 18               TRUE
## 19 19               TRUE
## 20 20               TRUE

4.5 Demostración del principio de buena ordenación

Paso 1: Generamos un conjunto aleatorio de números naturales

set.seed(123)
conjunto_aleatorio <- sample(1:1000, 10)
conjunto_aleatorio
##  [1] 415 463 179 526 195 938 818 118 299 229

Paso 2: Confirmamos que siempre existe un mínimo, sin importar el orden en que se presenten los elementos

min(conjunto_aleatorio)
## [1] 118

4.6 El símbolo sumatorio

Paso 1: Calculamos una suma finita usando el símbolo sumatorio (sum en R)

\[\sum_{i=1}^{5} i^2\]

suma1 <- sum((1:5)^2)
suma1
## [1] 55

Paso 2: Calculamos una suma con indice que no comienza en 1

\[\sum_{i=3}^{8} (2i - 1)\]

suma2 <- sum(2*(3:8) - 1)
suma2
## [1] 60

Paso 3: Verificamos la propiedad de linealidad del sumatorio

\[\sum_{i=1}^{n} (a_i + b_i) = \sum_{i=1}^{n} a_i + \sum_{i=1}^{n} b_i\]

a_vec <- 1:5
b_vec <- 6:10
sum(a_vec + b_vec) == sum(a_vec) + sum(b_vec)
## [1] TRUE

4.7 Ejercicios

4.7.1 Ejercicio: Calcular la suma de los cuadrados de los primeros n números

Formula: \(\sum_{i=1}^{n} i^2 = \frac{n(n+1)(2n+1)}{6}\)

Paso 1: Calculamos la suma directa para n = 10

n <- 10
suma_directa_cuadrados <- sum((1:n)^2)
suma_directa_cuadrados
## [1] 385

Paso 2: Comparamos con la formula cerrada

formula_cuadrados <- n*(n+1)*(2*n+1)/6
formula_cuadrados
## [1] 385

4.8 Valor absoluto y desigualdad triangular

La desigualdad triangular establece que \(|a + b| \le |a| + |b|\) para todo par de números reales.

Paso 1: Calculamos el valor absoluto de varios números

valores <- c(-5, 3, -2.7, 0)
abs(valores)
## [1] 5.0 3.0 2.7 0.0

Paso 2: Verificamos la desigualdad triangular con un ejemplo

a <- -4
b <- 6
c(abs(a + b), abs(a) + abs(b), abs(a + b) <= abs(a) + abs(b))
## [1]  2 10  1

Paso 3: Verificamos la desigualdad triangular para muchos pares aleatorios de números

set.seed(42)
a_rand <- runif(1000, -50, 50)
b_rand <- runif(1000, -50, 50)
todos_cumplen <- all(abs(a_rand + b_rand) <= abs(a_rand) + abs(b_rand))
todos_cumplen
## [1] TRUE

4.9 Ejercicios

4.9.1 Ejercicio: Resolver una ecuación con valor absoluto

Resolver \(|x - 3| = 5\).

Paso 1: Planteamos las dos posibles soluciones

solucion1 <- 3 + 5
solucion2 <- 3 - 5
c(solucion1, solucion2)
## [1]  8 -2

Paso 2: Verificamos ambas soluciones

c(abs(solucion1 - 3) == 5, abs(solucion2 - 3) == 5)
## [1] TRUE TRUE

4.10 Ejercicios varios referentes al método de inducción

4.10.1 Ejercicio: Demostrar que n! > 2^n para n >= 4

Paso 1: Definimos ambas funciones

factorial_vals <- function(n) factorial(n)
potencia_vals <- function(n) 2^n

Paso 2: Comparamos para varios valores de n a partir de 4

n_vals <- 4:12
data.frame(n = n_vals,
           factorial = factorial_vals(n_vals),
           potencia_2n = potencia_vals(n_vals),
           cumple = factorial_vals(n_vals) > potencia_vals(n_vals))
##    n factorial potencia_2n cumple
## 1  4        24          16   TRUE
## 2  5       120          32   TRUE
## 3  6       720          64   TRUE
## 4  7      5040         128   TRUE
## 5  8     40320         256   TRUE
## 6  9    362880         512   TRUE
## 7 10   3628800        1024   TRUE
## 8 11  39916800        2048   TRUE
## 9 12 479001600        4096   TRUE