Transformações matriciais;conceitos e teoria, existem recursos livres para aprender praticamente?[encerrado]

StackOverflow https://stackoverflow.com/questions/1016284

Pergunta

Tenho me divertido renderizando tabelas e gráficos de coordenadas ultimamente, e estou fascinado por usar matrizes para transformar espaços de coordenadas.

Consegui escalar e inverter com sucesso os espaços de coordenadas 2 dimensionais, mas agora meu apetite está aguçado.:)

Onde posso ir para obter material educativo claro, informativo, (gratuito) sobre matrizes, matemática matricial, especialmente no que se aplica ao espaço dimensional 2 e 3?

Foi útil?

Solução

Resposta Original: Não tenho certeza se você vai gostar de como os cursos de matemática normalmente introduzem matrizes.Como programador, você pode ficar mais feliz em pegar qualquer livro de gráficos 3D decente.Deve certamente ter matrizes 3x3 muito concretas.Descubra também os que lhe ensinarão transformações projetivas (a geometria projetiva é uma área muito bonita de geometria de baixa dimensão e fácil de programar).

Minicurso em matemática matricial com Python 3

Conteúdo:

  1. Matrizes [Vector, __add__, reflect_y, rotate, dilate, transform]
  2. Matrizes:Sobrecarregado [Matrix, __add__, __str__, __mul__, zero, det, inv, __pow__]
  3. Bónus:Números complexos
  4. Matrizes:A (R)evolução.Já está em construção (há um resumo no final)

Prefácio: Com base na minha experiência de ensino, penso que os cursos referenciados por outros são muito bons cursos.Isso significa que, se o seu objetivo é entender matrizes como os matemáticos fazem, você deve, por todos os meios, obter todo o curso.Mas se seus objetivos são mais modestos, aqui está minha tentativa de algo mais adaptado às suas necessidades (mas ainda escrito com o objetivo de transmitir muitos conceitos teóricos, contradizendo meu conselho original.)

Como utilizar:

  • Este post é longo.Você pode considerar imprimir isso e ir devagar, como uma parte por dia.
  • O código é essencial.Este é um curso para programadores.Os exercícios também são essenciais.
  • Você deve dê uma olhada no code companion que contém todo este código e muito mais
  • É" 2 pelo preço de 1 " especial:Você também pode aprender Python 3 aqui.E números complexos.
  • Eu valorizo muito qualquer tentativa de ler isso (eu me qualifico oficialmente para o post mais longo de todos os tempos?), portanto, sinta-se à vontade para comentar se não entender alguma coisa (e também se entender).

1.Matrizes

Vectores

Antes que as matrizes venham vetores.Você certamente sabe como lidar com os vetores de 2 e 3 dimensões:

class Vector:
    """This will be a simple 2-dimensional vector.

    In case you never encountered Python before, this string is a
    comment I can put on the definition of the class or any function.
    It's just one of many cool features of Python, so learn it here!

    """

    def __init__(self, x, y): 
        self.x = x
        self.y = y

agora você pode escrever

v = Vector(5, 3)
w = Vector(7, -1)

mas não é muito divertido por si só.Vamos adicionar métodos mais úteis:

    def __str__(self: 'vector') -> 'readable form of vector':
        return '({0}, {1})'.format(self.x, self.y)

    def __add__(self:'vector', v: 'another vector') -> 'their sum':
        return Vector(self.x + v.x, self.y + v.y)

    def __mul__(self:'vector', number: 'a real number') -> 'vector':
        '''Multiplies the vector by a number'''
        return Vector(self.x * number, self.y * number)

Isso torna as coisas mais interessantes como podemos escrever agora:

print(v + w * 2)

e obter a resposta (19, 1) bem impresso como um vetor (se os exemplos parecerem desconhecidos, pense em como esse código ficaria em C++).

Transformações

Agora é tudo legal poder escrever 1274 * w mas você precisa de mais operações vetoriais para os gráficos.Aqui estão alguns deles:você pode inverter o vetor (0,0) ponto, você pode refleti-lo em torno x ou y Eixo, você pode girá-lo no sentido horário ou anti-horário (é uma boa ideia desenhar uma imagem aqui).

