Quais são as bibliotecas de álgebra linear vetorial / matriz matemática / linear C ++ mais usadas, e suas vantagens e desvantagens em custos e benefícios? [fechadas]


242

Parece que muitos projetos enfrentam lentamente a necessidade de fazer matemática matricial e caem na armadilha de criar primeiro algumas classes de vetores e adicionar funcionalidades lentamente até serem pegos construindo uma biblioteca de álgebra linear personalizada de meia-boca e dependendo dela.

Eu gostaria de evitar isso enquanto não cria uma dependência em alguma biblioteca relacionada tangencialmente (por exemplo, OpenCV, OpenSceneGraph).

Quais são as bibliotecas de matemática / álgebra linear de matriz comumente usadas por aí e por que decidem usar uma sobre a outra? Existe algum que não seja aconselhável usar por algum motivo? Estou usando isso especificamente em um contexto geométrico / temporal * (2,3,4 Dim) *, mas pode estar usando dados dimensionais mais altos no futuro.

Estou procurando diferenças em relação a: API, velocidade, uso de memória, abrangência / abrangência, estreiteza / especificidade, extensibilidade e / ou maturidade / estabilidade.

Atualizar

Acabei usando o Eigen3, com o qual estou extremamente feliz.


2
Desde que você mencionou OSG e OpenCV, acho que você só precisa de gráficos / vetores 3D, como matrizes 3x3 e 4x4. Baseei minha resposta nisso, mas você pode especificar como exatamente está usando isso - precisa de resolução de matriz? Matemática matricial dimensional superior? etc.
Reed Copsey

No momento, estou apenas fazendo coisas baseadas em geometria 2D, mas hipoteticamente às vezes você precisa de operações 3x3 em dados 2D, e não está claro se dados 3D e operações com 4x4 podem ser necessárias. Gostaríamos de usar uma biblioteca comum em toda a empresa. Não tenho um bom senso de quais seriam as trocas. Mais geral seria melhor, mas a que custo está a questão.
Catskul 4/09/09

1
Se você está apenas fazendo transformações geométricas, eu realmente recomendo olhar o GGT, como mencionei na minha resposta. É muito completo para isso, mas realmente não faz nada além disso, por isso é uma opção muito limpa e fácil. BLAS e LAPACK são mais para soluções de matriz complexa de doign (ou seja: matrizes 50x50, matrizes esparsas, etc.) para ciências e matemática, não para transformações geométricas.
Reed Copsey

Respostas:


114

Existem alguns projetos que se adaptaram ao Generic Graphics Toolkit para isso. O GMTL é bom - é bem pequeno, muito funcional e foi usado o suficiente para ser muito confiável. O OpenSG, o VRJuggler e outros projetos passaram a usar isso em vez de suas próprias matemáticas de matriz / vertor.

Achei bastante legal - ele faz tudo via modelos, por isso é muito flexível e muito rápido.


Editar:

Após a discussão e as edições dos comentários, pensei em lançar mais algumas informações sobre os benefícios e desvantagens de implementações específicas e por que você pode escolher um sobre o outro, dada a sua situação.

GMTL -

Benefícios: API simples, projetada especificamente para mecanismos gráficos. Inclui muitos tipos primitivos voltados para a renderização (como planos, AABB, quatenrions com interpolação múltipla etc.) que não estão em nenhum outro pacote. Sobrecarga de memória muito baixa, muito rápido, fácil de usar.

Desvantagens: a API é muito focada especificamente em renderização e gráficos. Não inclui matrizes de uso geral (NxM), decomposição e resolução de matrizes, etc., pois estão fora do domínio das aplicações tradicionais de gráficos / geometria.

Eigen -

Benefícios: API limpa , bastante fácil de usar. Inclui um módulo de geometria com quaternions e transformações geométricas. Sobrecarga de memória baixa. Solução completa e de alto desempenho de grandes matrizes NxN e outras rotinas matemáticas de uso geral.

Desvantagens: pode ser um escopo um pouco maior do que você deseja (?). Menos rotinas geométricas / de renderização específicas quando comparadas ao GMTL (por exemplo: definições de ângulo de Euler, etc.).

