Recomendações para um solucionador de álgebra linear denso baseado em C ou C ++ leve / sem instalação

9

A maior parte da minha programação são códigos de pesquisa pontuais em C para uso próprio. Nunca distribuí nenhum código para outros colaboradores que não sejam colaboradores próximos. Eu desenvolvi um algoritmo que estou publicando em uma revista científica. Desejo fornecer o código fonte e talvez o código executável no suplemento online do artigo. Um colega solicitou que eu fizesse uma generalização no algoritmo que exigia que eu escrevesse em C ++ (ack!) E que exige que eu resolva pequenos sistemas lineares densos. Se eu conseguir obter uma base de usuários para o algoritmo, será em parte porque a barra de entrada para usá-lo é baixa (como no chão). Usuários em potencial não instalam bibliotecas etc. para usar o código. Quero que o código seja totalmente independente e livre de qualquer licença. Eu poderia simplesmente escrever meu próprio solucionador tirando algo de Golub e van Loan, mas prefiro usar um solucionador de baunilha que alguém já tenha escrito, se houver algum por aí. Sugestões apreciadas. Obrigado!

jep
fonte
Caro jep, bem-vindo ao fórum. Sua pergunta é muito semelhante à que está aqui: scicomp.stackexchange.com/questions/351/…
GertVdE 4/12
Os solucionadores de bibliotecas tendem a ser complexos e grandes em prol da robustez, eficiência e generalidade. Se seus problemas são muito pequenos e razoavelmente bem condicionados, sugiro que você escreva sua própria mini-implementação.
Stefano M
@GertVdE, obrigado pela resposta rápida a esta pergunta. Fico desconfortável ao me vincular à pergunta "Recomendações ..." porque tanto a pergunta quanto a resposta principal são gerais demais para fornecer ajuda em situações como essa. Se você quiser discutir mais sobre isso, sugiro que o levemos ao levemos à sala de bate-papo scicomp .
Aron Ahmadia 04/10/12
@AronAhmadia: Eu acho que a única maneira de começar a resolver alguns desses debates é começar a implementar uma programação de ciência da computação computacional que depende tanto da linguagem quanto da biblioteca. Se o código estiver claro e os problemas de configuração puderem ser resolvidos (usando um script de shell, Chef ou Puppet), os debates sobre desempenho poderão ser resolvidos (ou tornados concretos), basta executar o código e cronometrá-lo em um máquina de referência. Os debates sobre clareza podem ser resolvidos (ou pelo menos tornados mais concretos), observando o código. Caso contrário, continuaremos tendo os mesmos argumentos.
Geoff Oxberry

Respostas:

7

Eu sugeriria duplicar exatamente a interface Lapack para a função que você precisa, provavelmente você só precisa dgesv. Dessa forma, as pessoas que possuem o Lapack instalado podem simplesmente criar um link para ele e ele simplesmente funcionará. Para pessoas que não possuem o Lapack instalado, você fornece sua própria implementação simples dessa função ou, possivelmente, a implementa usando Eigen ou FLENS, conforme sugerido por outros.

Na terra de Fortran, a biblioteca Lapack é tão padrão que a maioria das pessoas simplesmente a usa e é isso, em vez de fornecer suas próprias implementações.

Ondřej Čertík
fonte
+1 Acrescente a isso o fato de que a maioria das distribuições Linux (pelo menos com base no Debian) possui pacotes binários no repositório e todas as bibliotecas matemáticas fornecidas pelo fornecedor (MKL, SunPerf, ACML, ESSL etc.) o carregam. Você deve sempre usar as bibliotecas padrão o máximo possível, mas se estiver no Windows / Mac, é melhor usar algo C, pois instalar um compilador Fortran gratuito (gfortran) nelas é uma quantidade de trabalho, pelo que ouvi dizer.
Stali #
Eu usei lapack muitas vezes, mas atualmente não estou em terra de fortran. Espero que a distribuição estatística das plataformas em que minha base de usuários seja executada seja semelhante à do mundo em geral, o que significa principalmente janelas, uma porcentagem menor de macs e uma porcentagem ainda menor de * nix. Minha experiência com o Windows é mínima e eu prefiro continuar assim. É por isso que eu quero um código C ++ independente. Eu acho que terei que fornecer a alguns dos meus usuários ajuda para obter o código para compilar e executar. Eu preciso minimizar o trabalho necessário para fazer isso.
jep
Se sua base de usuários é Windows / Macs, é melhor usar uma implementação simples baseada em C (talvez até a sua). Um pacote que é difícil de instalar ou depende de 5 outras bibliotecas, especialmente quando não há repositório de pacotes binários de primeira classe (como o Debian) disponível, desligará seus usuários por um longo tempo. Lembre-se de que a maioria dos usuários de Windows / Mac está acostumada a instalar um clique. A facilidade de uso triunfa sobre todo o resto.
Stali #
5

Um erro muito antigo que muitas pessoas cometem ao iniciar a computação científica está assumindo que você precisa escrever todo o seu código no mesmo idioma. Eu acho que isso se deve em grande parte a razões históricas, quando não ficou claro como fazer com que os programas compilados se comuniquem entre si, mesmo nas versões do mesmo compilador. Dito isto, neste caso, se você estiver usando C ++ de qualquer maneira, existem várias bibliotecas de modelos muito boas de cabeçalho C ++ que podem atender às suas necessidades.