Vamos fazer algumas operações simples:

    ...

    def flip(self:'vector') -> 'vector flipped around 0':
        return Vector(-self.x, -self.y)

    def reflect_x(self:'vector') -> 'vector reflected around x axis':
        return Vector(self.x, -self.y)


print(v.flip(), v.reflect_x())
  • Pergunta: é possível expressar flip(...) usando as operações que eu tinha abaixo?Que tal reflect_x?

Agora você pode se perguntar Por Que Eu omiti reflect_y.Bem, é porque quero que pares por um momento e escrevas a tua própria versão.Ok, aqui está o meu:

    def reflect_y(self:'vector') -> 'vector reflected around y axis':
        return self.flip().reflect_x()

Veja, se você olhar como esta função calcula, é realmente bastante trivial.Mas de repente uma coisa incrível aconteceu:Consegui escrever uma transformação usando apenas as transformações existentes flip e reflect_x.Por tudo o que me interessa, reflect_y pode ser definido em uma classe derivada sem acesso a x e y e ainda funcionaria!

Os matemáticos chamariam essas funções operadores.Eles diriam que reflect_y é um operador obtido por composição dos operadores flip e reflect_x que é denotado por reflect_y = flip ○ reflect_x (você deve ver o pequeno círculo, um símbolo Unicode 25CB).

  • Nota: Utilizarei livremente o = símbolo a partir de agora para indicar que duas operações produzem o mesmo resultado, como no parágrafo acima.Trata-se de uma " matemática =", que não pode ser expresso como um programa.

Então, se eu fizer

print(v.reflect_y())

Eu recebo o resultado (-5, 3).Vá e imagine!

  • Pergunta: Considere uma composição reflect_y ◦ reflect_y.Como o nomearia?

Rotações

Essas operações foram boas e úteis, mas provavelmente estão a perguntar-se porque é que demoramos a introduzir rotações.Ok, aqui vou eu:

    def rotate(self:'vector', angle:'rotation angle') -> 'vector':
        ??????

Neste ponto, se souber rodar Vectores, deverá continuar a preencher os pontos de interrogação.Caso contrário, por favor, tenha paciência comigo para mais um caso simples:rotação no sentido anti-horário por 90 graus.Este não é difícil de desenhar num pedaço de papel:

    def rotate_90(self:'vector') -> 'rotated vector':
        new_x = - self.y
        new_y =   self.x
        return Vector(new_x, new_y)

Tentando

x_axis = Vector(1, 0)
y_axis = Vector(0, 1)

print(x_axis.rotate_90(), y_axis.rotate_90())

agora dá (0, 1) (-1, 0).Execute você mesmo!

  • Pergunta: Prove que flip = rotate_90 ◦ rotate_90.

De qualquer forma, não vou esconder o ingrediente secreto por mais tempo:

import math   # we'll need math from now on
  ...

class Vector:

      ...

    def rotate(self:'vector', angle:'rotation angle') -> 'rotated vector':
        cos = math.cos(angle)
        sin = math.sin(angle)
        new_x = cos * self.x - sin * self.y
        new_y = sin * self.x + cos * self.y
        return Vector(new_x, new_y)

Agora vamos tentar algo ao longo das linhas:

print(x_axis.rotate(90), y_axis.rotate(90))

Se você espera o mesmo resultado de antes, (0, 1) (-1, 0), você está fadado a se decepcionar.Esse código imprime:

(-0.448073616129, 0.893996663601) (-0.893996663601, -0.448073616129)

e rapaz, é feio!

  • Notação: Direi que aplicámos a operação rotate(90) para x no exemplo acima.O conhecimento que adquirimos é que rotate(90) != rotate_90.

  • Pergunta: O que aconteceu aqui?Como expressar rotate_90 em termos de rotate?Como expressar flip em termos de rotate?

Dilatações

Essas rotações são certamente úteis, mas não são tudo o que você precisa fazer, mesmo os gráficos 2D.Considere as seguintes transformações:

    def dilate(self:'vector', axe_x:'x dilation', axe_y:'y dilation'):
        '''Dilates a vector along the x and y axes'''
        new_x = axe_x * self.x
        new_y = axe_y * self.y
        return Vector(new_x, new_y)

