суббота, 16 апреля 2016 г.

Maxima. Скрипты

Было бы странно, если б такая умная система, как Maxima, не умела работать со скриптами... К счастью, она это умеет. Всё что нужно сделать для запуска скрипта, это вызвать функцию batch(имя_файла). Если файл лежит не в стандартных папках программы, может помочь дополнительная функция: batch(file_search(имя_файла)).


Рассмотрим ещё несколько полезных моментов. Комментарии в Maxima оформляются в стиле языка си, т.е. текст между /* и */ считается комментарием. Данные из командной строки считывает функция read(выражение1, выражение2, ...). Вывод может осуществить функция print(выражение1, выражение2, ...) или display( ... ), первая из них объединит свои аргументы в единое предложение, а вторая разобьёт по строкам. Это, конечно, далеко не все средства ввода-вывода, даже для перечисленных функций есть аналоги, но для написания простейшего скрипта вполне достаточно.

У меня периодически возникает желание посмотреть, как выглядит график той или иной функции. Конечно, можно просто вызвать plot2d и указать ей интервал, но хотелось бы, чтобы программа сама его определила, а ещё нашла, по возможности, нули функции и точки экстремума. Попробуем написать соответствующий скрипт.
Здесь определены некоторые вспомогательные функции, которые нам пригодятся для решения поставленной задачи. Вообще, будем рассматривать только выражения с переменной "x". Нули (корни) выражения находит функция solve(), но она возвращает список вида "x = ...", а нас интересуют только числа, поэтому и нужна функция root_list, которая из полученного списка выделяет только правые части выражений (rhs).  Если solve() не может выразить корень в явном виде, она возвращает рекуррентное соотношение, типа "x = sin(x)", что нам тоже не подходит. Функция num_filter() "просеивает" список выражений, оставляя в нём только те, что являются числами. Обе функции работают со списками и написаны в духе функционального программирования. Осталось решить вопрос с границами графика по оси абсцисс. Для этого объединим списки корней самого выражения и его производной (точки экстремума) и будем считать, что эти точки для нас наиболее интересны. Функция get_bounds() анализирует передаваемый ей список чисел, если он пустой, используется интервал по-умолчанию, если в нём одно значение, интервал смещается, в противном случае отобразим все, что лежит между минимальным и максимальным значениями плюс 10% по бокам. 

Теперь о самой функции для построения графика.
Т.к. действия в ней выполняются последовательно, все они размещены в функции block(). Сначала пользователю предлагается ввести выражение с переменной x, затем вычисляются корни для самого выражения и его производной, результат используется для определения границ графика, после чего на экран выводятся списки нулей и экстремумов, а также строится сам график.

Для запуска скрипта не обязательно заходить в графическую оболочку программы, можно в консоли ввести команду
maxima -b имя_файла
и получить тот же результат. Однако сразу по завершении работы окно графика закроется вместе с Maxima. Чтобы этого не произошло, добавлена строка readonly("Готово"), которая будет ожидать от пользователя какого-либо ввода, и только после этого функция (и программа), будут считаться выполненными.

Полный вариант описанного скрипта: gr.mac.

P.S. В своём параллельном блоге я описал (написал) программу, которую можно использовать для расчётов в матричной оптике. Но поскольку упрощение и анализ результата - задача более нетривиальная, чем перемножение матриц, результат работы программы сохраняется в файл, который можно загрузить в Maxima через batch(), и уже в ней проводить дальнейшие изыскания.

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

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