Como você está distribuindo seu código por razões acadêmicas e gostaria de incorporar um solucionador de álgebra linear denso em seu código, eu recomendo fortemente que você considere Eigen . O Eigen foi licenciado sob a Mozilla Public License e é uma biblioteca somente de cabeçalho. Isso significa que você pode distribuir o Eigen com o seu código na forma de origem (isso não impõe restrições de licenciamento ao seu código) e você terá acesso a seus recursos gerais, incluindo solucionadores lineares densos e extremamente eficientes. Como o GertVdE menciona, você tem várias outras opções .

Aron Ahmadia
fonte
Eu estava esperando por um único arquivo. Eu faço programação científica há um bom tempo. Eu misturei linguagens como C e fortran um pouco, mas para este projeto eu realmente quero apenas um arquivo contendo todo o meu código-fonte. Suponho que eu poderia colocar um solucionador de C no código C ++, o que não seria um grande problema. Quero principalmente manter o código o mais simples possível. LU com pivotante deve ser adequada. Vou olhar para Eigen. Obrigado!
jep
@ep, você também pode tentar escolher as rotinas necessárias do CLAPACK se realmente não se importa com o desempenho.
Aron Ahmadia 05/10/12
Existem boas razões para escrever todo o código dependente no mesmo idioma, em particular nos ambientes HPC, você tem problemas estranhos de compilador / vinculação e problemas de interface de 32/64 bits. Por exemplo, como sei a largura de um número inteiro para bibliotecas internas? Como sei com certeza qual compilador foi usado para uma biblioteca interna e posso vincular esse outro compilador a ele? Ter tudo em um idioma simplifica muitos desses problemas. E sim, deve haver documentação fornecida pelos mantenedores de cluster, mas na maioria das vezes não existe.
Victor Liu
@VictorLiu - Os problemas aos quais você está se referindo são mais fortemente associados às implementações do que aos idiomas. O espaço para comentários é um péssimo lugar para entrar em uma discussão séria, mas fico feliz em conversar com você ou em outro lugar, se você quiser que eu expanda meus pensamentos sobre isso.
Aron Ahmadia 06/10/12
4

Se você deseja um solucionador confiável para sistemas de equações lineares, recomendo o FLENS . Ele contém uma reimplementação exata do LAPACK (até reproduz os mesmos erros de arredondamento que o LAPACK se uma implementação BLAS de thread único for usada). Isso é verdade para todos funções FLENS-LAPACK (junto com as funções utilitárias, cerca de 100 rotinas).

O FLENS está sob uma licença BSD e, portanto, permite ser incorporado em produtos proprietários.

FLENS é apenas cabeçalho e, se você precisar apenas de um subconjunto de FLENS, posso fornecer uma versão simplificada que contém apenas as funções necessárias. O FLENS vem com sua própria implementação de referência BLAS. Mas, opcionalmente, seus usuários podem vincular-se a bibliotecas BLAS otimizadas, como ATLAS, OpenBLAS ou GotoBALS. Para matrizes grandes, isso proporciona um ganho de desempenho de cerca de 40% em comparação com o Eigen.

E sim, Eigen também usa o conjunto de testes LAPACK para verificar seus resultados. Eles fazem isso para 3 funções (Lu, Cholesky e Autovalores / vetores de uma matriz simétrica). No entanto, o cálculo de autovalores / vetores de uma matriz não simétrica falharia no conjunto de testes LAPACK.

Disclaimer: Sim, FLENS é meu bebê! Isso significa que codifiquei cerca de 95% e todas as linhas de código valeram a pena.

Michael Lehn
fonte
11
Michael - Por favor, considere isso um aviso amigável de que você precisa seguir a regra no FAQ sobre a divulgação de afiliação .
Aron Ahmadia 05/10/12
Claro, mas você também pode reformular suas postagens de 'Eu recomendo fortemente que você considere Eigen' para algo como 'existe, por exemplo, Eigen'. Neste caso, excluo minhas observações sobre Eigen (embora todas sejam comprovadamente verdadeiras), incluindo esta.
Michael Lehn
11
Seus comentários sobre Eigen não estão em questão aqui (embora pareçam estranhos para mim). Você é o desenvolvedor principal do FLENS. Se você deseja recomendá-lo em uma resposta aqui, deve divulgar sua afiliação como desenvolvedor do projeto.
Aron Ahmadia 05/10/12
Ah, ok então. Eu pensei que era implicitamente claro por '... eu posso te dar ...'. A divulgação neste formulário está correta?
Michael Lehn
2
Eu só quero dizer obrigado por fazer isso; Eu tinha planos semelhantes de reimplementar grande parte do Lapack em C ++. No entanto, parece que para a maioria das rotinas avançadas (autovalor), você simplesmente adia a chamada para o Lapack; portanto, é um pouco de publicidade falsa dizer que você reimplementa tudo. Por outro lado, na verdade eu tenho portado a fonte ZGEEV para C ++ no RNP , embora algumas partes ainda estejam na indexação baseada em 1 a partir da conversão automática.
Victor Liu