Это действительно зависит от того, насколько сложен код и математика. Сам код должен - как всегда - быть как можно более самодокументируемым. Правильно присваивайте имена переменным, реализуйте логические и лаконичные методы (а не мега-функции), добавляйте встроенную документацию, где это уместно (т.е. когда неясно, что на самом деле делает код).
Если вы используете неочевидный алгоритм, добавьте ссылку на ссылку на источник. Это разумная практика, поскольку она дает разработчику очень быстрый способ выяснить, что вы делаете. Как я уже сказал, это полезно, если это неочевидный, но сложный алгоритм. Это должно доказать, что (а) вы делаете что-то, что имеет смысл, и (б) кто-то продемонстрировал, что это работает.
Хорошим примером может служить работа по нечеткому сопоставлению текста. Я провел серьезное исследование алгоритмов и реализовал так называемый «алгоритм Смита-Уотермана» (который фактически используется для последовательностей ДНК, но в целом применяется к «сопоставлению»). Поэтому вместо того, чтобы просто реализовать алгоритм, я нашел ссылки в Интернете и включил одну или две ссылки. Как и выше, это демонстрирует, что (а) мой алгоритм соответствует опубликованному алгоритму, и (б) алгоритм был рассмотрен и показан для работы.
Однако это не обязательно объясняет, как работает код и что должны делать различные классы. Когда вы собираетесь написать «настоящую» документацию - руководство для разработчиков системы - вы должны объяснить, что вы сделали, и предоставить достаточно информации для будущей поддержки. По моему мнению, этот документ должен быть читаемым технически неосведомленным человеком; он не должен быть «тупым», но он должен исключать жаргон и не полагаться на предполагаемые знания.