IMSL -

Benefícios: Biblioteca numérica muito completa. Muito, muito rápido (supostamente o solucionador mais rápido). De longe, a maior e mais completa API matemática. Suporte comercial, maduro e estável.

Desvantagens: Custo - não é barato. Muito poucos métodos geométricos / de renderização específicos, portanto, você precisará rolar por cima das classes de álgebra linear.

NT2 -

Benefícios: fornece uma sintaxe mais familiar se você estiver acostumado ao MATLAB. Fornece decomposição e solução completas para matrizes grandes, etc.

Desvantagens: matemático, sem renderização focada. Provavelmente não é tão eficiente quanto Eigen.

LAPACK -

Benefícios: algoritmos comprovados e muito estáveis. Já existe há muito tempo. Resolução completa de matrizes, etc. Muitas opções para matemática obscura.

Desvantagens: Não é tão altamente eficiente em alguns casos. Portado de Fortran, com API ímpar para uso.

Pessoalmente, para mim, tudo se resume a uma única pergunta - como você planeja usar isso. Se seu foco é apenas renderização e gráficos, eu gosto do Generic Graphics Toolkit , pois ele tem um bom desempenho e suporta muitas operações úteis de renderização prontas para uso, sem a necessidade de implementar suas próprias. Se você precisar de uma solução geral para matrizes (ex .: decomposição SVD ou LU de matrizes grandes), eu usaria o Eigen , pois ele lida com isso, fornece algumas operações geométricas e é muito eficiente em soluções de matrizes grandes. Você pode precisar escrever mais operações gráficas / geométricas (além das matrizes / vetores), mas isso não é horrível.


Você avaliou outras bibliotecas antes de decidir sobre o GMTL? Comparações superficiais me levaram a acreditar que o Eigen era melhor suportado, mas isso se baseia na análise dos respectivos sites. Você está ciente de alguma vantagem específica de uma sobre a outra?
Catskul

Eigen também funciona bem. Não era tão maduro na época em que fiz minha investigação, mas acredito que seria uma boa opção neste momento. O GMTL tem sido amplamente utilizado e estava muito maduro e sólido quando decidi usá-lo.
Reed Copsey

Acho que reduzi minha pergunta ao ponto crucial: você fez sua escolha subjetivamente como "Isso parece melhor" ou onde há recursos específicos (API, velocidade, uso de memória, largura, estreiteza e extensibilidade) que fizeram a diferença. Suponho que a maturidade se enquadre nesse critério, mas se a maturidade fosse a única métrica, imagino que você teria selecionado uma opção baseada em BLAS ou LAPACK.
Catskul

Eu escolhi isso depois de tentar várias opções e baseei-o: desempenho, usabilidade e baixo tempo de execução / tempo de compilação. Eigen parece muito melhor agora do que naquele momento, então não posso julgar entre eles. No entanto, fiquei muito feliz com o GMTL por nossos usos.
Reed Copsey

É por isso que eu gosto do GMTL e o uso. Parecia muito natural de usar e era muito, muito fácil de trabalhar. Ele também suportava tudo o que eu precisava, neste caso, pois estava preocupado em lidar diretamente com a transformação geométrica e as rotações de quaternion.
Reed Copsey

38

Portanto, sou uma pessoa bastante crítica e, se vou investir em uma biblioteca, é melhor saber no que estou me metendo. Eu acho que é melhor se opor às críticas e à luz da bajulação ao examinar; o que há de errado com isso tem muito mais implicações para o futuro do que o que é certo. Então, vou exagerar um pouco aqui para fornecer o tipo de resposta que teria me ajudado e espero que ajude outras pessoas que possam seguir esse caminho. Lembre-se de que isso se baseia no pouco teste / revisão que fiz com essas bibliotecas. Ah, e roubei parte da descrição positiva de Reed.

Vou mencionar acima que fui com o GMTL, apesar das idiossincrasias, porque a insegurança do Eigen2 era muito grande como um ponto negativo. Mas eu aprendi recentemente que a próxima versão do Eigen2 conterá definições que desligarão o código de alinhamento e o tornarão seguro. Então eu posso mudar.