Esta dilate coisa dilata o x e y eixos de uma forma possivelmente diferente.

  • Exercício: Preencha os pontos de interrogação em dilate(?, ?) = flip, dilate(?, ?) = reflect_x.

Eu vou usar isso dilate função para demonstrar uma coisa que os matemáticos chamam comutatividade:isto é, para cada valor de parâmetros a, b, c, d você pode ter certeza de que

dilate(a, b) ◦ dilate(c, d) = dilate(c, d) ◦ dilate(a, b)
  • Exercício: Prova-o.Além disso, é verdade que, para todos os valores possíveis de Parâmetros, os valores abaixo se manteriam?

    • rotate(a) ◦ rotate(b) = rotate(b) ◦ rotate(a)
    • dilate(a, b) ◦ rotate(c) = rotate(c) ◦ dilate(a, b)
    • rotate(a) ◦ __mul__(b) = __mul__(b) ◦ rotate(a)

Matrizes

Vamos resumir todas as coisas que tínhamos por aqui, a nossa operadores em vetor x

  • flip, reflect_x, *, rotate(angle), dilate(x, y)

a partir do qual se poderia fazer algumas coisas realmente loucas como

  • flip ◦ rotate(angle) ◦ dilate(x, y) ◦ rotate(angle_2) ◦ reflect_y + reflect_x = ???

À medida que se criam expressões cada vez mais complicadas, espera-se algum tipo de ordem que reduza subitamente todas as expressões possíveis a uma forma útil.Não temas!Magicamente, cada expressão da forma acima pode ser simplificada para

    def ???(self:'vector', parameters):
        '''A magical representation of a crazy function'''
        new_x = ? * self.x + ? * self.y
        new_y = ? * self.x + ? * self.y
        return Vector(new_x, new_y)

com alguns números e / ou parâmetros em vez de ?s.

  • Exemplo: Trabalhar para fora o que os valores de'?'são para __mul__(2) ◦ rotate(pi/4)
  • Outro exemplo: Mesma pergunta para dilate(x, y) ◦ rotate(pi/4)

Isso nos permite escrever uma função universal

    def transform(self:'vector', m:'matrix') -> 'new vector':
        new_x = m[0] * self.x + m[1] * self.y
        new_y = m[2] * self.x + m[3] * self.y
        return Vector(new_x, new_y)

que levaria qualquer 4-tupla de números, chamado matriz, e aplicar para vector x.Aqui está um exemplo:

rotation_90_matrix = (0, -1, 1, 0)
print(v, v.rotate_90(), v.transform(rotation_90_matrix))

que imprime (5, 3) (-3, 5) (-3, 5).Observe que, se você se inscrever transform com qualquer matriz de origem, você ainda obter origem:

origin = Vector(0, 0)
print(origin.transform(rotation_90_matrix))
  • Exercício: quais são as tuplas m que descrevem flip, dilate(x, y), rotate(angle)?

À medida que nos separamos do Vector aula, aqui está um exercício para aqueles que querem testar seus conhecimentos de matemática vetorial e habilidades Pitônicas:

  • A batalha final: Adicionar ao Vector Classifique todas as operações vetoriais que você pode criar (quantos operadores padrão você pode sobrecarregar para vetores?Veja a minha resposta).

2.Matrizes:Sobrecarregado

Como descobrimos na seção anterior, uma matriz pode ser pensada como uma abreviação que nos permite codificar uma operação vetorial de maneira simples.Por exemplo, rotation_90_matrix codifica a rotação em 90 graus.

Objectos matriciais

Agora, à medida que mudamos nossa atenção de vetores para matrizes, devemos, por todos os meios, ter uma classe para matrix também.Além disso, nessa função Vector.transform(...) acima do papel da matriz foi um pouco deturpado.É mais comum para m para ser corrigido enquanto o vetor muda, então, a partir de Agora, nossas transformações serão métodos de classe de matriz:

class Matrix:

    def __init__(self:'new matrix', m:'matrix data'):
        '''Create a new matrix.

        So far a matrix for us is just a 4-tuple, but the action
        will get hotter once The (R)evolution happens!

        '''
        self.m = m

    def __call__(self:'matrix', v:'vector'):
        new_x = self.m[0] * v.x + self.m[1] * v.y
        new_y = self.m[2] * v.x + self.m[3] * v.y
        return Vector(new_x, new_y)

Se você não conhece Python, __call__ sobrecarrega o Significado de (...) para matrizes para que eu possa usar a notação padrão para uma matriz acção em um vetor.Além disso, as matrizes são geralmente escritas usando uma única letra maiúscula:

J = Matrix(rotation_90_matrix)
print(w, 'rotated is', J(w))
  • Exercício: repita este exemplo com matrizes do exercício anterior.

Aditamento

Agora, vamos descobrir o que mais podemos fazer com matrizes.Lembre-se que a matriz m é realmente apenas uma maneira de codificar uma operação em vetores.Observe que para duas funções m1(x) e m2(x) Posso criar uma nova função (usando Notação lambda) m = lambda x: m1(x) + m2(x).Acontece que se m1 e m2 foram reunidas por matrizes, você também pode codificar isso m utilização de matrizes!

  • Exercício: Pense em quaisquer dificuldades que possa ter com esta afirmação.

Você só precisa adicionar seus dados, como (0, 1, -1, 0) + (0, 1, -1, 0) = (0, 2, -2, 0).Veja como adicionar duas tuplas em Python, com algumas técnicas muito úteis e altamente Pitônicas:

    def __add__(self:'matrix', snd:'another matrix'):
        """This will add two matrix arguments.

        snd is a standard notation for second argument.
        (i for i in array) is Python's powerful list comprehension.
        zip(a, b) is used to iterate over two sequences together

        """

        new_m = tuple(i + j for i, j in zip(self.m, snd.m))
        return Matrix(new_m)

Agora podemos escrever expressões como J + J ou mesmo J + J + J, mas para ver os resultados, temos que descobrir como imprimir uma matriz.Uma maneira possível seria imprimir uma tupla de 4 números, mas vamos dar uma dica do Matrix.__call__ função que os números devem ser organizados em um 2x2 bloco:

    def as_block(self:'matrix') -> '2-line string':
        """Prints the matrix as a 2x2 block.

        This function is a simple one without any advanced formatting.
        Writing a better one is an exercise.

        """

        return ('| {0} {1} |\n' .format(self.m[0], self.m[1]) +
                '| {0} {1} |\n' .format(self.m[2], self.m[3]) )

Se você olhar para esta função em ação, notará que há algum espaço para melhorias:

print((J + J + J).as_block())
  • Exercício: escreva uma função mais agradável Matrix.__str__ que irá arredondar o números e imprimi-los nos campos de comprimento fixo.

Agora você deve ser capaz de escrever a matriz para rotação:

def R(a: 'angle') -> 'matrix of rotation by a':
    cos = math.cos(a)
    sin = math.sin(a)
    m = ( ????? )
    return Matrix(m)
  • Exercício: Examinar o código para Vector.rotate(self, angle) e preencha os pontos de interrogação.Ensaio com

    from math import pi        
    print(R(pi/4) + R(-pi/4))
    

Multiplicação

A coisa mais importante que podemos fazer com funções de um parâmetro é compô-las: f = lambda v: f1(f2(v)).Como espelhar isso com matrizes?Isso exige que examinemos como Matrix(m1) ( Matrix(m2) (v)) funciona.Se você expandi-lo, você notará que

m(v).x = m1[0] * (m2[0]*v.x + m2[1]*v.y) + m1[1] * (m2[2]*v.x + m2[3]*v.y)

e da mesma forma para m(v).y, que, se você abrir os parênteses, parece suspeitamente semelhante para Matrix.__call__ usando uma nova tupla m, tal que m[0] = m1[0] * m2[0] + m1[2] * m2[2].Então, vamos tomar isso como uma dica para uma nova definição:

    def compose(self:'matrix', snd:'another matrix'):
        """Returns a matrix that corresponds to composition of operators"""

        new_m = (self.m[0] * snd.m[0] + self.m[1] * snd.m[2],
                 self.m[0] * snd.m[1] + self.m[1] * snd.m[3],
                 ???,
                 ???) 
        return Matrix(new_m)
  • Exercício: Preencha os pontos de interrogação aqui.Teste-o com

    print(R(1).compose(R(2)))
    print(R(3))
    
  • Exercício de matemática: Prove que R(a).compose(R(b)) é sempre o mesmo que R(a + b).

