```python
from sympy import *
init_printing(use_unicode=True)
```


```python
from typing import List, Dict
```

# Guía 1


```python
def coordenadas_de_un_vector_respecto_a_una_base_B(v: Matrix, coordenadas: Dict[Symbol, Matrix]):
    '''
    Devuelve las coordenadas de un vector respecto de una base B = {v1, v2, ..., vn}
    
    v: Es un vector escrito con símbolos (v1, v2, etc)
    coordenadas: es un diccionario que indica cómo traducir cada vector en coordenadas de la base B
    
    Ejemplo de un ejercicio completo:
    v1, v2, v3 = symbols('v1 v2 v3')

    B = [v1, v2, v3]

    coordenadas = {
        v1: Matrix([1, 0, 0]),
        v2: Matrix([0, 1, 0]),
        v3: Matrix([0, 0, 1]),
    }

    w1 = 0*v1 + 0*v2 + 0*v3
    w2 = v1 - v2
    w3 = 2*v2 - v3

    w2_B = coordenadas_de_un_vector_respecto_a_una_base_B(w2, coordenadas)
    w3_B = coordenadas_de_un_vector_respecto_a_una_base_B(w3, coordenadas)

    G_B = Matrix([[60, 30, 20], [30, 20, 15], [20, 15, 12]])

    G = matriz_de_gram(producto_interno_por_definicion, G_B, w2_B, w3_B)
    
    area_de_un_triangulo(G)
    '''
    w = v
    for vector in coordenadas:
        w = w.subs(vector, coordenadas[vector])
    return w

def encontrar_a(B: List[Matrix], a: Symbol):
    ''' MATRICES CUADRADAS
    Halla el o los valores que puede tener a para que la base dada sea una base efectivamente
    (para que los vectores sean linealmente independientes)
    
    Ejemplo:
    a = Symbol('a')
    B = [Matrix([a, 1, 2]), Matrix([3, 2, 3]), Matrix([1, -a, 1])]
    encontrar_a(B, a)
    '''
    return solve(det(Matrix.hstack(*B)), a)

def algoritmo_espacio_columna(S: List[Matrix]):
    '''
    Encuentra el espacio columna de un subespacio
    Devuelve una tupla con una lista de los vectores que generan el espacio columna 
    y los índices de los pivotes.
    
    S: es una lista de los vectores que generan al subespacio S
    '''
    B_S = Matrix.hstack(*S)
    _, pivotes_S = B_S.rref()
    S_li = []
    for pivote in pivotes_S:
        S_li.append(S[pivote])
    return S_li, pivotes_S

def dos_subespacios_generan_el_mismo_subespacio(S1: List[Matrix], S2: List[Matrix]):
    '''
    Verifica si dos subespacios son el mismo subespacio devolviendo True para ese 
    caso y False en caso contrario.
    
    Ejemplo:
    S1 = [Matrix([-4, -5, -3]), Matrix([26, 41, 23])]
    bien = [Matrix([11, 18, 10]), Matrix([15, 23, 13])]
    mal_1 = [Matrix([-3, 10, 8]), Matrix([-6, 11, 10])]
    mal_2 = [Matrix([7, 12, 2]), Matrix([9, 14, 1])]
    mal_3 = [Matrix([7, 2, 12]), Matrix([9, 1, 14]), 2 * Matrix([9, 1, 14])]

    dos_subespacios_generan_el_mismo_subespacio(S1, bien), dos_subespacios_generan_el_mismo_subespacio(S1, mal_1), dos_subespacios_generan_el_mismo_subespacio(S1, mal_2), dos_subespacios_generan_el_mismo_subespacio(S1, mal_3)
    '''
    S1_li, pivotes_S1 = algoritmo_espacio_columna(S1)
    S2_li, pivotes_S2 = algoritmo_espacio_columna(S2)
    
    B_S1_li = Matrix.hstack(*S1_li)
    B_S2_li = Matrix.hstack(*S2_li)
    
    B = Matrix.hstack(B_S1_li, B_S2_li)
    _, pivotes_B = B.rref()
    
    return len(pivotes_B) == len(pivotes_S1) and len(pivotes_B) == len(pivotes_S2)

''' OBTENER LOS 4 FANTÁSTICOS
A.nullspace() -> devuelve el espacio nulo de A 
A.columnspace() -> devuelve el espacio columna de A
A.T.columnspace() -> devuelve el espacio columna de A traspuesta
A.T.nullspace() -> devuelve el espacio nulo de A de a traspuesta
'''

#Función que calcula el Wronskiano 
#(existe wronskian() directamente de sympy, pero no devuelve la matriz wronskiana, sino sólo el valor del wronskiano)

def Wronskiano(B, x, return_matrix = True):
    """
    Calcula el Wronskiano del conjunto de funciones
    contenidas en B en función de la variable x.
    
    Args:
        B (lista de funciones):
            El conjunto de funciones sobre el cual 
            calcular el Wronskiano en función de la
            variable x.
        x (objeto tipo Symbol):
            Variable independiente.
        return_matrix (bool, opcional):
            Si es cierto, devuelve la matriz Wronskiana
            además del Wronskiano.
            
    Returns:
        w (función):
            Wronskiano del conjunto B.
        W (objeto tipo Matrix, opcional):
            Si return_matrix es True, devuelve la matriz
            wronskiana.
            
    Ejemplo:
    #Para ver si un conjunto es linealmente independiente en su correspondiente espacio vectorial, podemos emplear el Wronskiano.
    x = Symbol('x') # Definición de la variable simbólica
    F = [1, sinh(x), cosh(x)] #Conjunto de funciones

    W, M_W = Wronskiano(F,x,return_matrix=True) #W es el Wronskiano, M_W es la matriz wronskiana
    print('La matriz wronskiana es: '); display(M_W)
    print('y el Wronskiano resulta: '); display(W)

    #W.subs(x,0) #Si quisiera evaluar el Wronskiano en algún valor de x, por ejemplo en este caso x=0
    """

    n = len(B) # Cantidad de vectores

    # Calculo la matrix wronskiana
    W = zeros(n,n)
    for i in range(n):
        for j, f in enumerate(B):
            W[i,j] = diff(f,x,i)
            
    if return_matrix:
        return W.det(), W
    
    return W.det()
```




    ' OBTENER LOS 4 FANTÁSTICOS\nA.nullspace() -> devuelve el espacio nulo de A \nA.columnspace() -> devuelve el espacio columna de A\nA.T.columnspace() -> devuelve el espacio columna de A traspuesta\nA.T.nullspace() -> devuelve el espacio nulo de A de a traspuesta\n'



