пятница, 23 марта 2012 г.

Научная жизнь

осторожно, бесстыдная самореклама
Вчера наконец-то послали (с Ваней и А.И.) в архив работу по квантовой механике. Работа находилась в вялотекущем состоянии довольно долго, может год, может больше. Причина такого торможения --- в том, что для продвижения приходилось преодолевать некоторые предрассудки, весьма распространенные среди теор. физиков. Мое отношение к задаче в разные моменты времени можно выразить различными комбинациями "это интересно", "это патологично" и "это тривиально".
Ну кто бы мог подумать, что с виду нормальный, эрмитовый гамильтониан может привести к эффективно неупругому рассеянию? Кто бы мог подумать, что стационарные решения могут быть локально неинтегрируемые с квадратом, да и просто невозводимые в квадрат, а кроме того, еще и странно вырожденными в радиальной задаче? И при этом пригодными для разложения временного решения?

Ниже --- анимация рассеяния сферического пакета, локализованного изначально на больших $r$. Отразилась только часть пакета, а часть "прилипла". Если вам такая динамика не кажется странной, или даже невозможной, значит вы плохо учили квантовую механику.
P.S. Теперь на очереди другая задача --- написание пакета, реализующего давнюю тайную мечту любого ученого --- решение всех проблем в автоматическом режиме, включая в перспективе и написание статьи с изложенными результатами. Когда напишу --- моя миссия на работе сведется к нажатию кнопки утром и засылке в архив готовой работы вечером. Пока написанное выглядит так:

воскресенье, 18 марта 2012 г.

Нафига он нужен, этот Replace

В рамках программы подготовки к неизбежно приближающемуся склерозу.
Есть в Математике такая функция Replace. Долгое время я ее считал практически бесполезной, в отличии от ее старших родственников  ReplaceAll (/.) и ReplaceRepeated(//.). Но недавно я осознал, что эта функция является мощной заменой функции Switch. А именно,
Switch[expr, form1, value1, form2,value2,...]
в подавляющем большинстве случаев можно заменить на
Replace[expr, {form1:> value1, form2:>value2,...}]
Преимущество в том, что именнованные части паттерна formi можно использовать при построении valuei. Ну вот, теперь я понимаю зачем нужна функция Replace. Жалко только, что теперь я не понимаю зачем нужна функция Switch.
Вот, кстати, пример использования Replace  в процедуре SplitCases, которую, я думаю, стоит включить в следующий релиз Математики:
SplitCases[l_List,ps_List]:=Module[
  {pls=Table[{},{Length[ps]}],pn},
  Append[pls,#]&[Replace[l,

MapIndexed[pn:#:>(pls[[First@#2]]=Append[pls[[First@#2]],pn];Unevaluated[Sequence[]])&,ps],{1}]]]

вторник, 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" в рабочей директории, поэтому не теряются от сессии к сессии.