Isso realmente depende de quão complicado é o código e a matemática. O próprio código deve - como sempre - ser o mais documentado possível. Nomear variáveis corretamente, implementar métodos lógicos e concisos (em vez de mega-funções), adicionar documentação em linha onde apropriado (ou seja, quando não for óbvio o que o código está realmente fazendo).
Se você estiver usando um algoritmo não óbvio, adicione um link a uma referência à fonte. Essa é uma prática razoável, pois fornece ao desenvolvedor uma maneira muito rápida de descobrir o que você está fazendo. Como eu disse, isso é útil se for um algoritmo não óbvio, porém complexo. Isso deve provar que (a) você está fazendo algo que faz sentido; e (b) alguém demonstrou que funciona.
Um bom exemplo é um trabalho que fiz sobre a correspondência de texto difuso. Fiz uma pesquisa substancial sobre algoritmos e implementei o que é conhecido como 'algoritmo Smith-Waterman' (que é realmente usado para sequências de DNA, mas se aplica geralmente à 'correspondência'). Então, em vez de simplesmente implementar o algoritmo, encontrei referências on-line e incluí um link ou dois. Como acima, isso demonstra que (a) meu algoritmo corresponde ao algoritmo publicado e (b) o algoritmo foi revisado e mostrado para funcionar.
No entanto, isso não explica necessariamente como o código funciona e o que as várias classes devem fazer. Ao escrever uma documentação 'real' - um guia do desenvolvedor para o sistema - você deve explicar o que fez e fornecer informações suficientes para suporte futuro. Na minha opinião, este documento deve ser legível por uma pessoa tecnicamente agnóstica; não precisa ser "emburrecido", mas deve excluir o jargão e não confiar no conhecimento assumido.