# Guía 2


```python
def matriz_de_transformacion_lineal(B: List[Matrix], img_B: List[Matrix]):
    '''
    Halla la matriz de una transformación lineal T
    Si T(x) = A * x, esta función encuentra A dada una base B y la imágen
    por T de esa base B, es decir T(B).
    
    B: es una lista de vectores que conforman la base B
    img_B: es una lista de vectores que corresponden a las imágenes de los vectores de la base B
    
    Ejemplo:
    B = Matrix([[2, 2, 1], [1, -2, 2], [-2, 1, 2]])
    img_B = Matrix([[0, -1, -1], [1, 0, -1], [1, 0, -1], [1, 1, 0]])
    y = Matrix([2, 5, 5, 3])
    '''
    return Matrix.hstack(*img_B) * Matrix.hstack(*B).inv()

def imagen_por_T_de_un_subespacio(B: List[Matrix], img_B: List[Matrix], S: List[Matrix]):
    '''
    Halla la imágen por T de un subespacio S dada una base B y la imágen por T de B
    
    B: es una lista de vectores que conforman la base B
    img_B: es una lista de vectores que corresponden a las imágenes de los vectores de la base B
    S: es una lista de vectores que generan el subespacio S
    '''
    img_S = matriz_de_transformacion_lineal(B, img_B) * Matrix.hstack(*S)
    return img_S

def preimagen_subespacio(B,img_B,Au):
    """
    Dada una transformación lineal definida por una base B y las imágenes img_B 
    de cada uno de los vectores de B, la función devuelve una base del subespacio
    T^(-1)(U), donde U = Nul(Au).
    """
    B_matrix = Matrix.hstack(*B)
    Eb, pivots = B_matrix.rref(pivots=True)

    img_B_matrix = Matrix.hstack(*img_B)
    sol = (Au * img_B_matrix).nullspace()
    B_T_inv_U = [B_matrix * v for v in sol]
    return B_T_inv_U

# TODO: EN CONSTRUCCIÓN
def nucleo_de_operador_diferencial(L):
    '''
    '''
    x = Symbol('x')
    Nu_L = set()
    raices = str(L).split('*')
    for raiz in raices:
        try:
            l = -int(raiz[raiz.index('-')+1])
        except:
            l = int(raiz[raiz.index('+')+1])
        
        if '**' in raiz:   
            k = int(raiz.split('**')[1])
        else:
            k = 1
            
        for i in range(k):
            Nu_L.add((x**(i))*exp(-l*x))
    return Nu_L

def solucion_particular(Nu_L, Nu_A):
    Nu_AL = Nu_L | Nu_A
    yp_expr = ''
    for i, e in enumerate(Nu_AL - Nu_L):
        yp_expr += f'a{i+1}*{e}+'
    return yp_expr[:-1]

D, I = symbols('D I')
L = (D-2*I)*(D-4*I)*(D+3*I)**2

Nu_L = nucleo_de_operador_diferencial(L)
Nu_A = nucleo_de_operador_diferencial('(D+3I)^6')

solucion_particular(Nu_L, Nu_A)
```