Atualização : mudei para o Eigen3. Apesar das idiossincrasias, seu escopo e elegância são muito difíceis de ignorar, e as otimizações que a tornam insegura podem ser desativadas com uma definição.

Eigen2 / Eigen3

Benefícios: LGPL MPL2, API limpa, bem projetada, bastante fácil de usar. Parece ser bem conservado com uma comunidade vibrante. Sobrecarga de memória baixa. Alta performance. Feito para álgebra linear geral, mas também possui boa funcionalidade geométrica. Toda a biblioteca de cabeçalho, sem necessidade de vinculação.

Idiocincracias / desvantagens: (algumas / todas elas podem ser evitadas por algumas definições disponíveis no atual ramo de desenvolvimento Eigen3)

  • Otimizações de desempenho inseguras resultam na necessidade de seguir cuidadosamente as regras. O não cumprimento das regras causa falhas.
    • você simplesmente não pode transmitir com segurança o valor
    • o uso de tipos Eigen como membros requer personalização especial do alocador (ou você trava)
    • use com tipos de contêiner stl e, possivelmente, outros modelos requeiram personalização especial de alocação (ou você trava)
    • certos compiladores precisam de cuidados especiais para evitar falhas nas chamadas de função (janelas do GCC)

GMTL

Benefícios: LGPL, API bastante simples, projetada especificamente para mecanismos gráficos. Inclui muitos tipos primitivos voltados para a renderização (como planos, AABB, quatenrions com interpolação múltipla etc.) que não estão em nenhum outro pacote. Sobrecarga de memória muito baixa, muito rápido, fácil de usar. Tudo baseado em cabeçalho, sem vinculação necessária.

Idiocincracias / desvantagens:

  • API é peculiar
    • o que pode ser myVec.x () em outra lib está disponível apenas via myVec [0] (problema de legibilidade)
      • uma matriz ou stl :: vetor de pontos pode fazer com que você faça algo como pointsList [0] [0] para acessar o componente x do primeiro ponto
    • numa tentativa ingênua de otimização, removeu o cross (vec, vec) e substituiu o makeCross (vec, vec, vec) quando o compilador elimina temporariamente desnecessários
    • operações matemáticas normais não retornam tipos normais, a menos que você desligue alguns recursos de otimização, por exemplo: vec1 - vec2não retorna um vetor normal, portanto length( vecA - vecB )falha mesmo que vecC = vecA - vecBfuncione. Você deve quebrar como:length( Vec( vecA - vecB ) )
    • operações em vetores são fornecidas por funções externas e não por membros. Isso pode exigir que você use a resolução do escopo em qualquer lugar, pois nomes comuns de símbolos podem colidir
    • você tem que fazer
        length( makeCross( vecA, vecB ) )
      ou
        gmtl::length( gmtl::makeCross( vecA, vecB ) )
      onde, caso contrário, você pode tentar
        vecA.cross( vecB ).length()
  • mal conservado
    • ainda reivindicado como "beta"
    • documentação faltando informações básicas, como quais cabeçalhos são necessários para usar a funcionalidade normal
      • Vec.h não contém operações para Vetores, VecOps.h contém algumas, outras estão em Generate.h, por exemplo. cross (vec &, vec &, vec &) em VecOps.h, [make] cross (vec &, vec &) em Generate.h
  • API imatura / instável; ainda mudando.
    • Por exemplo, "cross" mudou de "VecOps.h" para "Generate.h" e, em seguida, o nome foi alterado para "makeCross". Exemplos de documentação falham porque ainda se referem a versões antigas de funções que não existem mais.

NT2

Não posso dizer porque eles parecem estar mais interessados ​​no cabeçalho da imagem fractal da página da web do que no conteúdo. Parece mais um projeto acadêmico do que um projeto de software sério.

Última versão há mais de 2 anos.

Aparentemente, nenhuma documentação em inglês, embora supostamente exista algo em francês em algum lugar.

Não é possível encontrar vestígios de uma comunidade em torno do projeto.

LAPACK & BLAS

Benefícios: Antigo e maduro.