Agora deixe-me dizer a verdade:esta compose função é, na verdade, como os matemáticos decidiram multiplicar matrizes.Isso faz sentido como uma notação: A * B é uma matriz que descreve o operador A ○ B, e como veremos a seguir, há razões mais profundas para chamar isso de 'multiplicação' também.

Para começar a usar a multiplicação em Python, tudo o que precisamos fazer é ordená-la em um Matrix classe:

    class Matrix:

          ...

        __mul__ = compose
  • Exercício: Computar (R(pi/2) + R(pi)) * (R(-pi/2) + R(pi)).Tente encontrar a resposta primeiro em um pedaço de papel.

Regras para + e *

Vamos fazer um bom nome para a matriz que corresponde ao dilate(a, b) operador.Agora não há nada de errado com D(a, b), mas eu vou use uma chance para introduzir uma notação padrão:

def diag(a: 'number', b: 'number') -> 'diagonal 2x2 matrix':
    m = (a, 0, 0, b)
    return Matrix(m)

Tente print(diag(2, 12345)) para ver por que é chamado a diagonal matrix.

Uma vez que a composição das operações não era sempre comutativa, * o operador também não será sempre comutativo para matrizes.

  • Exercício: volte e refresque o comutatividade coisa, se necessário.Em seguida, dê exemplos de matrizes A, B, feito de R e diag, tal que A * B não é igual a B * A.

Isso é um tanto estranho, uma vez que a multiplicação por números é sempre comutativa e levanta a questão de saber se compose realmente merece ser chamado __mul__.Aqui estão muitas regras que + e * fazer satisfazer:

  1. A + B = B + A
  2. A * (B + C) = A * B + A * C
  3. (A + B) * C = A * C + B * C
  4. (A * B) * C = A * (B * C)
  5. Existe uma operação chamada A - B e (A - B) + B = A

    • Exercício: Prove essas declarações.Como definir A - B em termos de +, * e diag?O que faz A - A igual a?Adicione o método __sub__ para a classe Matrix.O que acontece se você calcular R(2) - R(1)*R(1)?A que deveria ser igual?

O (A * B) * C = A * (B * C) igualdade é chamada associatividade e é especialmente bom, pois significa que não precisamos nos preocupar em colocar parênteses em uma expressão do formulário A * B * C:

print(R(1) * (diag(2,3) * R(2)))
print((R(1) * diag(2,3)) * R(2))

Vamos encontrar análogos aos números regulares 0 e 1 e subtração:

zero = diag(0, 0)
one = diag(1, 1)     

Com as seguintes adições facilmente verificáveis:

  1. A + zero = A
  2. A * zero = zero
  3. A * one = one * A = A

as regras tornam-se completas, no sentido de que há um nome curto para elas: axiomas em anel.Os matemáticos, portanto, diriam que as matrizes formam um anel, e eles de fato sempre usam símbolos + e * quando falamos de anéis, e nós também.

Usando as regras, é possível calcular facilmente a expressão da seção anterior:

(R(pi/2) + R(pi)) * (R(-pi/2) + R(pi)) = R(pi/2) * R(-pi/2) +  ... = one + ...
  • Exercício: Acaba com isto.Prove que (R(a) + R(b)) * (R(a) - R(b)) = R(2a) - R(2b).

Transformações Afins

Tempo para voltar à forma como definimos as matrizes:eles são um atalho para algumas operações que você pode fazer com vetores, então é algo que você pode realmente desenhar.Você pode querer pegar uma caneta ou olhar para os materiais que outros sugeriram para ver exemplos de diferentes transformações planas.

Entre as transformações, procuraremos o afim uns, aqueles que parecem 'iguais' em todos os lugares (sem flexão).Por exemplo, uma rotação em torno de algum ponto (x, y) qualifica.Ora, esta não pode ser expressa como lambda v: A(v), mas em Pode ser escrito na forma lambda v: A(v) + b para alguma matriz A e vector b.

  • Exercício: encontre o A e b tal que uma rotação por pi/2 em torno do ponto (1, 0) tem a forma acima.São únicos?