# Guía 3

## Productos Internos


```python
'''
Para los productos internos en general

A: es una matriz
B: es una matriz armada con los vectores que conforman una base B

x, y: son vectores
G: es la matriz de Gram
'''

def producto_interno_matrices_3_x_3(A: Matrix, B: Matrix, G: Matrix=None):
    return 1/2 * (B.T * A).trace()

def producto_interno_por_definicion(x: Matrix, y: Matrix, G: Matrix):
    return (y.T * G * x)[0]

def producto_interno_polinomios_integral(p, q, x, limite_inferior=0, limite_superior=1, a=1):
    return integrate(p * q * a, (x, limite_inferior, limite_superior))

def producto_interno_canonico(x, y, G):
    return (y.T * x)[0]
```

## Matriz de Gram


```python
def matriz_de_gram(producto_interno, G_B, *vectores_ordenados):
    '''
    Dado un producto interno, una matriz de Gram que define ese producto interno (si es de matrices
    enviar cualquier cosa) y una lista de vectores ordenados devuelve la matriz de Gram de esos vectores
    
    producto_interno: es el nombre de una función definida
    G_B: es la matriz de Gram del producto interno
    *vectores_ordenados: es una lista de vectores que se tienen que mandar ordenados
    
    Ejemplo:
    
    '''
    G = eye(len(vectores_ordenados))
    for i in range(len(vectores_ordenados)):
        for j, vector in enumerate(vectores_ordenados):
            G[i,j] = producto_interno(vectores_ordenados[i], vectores_ordenados[j], G_B)
    
    return G



```

## Norma, Ángulo y Distancia


```python
def norma(x, producto_interno, G):
    '''
    Dado un vector, una matriz de producto interno y un producto interno, se computa la norma de dicho vector.
    
    x, y: son vectores
    producto_interno: es el nombre de una función definida
    G_B: es la matriz de Gram del producto interno
    '''
    return sqrt(producto_interno(x, x, G))

def angulo(x: Matrix, y: Matrix, G: Matrix, producto_interno):
    '''
    Dados dos vectores, una matriz de producto interno y un producto interno, se computa el ángulo entre
    dichos vectores.
    
    x, y: son vectores
    producto_interno: es el nombre de una función definida
    G_B: es la matriz de Gram del producto interno
    '''
    return acos(producto_interno(x, y, G) / (norma(x, producto_interno, G) * norma(y, producto_interno, G)))

def distancia_de_un_vector_a_un_subespacio(v, B, G, producto_interno):
    '''AGARRAR CON PINZAS'''
    _v_tilda = v_tilda(v, B, eye(4), producto_interno)
    return sqrt(producto_interno(v, v, G) - (_v_tilda.T * G.inv() * _v_tilda)[0])
```

## Áreas (triángulo y paralelogramo)


