вторник, 13 марта 2012 г.

Полезность.

Поскольку занимаюсь в настоящий момент добиванием пакета на Математике, пытаюсь облегчить себе жизнь всеми возможными способами. Сегодня аспирант навел на полезную мысль. Нет, говорит, в Математике тестов. Выяснилось, что речь о следующем. Когда отлаживаешь какой-нибудь пакет, хорошо иметь набор тестов, который запускается после модификации пакета и сравнивает вновь получившиеся результаты с теми, что получались до модификации. Ну, действительно хорошо. Сказано-сделано, вот простейший пакет, призванный помочь пакетописателям. Работает так. Допустим, что ценой неимоверных усилий была написана функция, вычисляющая числа Фиббоначи:
f[1]=f[2]=1;
f[n_Integer?Positive]:=f[n-1]+f[n-2];
Работает функция правильно, но долго, и хочется ее переписать так, чтобы она работала быстро. И тут вы узнаете, что есть чудная формула\[f_n=\frac{\varphi ^n-(-\varphi )^{-n}}{\sqrt{5}}\,.\] Хочется переписать функцию, но страшно, вдруг где-нибудь сделаешь ошибку. Тогда делаем так: загружаем пакет Tests.m и со старым определением f[n] создаем некоторое количество тестов:
<<"Tests.m"
SaveTest[f[15],"Fib15"];
SaveTest[f[20],"Fib20"];
SaveTest[f[30],"Fib30"];

Затем меняем наше определение
Clear[f];
f[n_Integer?Positive]:=Expand[(((1 - Sqrt[5])/2)^n 
                              +((1 + Sqrt[5])/2)^n)/Sqrt[5]]

И проверяем на уже известных примерах:
RunTests["Fib*"]
Получаем гневные сообщения:
Fib15 Failed.
Input:f[15] -> 1364/Sqrt[5]
Output:610 -> 610
Fib20 Failed.
Input:f[20] -> 15127/Sqrt[5]
Output:6765 -> 6765
Fib30 Failed.
Input:f[30] -> 1860498/Sqrt[5]
Output:832040 -> 832040
{"Fib15" -> "Failed", "Fib20" -> "Failed", "Fib30" -> "Failed"}
 
Значит, где-то затупили... Ага, забыли минус, исправляем:
Clear[f];
f[n_Integer?Positive]:=Expand[(-((1 - Sqrt[5])/2)^n 
                              + ((1 + Sqrt[5])/2)^n)/Sqrt[5]]
Ну вот, теперь все в порядке:
Fib15 Passed.
Fib20 Passed.
Fib30 Passed.
{"Fib15" -> "Passed", "Fib20" -> "Passed","Fib30" -> "Passed"}
Ну, там есть еще некоторые возможности, желающим глядеть в код или использовать ?"Tests`*". Кстати, тесты хранятся в виде файла "tests.tst" в рабочей директории, поэтому не теряются от сессии к сессии.

Комментариев нет:

Отправить комментарий