Note - se que para cada vetor existe uma transformação afim que é um mudança pelo vetor.

Uma transformação afim pode esticar ou dilatar formas, mas deve fazer o mesmo em todos os lugares.Agora, espero que acreditem que a área de qualquer figura muda por um número constante sob a transformação.Para uma transformação dada pela matriz A este coeficiente é denominado determinante de A e pode ser calculado aplicando a fórmula para uma área a dois vetores A(x_axis) e A(y_axis):

    def det(self: 'matrix') -> 'determinant of a matrix':
        return self.m[0]*self.m[3] - self.m[1] * self.m[2]

Como uma verificação de sanidade, diag(a, b).det() é igual a a * b.

  • Exercício: Verifica isto.O que acontece quando um dos argumentos é 0?Quando é negativo?

Como você pode ver, o determinante da matriz de rotação é sempre o mesmo:

from random import random
r = R(random())
print (r, 'det =', r.det())

Uma coisa interessante sobre det é que é multiplicativo (meio que segue da definição se você meditar por tempo suficiente):

A = Matrix((1, 2, -3, 0))
B = Matrix((4, 1, 1, 2))
print(A.det(), '*', B.det(), 'should be', (A * B).det())

Inverso

Uma coisa útil que você pode fazer com matrizes é escrever um sistema de duas equações lineares

A.m[0]*v.x + A.m[1]*v.y = b.x
A.m[2]*v.x + A.m[3]*v.y = b.y

de uma forma mais simples: A(v) = b.Vamos resolver o sistema enquanto ensinam em (algumas) escolas secundárias:multiplique a primeira equação por A.m[3], segundo por-A. m1 e adicione (em caso de dúvida, faça isso em um pedaço de papel) para resolver v.x.

Se você realmente tentou, você deveria ter A.det() * v.x = (A.m[3]) * b.x + (-A.m[1]) * b.y, o que sugere que você sempre pode obter v multiplicando b por alguma outra matriz.Esta matriz é chamada inverso de A:

    def inv(self: 'matrix') -> 'inverse matrix':
        '''This function returns an inverse matrix when it exists,
        or raises ZeroDivisionError when it doesn't. 

        '''
        new_m = ( self.m[3] / self.det(), -self.m[1] / self.det(),
                  ????? )
        return Matrix(new_m)

Como você vê, este método falha alto quando determinante da matriz é zero.Se você realmente quiser, pode pegar essa expectativa com:

try:
    print(zero.inv())
except ZeroDivisionError as e: ...
  • Exercício: Termine o método.Prove que a matriz inversa não existe quando self.det() == 0.Escreva o método para dividir matrizes e testá-lo.Use a matriz inversa para resolver uma equação A(v) = x_axis (A foi definido acima).

Poderes

A principal propriedade da matriz inversa é que A * A.inv() sempre igual a one

  • Exercício: verifique você mesmo.Explique por que isso deveria ser assim a partir da definição de matriz inversa.