```python
def area_de_un_paralelogramo(G: Matrix):
    '''
    Computa el área de un paralelogramo dada una matriz de Gram de los vértices de dicho triángulo
    
    G: es la matriz de Gram de los vectores que forman el paralelogramo cuya área se quiere calcular
    '''
    return G.det()

def area_de_un_triangulo(G: Matrix):
    '''
    Computa el área de un triángulo dada una matriz de Gram de los vértices de dicho triángulo
    
    G: es la matriz de Gram de los vectores que forman el triángulo cuya área se quiere calcular
    '''
    return 1/2 * sqrt(area_de_un_paralelogramo(G))

def resolver_area_de_un_triangulo_en_el_origen(G_B: Matrix, v1: Matrix, v2: Matrix, producto_interno):
    '''
    Calcula el área del triángulo de vértices v1 y v2 (siendo nunguno el vector nulo)
    
    Ejemplo:
    v1 = Matrix([1, 1, 0])
    v2 = Matrix([1, 0, 1])
    G_B = Matrix([[1, 1, 1], [1, 2, 2], [1, 2, 3]])
    resolver_area_de_un_triangulo_con_uno_de_los_vertices_en_el_origen(G_B, v1, v2, producto_interno_por_definicion)
    '''
    G_v1_v2 = matriz_de_gram(producto_interno, G_B, v1, v2)
    return area_de_un_triangulo(G_v1_v2)
   
def resolver_area_de_un_triangulo_corrido_del_origen(G_B: Matrix, v1: Matrix, v2: Matrix, v3: Matrix, producto_interno):
    '''
    Calcula el área del triángulo de vértices v1, v2, y v3 (siendo nunguno el vector nulo)
    
    Ejemplo:
    v1 = Matrix([3, 1, 2])
    v2 = Matrix([4, 2, 2])
    v3 = Matrix([4, 1, 3])
    G_B = Matrix([[1, 1, 1], [1, 2, 2], [1, 2, 3]])
    resolver_area_de_un_triangulo_con_uno_de_los_vertices_en_el_origen(G_B, v1, v2, v3, producto_interno_por_definicion)
    '''
    w1, w2, w3 = v1-v1, v2-v1, v3-v1
    G_w2_w3 = matriz_de_gram(producto_interno, G_B, w2, w3)
    return area_de_un_triangulo(G_v1_v2)
```

## Proyecciones y Simetrías


```python
def v_tilda(x: Matrix, B: List[Matrix], G: Matrix, producto_interno):
    return Matrix([producto_interno(x, B[i], G) for i in range(len(B))])

def proyeccion_ortogonal_de_un_vector_a_un_subespacio(x: Matrix, B: list, G: Matrix, producto_interno):
    return G.inv() * v_tilda(x, B, G, producto_interno)

def matriz_de_proyeccion_sobre_S1_en_direccion_de_S2_en_coordenadas_canonicas(S1: List[Matrix], S2: List[Matrix]):
    '''
    Arma la matriz de proyección sobre un subespacio S1 en dirección de otro subespacio S2 en coordenadas
    canónicas dadas dos listas con vectores generadores de cada subespacio en particular.
    
    S1: lista de vectores que generan al subespacio S1 (sobre el que se quiere proyectar)
    S1: lista de vectores que generan al subespacio S2 (la dirección)
    '''
    B_S1 = Matrix.hstack(*S1)
    B_S2 = Matrix.hstack(*S2)
    B = Matrix.hstack(B_S1, B_S2)
    
    P_BB = eye(B.rank())
    for i in range(B_S1.rank(), B_S1.rank()-1, -1):
        P_BB[i, i] = 0
        
    return B * P_BB * B.inv()

def matriz_de_simetria_sobre_S1_en_direccion_de_S2_en_coordenadas_canonicas(S1: List[Matrix], S2: List[Matrix]):
    '''
    Arma la matriz de simetríá sobre un subespacio S1 en dirección de otro subespacio S2 en coordenadas
    canónicas dadas dos listas con vectores generadores de cada subespacio en particular.
    
    S1: lista de vectores que generan al subespacio S1 (sobre el que se quiere hacer la simetría)
    S1: lista de vectores que generan al subespacio S2 (la dirección)
    '''
    B_S1 = Matrix.hstack(*S1)
    B_S2 = Matrix.hstack(*S2)
    B = Matrix.hstack(B_S1, B_S2)
    
    S_BB = eye(B.rank())
    for i in range(B_S1.rank(), B_S1.rank()-1, -1):
        S_BB[i, i] = -1
        
    return B * S_BB * B.inv()
```

## QR


```python
'''
Q, R = A.QRDecomposition()
'''
```

54bb2b09026df613fe00672b6bd6cf218f1cdba8
ipynb
Jupyter Notebook
notebooks_varios/Funciones para ejercicios de guias 1-3.ipynb
ilitteri/manim-algebra-notebooks
d57461de498ca574e7d866dae1d091a2c5a6880a
MIT
2021-11-12T21:23:35.000Z
2022-02-27T14:43:48.000Z
notebooks_varios/Funciones para ejercicios de guias 1-3.ipynb
ilitteri/manim-algebra-notebooks
d57461de498ca574e7d866dae1d091a2c5a6880a
MIT
notebooks_varios/Funciones para ejercicios de guias 1-3.ipynb
ilitteri/manim-algebra-notebooks
d57461de498ca574e7d866dae1d091a2c5a6880a
MIT
2021-11-12T18:24:56.000Z
2021-11-12T18:24:56.000Z
Qwen/Qwen-72B
1. YES
2. YES