Desvantagens:

  • velhos como dinossauros com APIs realmente ruins

1
Em relação às declarações alinhadas à Eigen: para obter alto desempenho das operações SSE (1,2,3 ou 4) para pequenos conjuntos de dados, você precisa absolutamente de dados alinhados. As operações de carga / armazenamento desalinhadas são muito mais lentas. A decisão entre carga / armazenamento alinhado ou não alinhado também leva tempo. Qualquer implementação de "uso geral" teria muita dificuldade em fazer a coisa certa para todos, a menos que eles também separassem a interface em operações "alinhadas" e "desalinhadas" - e, novamente, simplesmente não é um objetivo geral.
Joris Timmermans

@Catskul Eu gostaria de usar o Eigen3. Você poderia expandir "as otimizações que a tornam insegura podem ser desativadas com uma definição"? Os outros problemas listados no Eigen2 são detalhadamente detalhados no documento em Tópicos relacionados aos problemas de alinhamento . Eu posso viver com esses problemas.
Ali

Os problemas de segurança que estou me referindo a todos os alinhamentos relacionados são os mesmos do Eigen2. Se você estiver bem com o Eigen2, você ficará bem com o Eigen3.
Catskul

2
BLAS e LAPACK não são realmente bibliotecas, mas especificações / APIs. você poderia ter mencionado suas implementações iniciais pelo netlib ou outras implementações, como ATLAS e OpenBLAS.
Carrega

12

Pelo que vale a pena, tentei Eigen e Tatu. Abaixo está uma breve avaliação.

Vantagens do Eigen: 1. Completamente independente - sem dependência de BLAS ou LAPACK externo. 2. Documentação decente. 3. Supostamente rápido, embora eu não o tenha posto à prova.

Desvantagem: O algoritmo QR retorna apenas uma matriz, com a matriz R incorporada no triângulo superior. Nenhuma ideia de onde vem o restante da matriz e nenhuma matriz Q pode ser acessada.

Vantagens do tatu: 1. Vasta gama de decomposições e outras funções (incluindo QR). 2. Razoavelmente rápido (usa modelos de expressão), mas, novamente, eu não o levei a grandes dimensões.