É por isso que os matemáticos denotam A.inv() por A-1.Que tal escrevermos um boa função para usar A ** n notação para An?Note - se que o ingênuo for i in range(n): answer *= self o ciclo é O (|n/) que é certamente demasiado lento, porque isso pode ser feito com uma complexidade de log |n|:

    def __pow__(self: 'matrix', n:'integer') -> 'n-th power':
        '''This function returns n-th power of the matrix.

        It does it more efficiently than a simple for cycle. A
        while loop goes over all bits of n, multiplying answer
        by self ** (2 ** k) whenever it encounters a set bit.

        ...
  • Exercício: Preencha os detalhes nesta função.Teste-o com

    X, Y = A ** 5, A ** -5 print (X, Y, X * Y, sep = '\n')

Esta função só funciona para valores inteiros de n, embora para algumas matrizes também possamos definir uma potência fracionária, como raiz quadrada (em outras palavras, uma matriz B tal que B * B = A).

  • Exercício: Encontre uma raiz quadrada de diag(-1, -1).Será esta a única resposta possível?Encontre um exemplo de matriz que não tem uma raiz quadrada.

Bónus:Números complexos

Aqui vou apresentar-vos o assunto exactamente numa secção!Uma vez que é um assunto complexo, é provável que eu falhe, por isso, por favor, perdoe-me antecipadamente.

Primeiro, da mesma forma que temos matrizes zero e one, podemos fazer uma matriz de qualquer número real fazendo diag(number, number).As matrizes dessa forma podem ser somadas, subtraídas, multiplicadas, invertidas e os resultados imitam o que acontece com os próprios números.Assim, para todos os efeitos práticos, pode-se dizer que, por exemplo., diag(5, 5) é 5.

No entanto, Python ainda não sabe como lidar com expressões do formulário A + 1 ou 5 * B onde A e B são matrizes.Se você estiver interessado, você deve por todos os meios ir e fazer o seguinte exercício ou olhar para a minha implementação (que usa um recurso Python legal chamado decorador);caso contrário, apenas saiba que foi implementado.

  • Exercício para gurus: Alterar os operadores em um Matrix classe de modo que em todas as operações padrão em que um dos operandos é uma matriz e outro um número, o número é automaticamente convertido para o diag matrix.Adicione também comparação para igualdade.

Aqui está um exemplo de teste:

print( 3 * A - B / 2 + 5 )

Agora aqui está o primeiro interessante número complexo:a matriz J, introduzido no início e igual a Matrix((0, 1, -1, 0)), tem uma propriedade engraçada que J * J == -1 (experimente!).Isso significa J não é certamente um número normal, mas, como acabei de dizer, matrizes e números misturam-se facilmente.Por exemplo,

(1 + J) * (2 + J) == 2 + 2 * J + 1 * J + J * J = 1 + 3 * J

utilizar as regras enumeradas há algum tempo.O que acontece se testarmos isso em Python?

(1 + J) * (2 + J) == 1 + 3*J

Isso deve dizer alegremente True.Outro exemplo:

(3 + 4*J) / (1 - 2*J) == -1 + 2*J 

Como você deve ter adivinhado, os matemáticos não chamam esses 'números loucos', mas eles fazem algo semelhante-Eles chamam expressões da forma a + b*J números complexos.Porque esses ainda são exemplos de nossa Matrix classe, podemos fazer muitas operações com aqueles:adição, subtração, multiplicação, divisão, potência - tudo já está implementado!As matrizes não são incríveis?

Esqueci a questão de como imprimir o resultado de uma operação como E = (1 + 2*J) * (1 + 3*J) para que pareça uma expressão com J em vez de um 2x2 matrix.Se o examinar cuidadosamente, você verá que precisa imprimir a coluna da esquerda dessa matriz no formato ... + ...J (Só mais uma coisa boa:é exactamente E(x_axis)!) Aqueles que sabem a diferença entre str() e repr() deve ver que é natural nomear uma função que produziria expressão de tal forma como repr().

  • Exercício: Escreva a função Matrix.__repr__ isso faria exatamente isso e tentaria alguns testes com ele, como (1 + J) ** 3, primeiro computando o resultado no papel e depois tentando com Python.

  • Questão matemática: Qual é o determinante de a + b*J?Se você sabe o que valor absoluto do número complexo é:como eles estão conectados?Qual é o valor absoluto de a?de a*J?

3.Matrizes:A (R)evolução

Na parte final desta trilogia, veremos que tudo é uma matriz.Vamos começar pelo general M x N matrizes, e descobrir como os vetores podem ser pensados como 1 x N matrizes e por que os números são iguais às matrizes diagonais.Como uma nota lateral, exploraremos os números complexos como 2 x 2 matrizes.

Finalmente, aprenderemos a escrever transformações afins e projetivas usando matrizes.

As aulas previstas são [MNMatrix, NVector, Affine, Projective].

Eu acho que se você foi capaz de suportar comigo até aqui, você poderia estar interessado nesta sequela, então eu gostaria de ouvir se eu deveria continuar com isso (e onde, já que tenho certeza de que estou além do que considerou razoável comprimento de um único documento).

Outras dicas

MIT tem um monte de materiais de seus cursos de matemática on-line em http://ocw.mit.edu / OcwWeb / Matemática / . Depois de ter o básico para baixo, eles têm as notas de física on-line também.

Este documento MIT é um must-have para obter conhecimento forte sobre os conceitos básicos de Transformação.

http : //stellar.mit.edu/S/course/6/fa08/6.837/courseMaterial/topics/topic2/lectureNotes/03_transform/03_transform.pdf

Um dos melhores livros para iniciantes é Carl Meyer de "Matriz de Análise e Aplicada Álgebra Linear".

Você pode visualizar todo o livro on-line aqui (embora tenha uma marca d'água de direitos autorais): http://www.matrixanalysis.com/DownloadChapters.html

Você pode querer dar uma olhada em Capítulo 5 pg. 326-332, que abrange as rotações em 3 dimensões computação gráfica

Você pode querer olhar para geométrica linear álgebra por I-Hsiung Lin, Yixiong Lin (ISBN: 9812560874). O livro é especificamente voltada para o que você quer (linear transformações de espaços vetoriais 2 e 3 dimensões) e trata-o com uma abordagem geométrica na íntegra, detalhe progressiva (300 páginas para cada dimensão). Eu tenho medo que não é livre para comprar, mas você deve ser capaz de encontrá-lo em qualquer boa biblioteca universitária. Caso contrário Bookfinder deve ajudá-lo a obtê-lo a um preço relativamente modesto.

O Jim Hefferon livre Álgebra Linear livro é realmente bom. Ao contrário de muitos ebooks gratuitos, Jim tem claramente tomado a tempo para elaborar um excelente leitor e introdução à álgebra linear. Não é excessivamente sobrecarregados com escrita matemática formal, que é muitas vezes demasiado denso, com teoremas e provas para ser facilmente compreensível. Ele também contém vários realmente excelentes exemplos de aplicações do mundo real da álgebra linear - transformações de coordenadas sendo apenas um exemplo. Você não pode bater o preço, e ele também vem com soluções opcionais para os exercícios.

P.S. Se transformações de coordenadas são sua coisa, você pode estar interessado em geometria diferencial depois que você fez com a álgebra linear.

Essas são as informações que eu encontrei. Alguns deles podem ser valiosas para você:

Teoria:

(Buscando "Matrizes" em livros do Google lhe dá muita lecutures, alguns dos quais estão diretamente relacionados com transformações - este é um dos primeiros resultados, mas eu animá-lo para verificar mais.)

Eu também incentivar (Eu não sei se esta é a palavra certa, estou apenas aprendendo Inglês) Você, a olhar para este tipo de informação em um desses livros (embora eles não são livres, mas você pode encontrar grandes partes mais velhos no Google Livros):

  1. Jogo gemas de programação 7
  2. Jogo gemas de programação 6
  3. Jogo gemas de programação 5
  4. Jogo gemas de programação 4
  5. Jogo gemas de programação 3
  6. Jogo gemas de programação 2
  7. Jogo gemas programação

Cada um desses tem seção sobre gemas de matemática - e existem muitos truques lá. Esses livros valem cada centavo.

Há também gemas GPU programação, assim você pode experimentá-los também.

Práticas:

Se eu vou encontrar mais, vou editar e adicionar links aqui, mas para ser honesto - eu encontrei aquelas ligações em cerca de 10 minutos de usar o Google. a maioria do mundo populares navegador armazena dados sobre tudo - e sim, matrizes "tudo" significa muito.

Cheers, Mate.

Eu acho que você deve passar alguns dias fazendo produtos de ponto e produtos cruzados com vetores em 3D. Então aprenda a relação entre trig e vetores. Depois que as matrizes fará muito mais sentido para você.

O curso de MIT-OCW em Álgebra Linear por Gilbert Strang. palestras incríveis por um homem incrível; se o seu entendimento de matrizes é exclusivamente derivado de fontes (como MATLAB) Programação em seguida, um curso de Álgebra Linear vai certamente dar-lhe os fundamentos de fazer coisas loucas com matrizes.

http://www.ocw.cn /OcwWeb/Mathematics/18-06Spring-2005/VideoLectures/index.htm

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top