Desvantagens: 1. Depende do BLAS externo e / ou do LAPACK para decomposições da matriz. 2. Falta a documentação do IMHO (incluindo os específicos do LAPACK, exceto a alteração de uma declaração #define).

Seria bom se houvesse uma biblioteca de código aberto independente e fácil de usar. Corri para esse mesmo problema há 10 anos e fica frustrante. A certa altura, usei o GSL para C e escrevi wrappers em C ++, mas com o C ++ moderno - especialmente usando as vantagens dos modelos de expressão - não devemos mexer com C no século XXI. Apenas meu tuppencehapenny.


2
O tatu possui uma sintaxe deliberada do tipo Matlab, para que seja fácil de usar. Não sei ao certo o que você quer dizer com "falta documentação ... detalhes sobre o LAPACK". A documentação documenta claramente todas as funções disponíveis pelo usuário, além de exemplos de como usá-las. O ponto inteiro sobre uma biblioteca de wrapper C ++ é abstrair a complexidade e a verbosidade do LAPACK. Você sempre pode procurar a fonte se quiser ver como o Armadillo chama LAPACK.
Mtall

Sobre a decomposição QR em Eigen, você quer dizer Eigen2 ou Eigen3?
Qed 23/07

11

Se você está procurando matriz de alto desempenho / álgebra linear / otimização em processadores Intel, eu examinaria a biblioteca MKL da Intel.

O MKL é cuidadosamente otimizado para um desempenho rápido em tempo de execução - em grande parte, com base nos padrões muito maduros do BLAS / LAPACK fortran. E seu desempenho é escalonado com o número de núcleos disponíveis. A escalabilidade viva-voz com núcleos disponíveis é o futuro da computação e eu não usaria nenhuma biblioteca matemática para um novo projeto que não suporta processadores com vários núcleos.

Muito brevemente, inclui:

  1. Operações básicas vetor-vetor, matriz-vetor e matriz-matriz
  2. Fatoração matricial (LU decomp, eremita, esparsa)
  3. Problemas de ajuste de mínimos quadrados e autovalores
  4. Solucionadores de sistemas lineares esparsos
  5. Solucionador de mínimos quadrados não lineares (regiões confiáveis)
  6. Além disso, rotinas de processamento de sinal como FFT e convolução
  7. Geradores de números aleatórios muito rápidos (mersenne twist)
  8. Muito mais .... veja: link text

Uma desvantagem é que a API MKL pode ser bastante complexa, dependendo das rotinas necessárias. Você também pode dar uma olhada na biblioteca IPP (Integrated Performance Primitives), que é voltada para operações de processamento de imagem de alto desempenho, mas, no entanto, é bastante ampla.

Paulo

Software CenterSpace, bibliotecas .NET de matemática, centerspace.net


8

Ouvi coisas boas sobre Eigen e NT2 , mas também não as usei pessoalmente. Há também o Boost.UBLAS , que acredito estar demorando um pouco. Os desenvolvedores do NT2 estão construindo a próxima versão com a intenção de inseri-la no Boost, para que isso possa contar para alguma coisa.

Meu lin. alg. as necessidades não ultrapassam o caso da matriz 4x4, por isso não posso comentar sobre funcionalidades avançadas; Estou apenas apontando algumas opções.


Na minha experiência (matrizes maiores), o Boost.UBLAS é usado mais. No entanto, quando examinei, não gostei (principalmente por causa da documentação), então me concentrei em Eigen. Eigen tem um módulo de geometria , mas eu não o usei.
Jitse Niesen 5/09/09

Aparentemente, Eigen é usado por ROS (willow garage), Celestia, Koffice e libmv. Vejo algumas conversas sobre o UBLAS, mas foi difícil encontrar projetos que anunciam o uso. O mesmo vale para NT2. Você pode elaborar as coisas boas que ouviu?
Catskul

Ele estava em uma discussão na lista de email do Boost sobre como adicionar uma biblioteca moderna do LinAlg ao Boost - Eigen e NT2 foram mencionados como possíveis candidatos, mas apenas os desenvolvedores do NT2 manifestaram interesse em segui-lo. As duas bibliotecas pareciam decentes; como você disse, Eigen é um pouco mais popular e também mais C ++; O NT2 foi projetado para imitar o MATLAB, tanto quanto possível.
9119 Jeff Hardy

8

Eu sou novo neste tópico, então não posso dizer muito, mas o BLAS é praticamente o padrão na computação científica. O BLAS é na verdade um padrão de API, que possui muitas implementações. Sinceramente, não tenho certeza de quais implementações são mais populares ou por quê.

Se você também deseja fazer operações comuns de álgebra linear (sistemas de resolução, regressão de mínimos quadrados, decomposição etc.), procure no LAPACK .


7

E o GLM ?

Ele é baseado na especificação OpenGL Shading Language (GLSL) e lançado sob a licença MIT. Claramente direcionado a programadores gráficos


bem, ele fornece vetor de programação gráfica e matrizes. ele introduz uma boa quantidade de sobrecarga para manter a conformidade com o GLSL (se você pode fazê-lo no GLSL, na maioria das vezes fazê-lo no GLSL é melhor, especialmente no GL 4.x), e perde muitas primitivas de programação gráfica (frustum, AABB, BB, elipsóide ) Sua interface swizzle é obesa. Uma alternativa muito melhor seria se tivesse funções ".xyzz ()" geradas com alguma geração de código. É perfeito quando você precisa criar um protótipo de aplicativos opengl e começa a mostrar seus lados negativos em projetos maiores. nunca codifique uma biblioteca de matemática.
CoffeDeveloper 03/04

5

Acrescentarei voto a Eigen: portamos muitos códigos (geometria 3D, álgebra linear e equações diferenciais) de diferentes bibliotecas para esta - melhorando o desempenho e a legibilidade do código em quase todos os casos.

Uma vantagem que não foi mencionada: é muito fácil usar o SSE com Eigen, o que melhora significativamente o desempenho das operações 2D-3D (onde tudo pode ser aumentado para 128 bits).


1
A coisa toda "se você fizer isso, então certifique-se de ..." me parece uma bandeira vermelha. Até agora, encontrei duas vezes esses problemas e comecei a usá-lo. Eu realmente esperava não sobrecarregar os desenvolvedores futuros por conhecer todos os tipos de idiossincrasias de cada biblioteca, incluindo: especificamente os problemas de alinhamento em que ocorre um erro se você não usar determinadas macros cada vez que tiver membros e o fato de que eles espalharam a funcionalidade de cada indivíduo classes em vários cabeçalhos. Sozinho, isso pode não me impedir de escolher, mas é um sinal de alerta.
Catskul 17/09/09

1
O alinhamento e essa macro são importantes apenas se você usar o SSE, o que não é de forma alguma necessário. E se você usar o SIMD, esses problemas surgirão independentemente da biblioteca usada. Pelo menos o Eigen não apenas falha, mas fornece mensagens de erro significativas que apontam diretamente para o problema.
ima

E existe uma maneira fácil de evitar macro de alinhamento - use ponteiros ou referências como membros.
ima

1
Eu não acho que isso seja verdade. Não usei nenhuma opção especial de SSE e tive várias falhas depois de usá-lo com contêineres stl. Sim, eu sei que isso lhe fornece mensagens úteis, e Sim, eu sei que existem instruções especiais, mas esse é o meu ponto. Não quero sobrecarregar outros desenvolvedores com instruções especiais para cada biblioteca incluída. A coisa de não passar por valor, por exemplo, é demais.
Catskul 21/09/09

Acabei de descobrir que o ramo de desenvolvimento mais recente tem algumas definições que você pode usar para desativar o alinhamento e evitar os problemas relacionados.
Catskul 21/09/09

4

Ok, acho que sei o que você está procurando. Parece que o GGT é uma solução muito boa, como sugeriu Reed Copsey.

Pessoalmente, montamos nossa própria pequena biblioteca, porque lidamos muito com pontos racionais - muitos NURBS e Beziers racionais.

Acontece que a maioria das bibliotecas de gráficos 3D faz cálculos com pontos projetivos que não têm base na matemática projetiva, porque é isso que dá a resposta que você deseja. Acabamos usando pontos de Grassmann, que têm uma base teórica sólida e diminuímos o número de tipos de pontos. Os pontos de Grassmann são basicamente os mesmos cálculos que as pessoas estão usando agora, com o benefício de uma teoria robusta. Mais importante, isso torna as coisas mais claras em nossas mentes, por isso temos menos bugs. Ron Goldman escreveu um artigo sobre pontos de Grassmann em computação gráfica chamado "Sobre os fundamentos algébricos e geométricos da computação gráfica" .

Não está diretamente relacionado à sua pergunta, mas é uma leitura interessante.


É intencionalmente aberto, pois não sei quais são as vantagens e desvantagens. Provavelmente, é justo dizer que a geometria é a nossa principal preocupação, a dimensionalidade da geometria não é clara. Atualmente, é 2/3 (2 + tempo) e, hipoteticamente, pode ser bastante alto (3dims + tempo + mapas de custos com várias tonalidades).
Catskul 4/09/09

Estou de acordo com a pergunta. Por exemplo, muitas aplicações desse tipo precisam de desempenho em tempo real (comportamento consistente do tempo), enquanto muitas outras são perfeitas, renunciando à consistência e / ou à velocidade da precisão.
TED

Então você está dizendo que das bibliotecas que você investigou, nenhuma cuidou de NURBS e Beziers? Algum motivo específico para não pegar uma das bibliotecas existentes e criar o suporte NURBS e Bezier ao lado?
Catskul

O que eu estava tentando dizer é que NURBS e Beziers racionais usam pontos de controle racional muito mais do que a maioria das aplicações 3D, então estávamos cometendo mais erros. Normalmente, a maioria dos aplicativos 3D só tem pontos e vetores 3d baunilha até depois de passar pela transformação de perspectiva. Muitos dos nossos algoritmos tem que ser capaz de tratar corretamente ponderada pontos / racionais / projetivas e cartesianas, indo e voltando, etc.
tfinniga


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.