This is maxima.info, produced by makeinfo version 6.5 from maxima.texi.

This is a Texinfo Maxima Manual

   Copyright 1994,2001 William F. Schelter

START-INFO-DIR-ENTRY
* Maxima: (maxima).     A computer algebra system.
END-INFO-DIR-ENTRY


File: maxima.info,  Node: Функции и переменные для картин,  Next: Функции и переменные для карты мира,  Prev: Функции и переменные пакета draw,  Up: Пакет draw

46.3 Функции и переменные для картин
====================================

 -- Функция: make_level_picture (<data>)
 -- Функция: make_level_picture (<data>,<width>,<height>)
     Возвращает объект типа <картина> уровней.  ‘make_level_picture
     (<data>)’ строит объект <картина> из матрицы <data>.
     ‘make_level_picture (<data>,<width>,<height>)’ строит объект из
     списка чисел; в этом случае должны быть заданы оба параметра
     <width> и <height>.

     Возвращает объект типа <картина>, содержащий следующие четыре
     части:

       1. символ ‘level’
       2. ширина картины
       3. высота картины
       4. массив целых чисел в пределах от 0 до 255, описывающих
          пикселы.  Аргумент <data> должен содержать только числа в
          пределах от 0 до 255; отрицательные числа заменяются 0, а те,
          что превышают 255, заменяются на 255.

     Пример:

     Картина уровней из матрицы.
          (%i1) load("draw")$
          (%i2) make_level_picture(matrix([3,2,5],[7,-9,3000]));
          (%o2)         picture(level, 3, 2, {Array:  #(3 2 5 7 0 255)})

     Картина уровней из числового списка.
          (%i1) load("draw")$
          (%i2) make_level_picture([-2,0,54,%pi],2,2);
          (%o2)            picture(level, 2, 2, {Array:  #(0 0 54 3)})

 -- Функция: picturep (<x>)
     Возвращает ‘true’, если аргумент является правильно сформированной
     картиной, и ‘false’ в противном случае.

 -- Функция: picture_equalp (<x>,<y>)
     Возвращает ‘true’, если картины совпадают, и ‘false’ в противном
     случае.

 -- Функция: make_rgb_picture (<redlevel>,<greenlevel>,<bluelevel>)
     Возвращает rgb-цветную <картину>.  Все три аргумента должны быть
     картинами уровней, с уровнями, задающими красный, зеленый и синий
     цвета соответственно.

     Возвращаемый объект <картина> содержит следующие четыре части:

       1. символ ‘rgb’
       2. ширина картины
       3. высота картины
       4. целый массив длины <3*width*height> с данными о пикселах со
          значениями от 0 до 255.  Каждый пиксел представляется тремя
          последовательными числами (красный, зелены, синий).

     Пример:

          (%i1) load("draw")$
          (%i2) red: make_level_picture(matrix([3,2],[7,260]));
          (%o2)           picture(level, 2, 2, {Array:  #(3 2 7 255)})
          (%i3) green: make_level_picture(matrix([54,23],[73,-9]));
          (%o3)           picture(level, 2, 2, {Array:  #(54 23 73 0)})
          (%i4) blue: make_level_picture(matrix([123,82],[45,32.5698]));
          (%o4)          picture(level, 2, 2, {Array:  #(123 82 45 33)})
          (%i5) make_rgb_picture(red,green,blue);
          (%o5) picture(rgb, 2, 2,
                        {Array:  #(3 54 123 2 23 82 7 73 45 255 0 33)})

 -- Функция: take_channel (<im>,<color>)
     Если параметр <color> равен ‘red’, ‘green’ или ‘blue’, то функция
     ‘take_channel’ возвращает соответствующий цветовой канал картины
     <im>.  Пример:

          (%i1) load("draw")$
          (%i2) red: make_level_picture(matrix([3,2],[7,260]));
          (%o2)           picture(level, 2, 2, {Array:  #(3 2 7 255)})
          (%i3) green: make_level_picture(matrix([54,23],[73,-9]));
          (%o3)           picture(level, 2, 2, {Array:  #(54 23 73 0)})
          (%i4) blue: make_level_picture(matrix([123,82],[45,32.5698]));
          (%o4)          picture(level, 2, 2, {Array:  #(123 82 45 33)})
          (%i5) make_rgb_picture(red,green,blue);
          (%o5) picture(rgb, 2, 2,
                        {Array:  #(3 54 123 2 23 82 7 73 45 255 0 33)})
          (%i6) take_channel(%,'green);  /* simple quote!!! */
          (%o6)           picture(level, 2, 2, {Array:  #(54 23 73 0)})

 -- Функция: negative_picture (<pic>)
     Возвращает негатив картины (<уровней> или <rgb>).

 -- Функция: rgb2level (<pic>)
     Преобразует <rgb> картину в картину <уровней> усреднением красного,
     зеленого и синего каналов.

 -- Функция: get_pixel (<pic>,<x>,<y>)
     Возвращает пиксел из картины.  Координаты <x> и <y> должны быть от
     0 до ‘width-1’ и ‘height-1’ соответственно.

 -- Функция: read_xpm (<xpm_file>)
     Читает файл в формате xpm и возвращает объект типа картина.


File: maxima.info,  Node: Функции и переменные для карты мира,  Prev: Функции и переменные для картин,  Up: Пакет draw

46.4 Функции и переменные для карты мира
========================================

 -- Функция: region_boundaries (<x1>,<y1>,<x2>,<y2>)
     Определяет многоугольные сегменты из глобальной переменной
     ‘boundaries_array’, содержащиеся внутри прямоугольника с вершинами
     (<x1>,<y1>) (верхний левый) и (<x2>,<y2>) (нижний правый).

     Пример:

     Возвращает номера сегментов для северной Италии.
          (%i1) load("draw")$
          (%i2) load("worldmap")$
          (%i3) region_boundaries(10.4,41.5,20.7,35.4);
          (%o3)                [1846, 1863, 1864, 1881, 1888, 1894]
          (%i4) draw2d(geomap(%))$

 -- Функция: numbered_boundaries (<nlist>)
     Строит многоугольные сегменты (границы), обозначаемые числами
     (координаты в ‘boundaries_array’).  Эта функция очень полезна при
     создании географических объектов.

     Пример:

     Карта Европы, с границами, обозначенными номерами компонент в
     ‘boundaries_array’.
          (%i1) load("draw")$
          (%i2) load("worldmap")$
          (%i3) european_borders:
                     region_boundaries(-31.81,74.92,49.84,32.06)$
          (%i4) numbered_boundaries(european_borders)$

 -- Функция: make_polygon (<nlist>)
     Возвращает объект ‘polygon’, построенный из индексов границ.
     Аргумент <nlist> – список компонент в массиве ‘boundaries_array’.

     Пример:

     Бутан определяется номерами компонент 171, 173 и 1143, так что
     ‘make_polygon([171,173,1143])’ добавляет массив координат
     ‘boundaries_array[171]’, ‘boundaries_array[173]’ и
     ‘boundaries_array[1143]’ и возвращает объект ‘polygon’, пригодный
     для изображения функцией ‘draw’.  Для того чтобы избежать сообщений
     о ошибках, массивы должны быть совместимы в том смысле, что два
     последовательных массива имеют общие предельные координаты.  В этом
     примере, две первые компоненты ‘boundaries_array[171]’ равны двум
     последним компонентам ‘boundaries_array[173]’, и две первые
     компоненты ‘boundaries_array[173]’ равны двум первым компонентам
     ‘boundaries_array[1143]’.  В целом, числа 171, 173 и 1143 (именно в
     этом порядке) совместимы и цветной многоугольник может быть
     построен.
          (%i1) load("draw")$
          (%i2) load("worldmap")$
          (%i3) Bhutan;
          (%o3)                        [[171, 173, 1143]]
          (%i4) boundaries_array[171];
          (%o4) {Array:
                 #(88.750549 27.14727 88.806351 27.25305 88.901367 27.282221
                   88.917877 27.321039)}
          (%i5) boundaries_array[173];
          (%o5) {Array:
                 #(91.659554 27.76511 91.6008 27.66666 91.598022 27.62499
                   91.631348 27.536381 91.765533 27.45694 91.775253 27.4161
                   92.007751 27.471939 92.11441 27.28583 92.015259 27.168051
                   92.015533 27.08083 92.083313 27.02277 92.112183 26.920271
                   92.069977 26.86194 91.997192 26.85194 91.915253 26.893881
                   91.916924 26.85416 91.8358 26.863331 91.712479 26.799999
                   91.542191 26.80444 91.492188 26.87472 91.418854 26.873329
                   91.371353 26.800831 91.307457 26.778049 90.682457 26.77417
                   90.392197 26.903601 90.344131 26.894159 90.143044 26.75333
                   89.98996 26.73583 89.841919 26.70138 89.618301 26.72694
                   89.636093 26.771111 89.360786 26.859989 89.22081 26.81472
                   89.110237 26.829161 88.921631 26.98777 88.873016 26.95499
                   88.867737 27.080549 88.843307 27.108601 88.750549
                   27.14727)}
          (%i6) boundaries_array[1143];
          (%o6) {Array:
                 #(91.659554 27.76511 91.666924 27.88888 91.65831 27.94805
                   91.338028 28.05249 91.314972 28.096661 91.108856 27.971109
                   91.015808 27.97777 90.896927 28.05055 90.382462 28.07972
                   90.396088 28.23555 90.366074 28.257771 89.996353 28.32333
                   89.83165 28.24888 89.58609 28.139999 89.35997 27.87166
                   89.225517 27.795 89.125793 27.56749 88.971077 27.47361
                   88.917877 27.321039)}
          (%i7) Bhutan_polygon: make_polygon([171,173,1143])$
          (%i8) draw2d(Bhutan_polygon)$

 -- Функция: make_poly_country (<country_name>)
     Строит многоугольники, необходимые для изображения страны в цвете.
     Если есть острова, то страна определяется более чем одним
     многоугольником.

     Пример:

          (%i1) load("draw")$
          (%i2) load("worldmap")$
          (%i3) make_poly_country(India)$
          (%i4) apply(draw2d, %)$

 -- Функция: make_poly_continent (<continent_name>)
 -- Функция: make_poly_continent (<country_list>)
     Строит многоугольники, необходимые для изображение континента или
     списка стран в цвете.

     Пример:

          (%i1) load("draw")$
          (%i2) load("worldmap")$
          (%i3) /* A continent */
                make_poly_continent(Africa)$
          (%i4) apply(draw2d, %)$
          (%i5) /* A list of countries */
                make_poly_continent([Germany,Denmark,Poland])$
          (%i6) apply(draw2d, %)$


File: maxima.info,  Node: Пакет dynamics,  Next: Пакет f90,  Prev: Пакет draw,  Up: Top

47 Пакет dynamics
*****************

* Menu:

* Введение в пакет dynamics::
* Функции и переменные пакета dynamics::


File: maxima.info,  Node: Введение в пакет dynamics,  Next: Функции и переменные пакета dynamics,  Prev: Пакет dynamics,  Up: Пакет dynamics

47.1 Введение в пакет dynamics
==============================

Пакет ‘dynamics’ включает несколько функций, предназначенных для
создания различных графических представлений дискретных динамических
систем и фракталов, и реализацию метода Рунге-Кутта 4-го порядка для
численного решения систем дифференциальных уравнений.

   Для того, чтобы использовать функции данного пакета, его нужно
сначала загрузить командой ‘load("dynamics")’.

   Изменения введенные в Maxima 5.12

   Начиная с версии Maxima 5.12 пакет dynamics использует для построения
графиков функцию ‘plot2d’.  Команды, строящие графики (исключая ‘julia’
и ‘mandelbrot’), принимают любые опции команды ‘plot2d’, включая опции
выбора различных графических интерфейсов, выбора стилей и цвета, и
представления одной или обеих осей в логарифмической шкале.  Старые
опции <domain>, <pointsize>, <xcenter>, <xradius>, <ycenter>, <yradius>,
<xaxislabel> и <yaxislabel>, начиная с этой версии не действуют.

   Все программы теперь принимают произвольные имена переменных, а не
только <x> и <y>, как в старых версиях.  Обязательные параметры
изменились в двух программах: ‘evolution2d’ теперь требует список,
называющий явным образом две независимые переменные, а горизонтальный
предел для ‘orbits’ больше не требует указание размера шага.  Теперь
предел задает имя переменной, минимальное и максимальное значения.
Размер шага теперь может быть изменен с помощью опции <nticks>.
<nticks>.


File: maxima.info,  Node: Функции и переменные пакета dynamics,  Prev: Введение в пакет dynamics,  Up: Пакет dynamics

47.2 Функции и переменные пакета dynamics
=========================================

 -- Функция: chaosgame (‘[[’<x1>, <y1>‘]’...‘[’<xm>, <ym>‘]]’, ‘[’<x0>,
          <y0>‘]’, <b>, <n>, ..., options, ...);

     Реализует так называемую игру хаоса: сначала изображается начальная
     точка (<x0>, <y0>), далее одна из <m> точек ‘[’<x1>,
     <y1>‘]’...‘[’<xm>, <ym>‘]’ выбирается произвольным образом.
     Следующая точка изображается на отрезке, соединяющем предыдущую
     точку со случайно выбранной, на расстоянии от случайной точки
     равном длине этого отрезка, умноженной на <b> Процедура повторяется
     <n> раз.

 -- Функция: evolution (<F>, <y0>, <n>, ..., options, ...);

     Изображает <n+1> точек на 2-мерном графе, где горизонтальные
     координаты точек есть 0, 1, 2, ..., <n>, а вертикальные координаты
     есть соответствующие значения последовательности <y(n)>,
     определенной рекуррентным соотношением
                  y(n+1) = F(y(n))

     С начальным значением <y(0)> равным <y0>.  <F> должно быть
     выражением, которое зависит только от одной переменной (в примере,
     оно зависит от <y>, но может быть использована только одна
     переменная), <y0> должно быть вещественным числом, а <n> должно
     быть положительным целым.

 -- Функция: evolution2d (‘[’<F>, <G>‘]’, ‘[’<u>, <v>‘]’, ‘[’<u0>,
          <y0>‘]’, <n>, ..., options, ...);

     Изображает на двумерном графике первые <n+1> точек
     последовательности, определяемой двумерной дискретной динамической
     системой с рекуррентными соотношениями
                  u(n+1) = F(u(n), v(n))    v(n+1) = G(u(n), v(n))

     С начальными значениями <u0> и <v0>.  Выражения <F> и <G> должны
     зависеть только от двух переменных <u> и <v>, которые должны быть
     явно объявлены в списке.

 -- Функция: ifs (‘[’<r1>, ..., <rm>‘]’, ‘[’<A1>, ..., <Am>‘]’,
          ‘[[’<x1>, <y1>‘]’, ..., ‘[’<xm>, <ym>‘]]’, ‘[’<x0>, <y0>‘]’,
          <n>, ..., options, ...);

     Реализует метод системы повторяющихся функций (Iterated Function
     System).  Этот метод аналогичен игре хаоса, описанной в функции
     ‘chaosgame’, но вместо сжатия отрезка от текущей точки до случайно
     выбранной, две компоненты данного отрезка умножаются на 2х2 матрицу
     <Ai>, которая соответствует случайно выбранной точке.

     Случайный выбор <m> точек притяжения может быть осуществлен с
     вероятностью, определенной весами <r1>,...,<rm>.  Веса могут быть
     заданы в кумулятивной форме, например, если есть 3 точки с
     вероятностями 0.2, 0.5 и 0.3, то веса <r1>, <r2> и <r3> могут быть
     2, 7 и 10.

 -- Функция: julia (<x>, <y>, ...<options>...)

     Создает графический файл с изображением фрактала Джулия для
     комплексного числа (<x> + i <y>).  Параметры <x> и <y> должны быть
     вещественными.  Файл в графическом формате XPM создается в текущей
     директории пользователя.  Работа программы занимает несколько
     секунд, а по окончании вычислений она печатает имя созданного
     файла.

     Точкам, которые не принадлежат фракталу Джулия, присваиваются
     разные цвета в соответствии с числом итераций, необходимых
     последовательности, начинающейся в точке, чтобы выити из круга
     сходимости радиуса 2.  Максимальное число итераций определяется
     опцией <levels>.  Если после этого числа итераций,
     последовательность все еще находится в круге сходимости, то точка
     будет изображена цветом, определяемым опцией <color>.

     Все цвета, используемые для изображения точек, не принадлежащих
     фракталу Джулия, имеют одинаковые <saturation> и <value>, но
     различные углю оттенков, равномерно распределенные в интервале от
     <hue> до (<hue> + <huerange>).

     <options> – набор необязательных опций.  Список допустимых опций
     приведен в разделе ниже.

 -- Функция: mandelbrot (<options>)

     Создает графический файл с изображением фрактала Мандельброта.
     Файл в графическом формате XPM создается в текущей директории
     пользователя.  Работа программы занимает несколько секунд, а по
     окончании вычислений она печатает имя созданного файла.

     Точкам, которые не принадлежат фракталу Джулия, присваиваются
     разные цвета в соответствии с числом итераций, необходимых
     последовательности, начинающейся в точке, чтобы выити из круга
     сходимости радиуса 2.  Максимальное число итераций определяется
     опцией <levels>.  Если после этого числа итераций,
     последовательность все еще находится в круге сходимости, то точка
     будет изображена цветом, определяемым опцией <color>.

     Все цвета, используемые для изображения точек, не принадлежащих
     фракталу Джулия, имеют одинаковые <saturation> и <value>, но
     различные углы оттенков, равномерно распределенные в интервале от
     <hue> до (<hue> + <huerange>).

     <options> – набор необязательных опций.  Список допустимых опций
     приведен в разделе ниже.

 -- Функция: orbits (<F>, <y0>, <n1>, <n2>, [<x>, <x0>, <xf>, <xstep>],
          ...options...);

     Изображает диаграмму траекторий семейства одномерных дискретных
     динамических систем с одним параметром <x>.  Такой тип диаграмм
     используется при изучении бифуркации одномерных дискретных систем.

     Функция <F(y)> определяет последовательность с начальным значением
     <y0>, также как в случае функции ‘evolution’, но в данном случае
     функция еще зависит от параметра <x>, принимающего значения в
     интервале от <x0> до <xf> с шагом <xstep>.  Каждое значение
     параметра <x> изображается на горизонтальной оси.  На вертикальной
     оси изображаются <n2> значений последовательности <y(n1+1)>,...,
     <y(n1+n2+1)>, полученных поле <n1> начальных итераций.

 -- Функция: rk (<ODE>, <var>, <initial>, <domain>)
 -- Функция: rk ([<ODE1>,...,<ODEm>], [<v1>,...,<vm>],
          [<init1>,...,<initm>], <domain>)

     Первая форма численно решает одно обычное дифференциальное
     уравнение первого порядка, а вторая форма решает систему m подобных
     уравнений, с использованием метода Рунге-Кутта 4-го порядка.  <var>
     – зависимая переменная.  <ODE> – должно быть выражением, которое
     зависит только от независимой и зависимой переменных и определяет
     производную зависимой переменной по независимой.

     Независимая переменная задается параметром ‘domain’, который должен
     быть списком четырех элементов.  Например:
          [t, 0, 10, 0.1]
     первый элемент списка есть независимая переменная, второй и третий
     элементы есть начальное и конечное значения этой переменной, и
     последний элемент задает шаг для данного интервала.

     Если предстоит решить <m> уравнений, то должно быть <m> зависимых
     переменных <v1>, <v2>, ..., <vm>.  Начальные значения для этих
     переменных будут <init1>, <init2>, ..., <initm>.  При этом все
     равно остается только одна зависимая переменная, задаваемая
     ‘domain’, как в предыдущем случае.  <ODE1>, ..., <ODEm> –
     выражения, определяющие производную каждой из зависимых переменных
     по независимой.  Эти выражения могут зависеть только от зависимых
     переменных и независимой переменной.  Важно задать производные
     <ODE1>, ..., <ODEm> в списке точно в том порядке, что и зависимые
     переменные.  Т.е.  третий элемент списка будет интерпретирован как
     производная третьей зависимой переменной.

     Программа пытается проинтегрировать уравнения от начального
     значения независимой переменной до конечного значения с
     использованием постоянного приращения.  Если на каком-либо шаге
     значение одной из зависимых переменных становится слишком большим
     по абсолютной величине, то интегрирование прекращается.  Результат
     является списком с числом элементов равным числу итераций.  Каждый
     элемент сам является списком с <m>+1 элементами: значение зависимой
     переменной с последующими значениями зависимых переменных в
     соответствующей точке.

 -- Функция: staircase (<F>, <y0>, <n>, ...options...);

     Строит лестничную диаграмму для последовательности, заданной
     рекуррентным соотношением
                  y(n+1) = F(y(n))

     Интерпретация и допустимые значения параметров аналогичны таковым
     для команды ‘evolution’.  Лестничная диаграмма состоит из графика
     функции <F(y)> вместе с прямой <G(y)> ‘=’ <y>.  Из точки (<y0>,
     <y0>) на этой прямой строится вертикальный отрезок до переcечения с
     функцией <F>.  Из этой точки строится горизонтальный отрезок до
     точки пересечения с прямой в точке (<y1>, <y1>).  Процедура
     повторяется <n> раз до достижения точки (<yn>, <yn>).

   Опции

   Каждая опция есть список из двух или более элементов.  Первый элемент
– имя опции, остальные – аргументы опции.

   Допустимые опции функций ‘evolution’, ‘evolution2d’, ‘staircase’,
‘orbits’, ‘ifs’ и ‘chaosgame’ те же самые, что у функции ‘plot2d’.
Функция ‘orbits’ допускает дополнительную опцию <pixels>, которая задает
максимальное число точек по вертикали.

   Следующие опции допускаются функциями ‘julia’ и ‘mandelbrot’:

   • “size” имеет один или два аргумента.  Если задан только один
     аргумент, то ширина и высота создаваемого графика в пикселях будут
     равны этому значению.  Если заданы два агрумента, то они определяют
     ширину и высоту соответственно.  Значение по умолчанию равно 400
     для ширины и для высоты.  Если два параметра не равны, то график
     будет искаженным.

   • “levels” определяет максимальное число итераций, которое также
     равно числу цветов, используемых для раскраски не принадлежащих
     фракталу точек.  Значение по умолчанию равно 12.  Большее значение
     приводят к большему времени вычисления.

   • “huerange” определяет диапазон углов оттенков, используемых для
     раскраски не принадлежащих фракталу точек.  Значение по умолчанию
     360, что означает – весь диапазон оттенков.  Значения больше 360
     означает повторяющиеся оттенки, а отрицательное значение позволяет
     уменьшать углы оттенков с увеличением числа итераций.

   • “hue” задает оттенок в градусах для первого цвета, используемого
     для раскраски не принадлежащих фракталу точек.  Значение по
     умолчанию 300, что соответствует цвету маджента.  Значения для
     некоторый других стандартных цветов: 0 – красный, 45 – оранжевый,
     60 – желтый, 120 – зеленый, 180 – циан и 240 – синий.  См.  также
     опцию <huerange>.

   • “saturation” задает значение насыщенности цвета для не
     принадлежащих фракталу точек.  Оно должно быть в пределах от 0 до
     1.  Значение по умолчанию 0.46.

   • “value” задает яркость цвета для не принадлежащих фракталу точек.
     Оно должно быть в пределах от 0 до 1.  Чем больше значение, тем
     ярче цвет.

   • “color” должна иметь три параметра, задающих оттенок, насыщенность
     и яркость.  Значение по умолчанию 0 для всех трех параметров, что
     соответствует черному цвету.  Для объяснения допустимых значений
     см.  опции <hue>, <saturation> и <value>.

   • “center” должна иметь два вещественных параметра, задающих на
     комплексной плоскости точку центра изображаемой области.  Значение
     по умолчанию 0 для обеих координат (начало координат).

   • “radius” задает радиус наибольшего круга внутри изображаемой
     квадратной области.  Значение по умолчанию 2.

   • “filename” задает имя файла, в котором будет сохранен
     результирующий график.  Расширение .xpm добавляется к имени файла.
     Если файл уже существует, то он будет замене на новый.  Значение по
     умолчанию есть julia для фрактала Джулия и mandelbrot для фрактала
     Мандельброта.

   Примеры

   Графическое представление лестничной диаграммы для
последовательности: 2, cos(2), cos(cos(2)),...

     (%i1) load("dynamics")$

     (%i2) evolution(cos(y), 2, 11);

     (%i3) staircase(cos(y), 1, 11, [y, 0, 1.2]);

   Если ваша система медленна, следует уменьшить число итераций в
следующих примерах.  Если точки кажутся слишком маленькими на мониторе,
то можно попробовать другой стиль, например ‘[’<style>, ‘[’<points>, 0.8
‘]]’.

   Диаграмма траекторий для квадратичного отображения с параметром <a>.
             x(n+1) = a + x(n)^2

     (%i4) orbits(x^2+a, 0, 50, 200, [a, -2, 0.25], [style, dots]);

   Для того, чтобы увеличить область вблизи нижней бифуркации около x
‘=’ -1.25 используем:
     (%i5) orbits(x+y^2, 0, 100, 400, [a,-1,-1.53], [x,-1.6,-0.8],
                  [nticks, 400], [style,dots]);

   Эволюция двумерной системы, приводящая к фракталу:

     (%i6) f: 0.6*x*(1+2*x)+0.8*y*(x-1)-y^2-0.9$

     (%i7) g: 0.1*x*(1-6*x+4*y)+0.1*y*(1+9*y)-0.4$

     (%i8) evolution2d([f,g], [x,y], [-0.5,0], 50000, [style,dots]);

   Увеличение небольшой области фрактала:

     (%i9) evolution2d([f,g], [x,y], [-0.5,0], 300000, [x,-0.8,-0.6],
                       [y,-0.4,-0.2], [style, dots]);

   График треугольника Серпинского, полученный как игра хаоса:

     (%i9) chaosgame([[0, 0], [1, 0], [0.5, sqrt(3)/2]], [0.1, 0.1], 1/2,
                      30000, [style, dots]);

   Фрактал папоротник (Barnsley’s fern) полученный при помощи системы
повторяющихся функций (Iterated Function System):

     (%i10) a1: matrix([0.85,0.04],[-0.04,0.85])$

     (%i11) a2: matrix([0.2,-0.26],[0.23,0.22])$

     (%i12) a3: matrix([-0.15,0.28],[0.26,0.24])$

     (%i13) a4: matrix([0,0],[0,0.16])$

     (%i14) p1: [0,1.6]$

     (%i15) p2: [0,1.6]$

     (%i16) p3: [0,0.44]$

     (%i17) p4: [0,0]$

     (%i18) w: [85,92,99,100]$

     (%i19) ifs(w, [a1,a2,a3,a4], [p1,p2,p3,p4], [5,0], 50000, [style,dots]);

   Чтобы создать файл _dynamics9.xpm_ с графическим изображением
фрактала Мандельброта с 12 цветами, выполним:

     mandelbrot([filename,"dynamics9"])$

   Для фрактала Джулия с числом (-0.55 + i 0.6):
     julia(-0.55, 0.6, [levels, 36], [center, 0, 0.6], [radius, 0.3],
           [hue, 240], [huerange, -180], [filename, "dynamics10"])$

   Граф будет сохранен ф файле _dynamics10.xpm_ и будет изображать
область от -0.3 до 0.3 по оси x, и от 0.3 до 0.9 по оси y.  Используется
36 цветов, начиная с синего и заканчивая желтым.

   Чтобы решить дифференциальное уравнение

               dx/dt = t - x^2

   с начальным значением x(t=0) = 1, в интервале t от 0 до 8 с шагом
0.1, используем команду:

     (%i20) results: rk(t-x^2,x,1,[t,0,8,0.1])$

   Результат сохраняется в списке ‘results’.

   Чтобы численно решить систему:

             dx/dt = 4-x^2-4*y^2     dy/dt = y^2-x^2+1

   для t от 0 до 4, и с значениями -1.25 и 0.75 для x и y в t=0:

     (%i21) sol: rk([4-x^2-4*y^2,y^2-x^2+1],[x,y],[-1.25,0.75],[t,0,4,0.02])$


File: maxima.info,  Node: Пакет f90,  Next: Package ggf,  Prev: Пакет dynamics,  Up: Top

48 Пакет f90
************

* Menu:

* Функции и переменные пакета f90::


File: maxima.info,  Node: Функции и переменные пакета f90,  Prev: Пакет f90,  Up: Пакет f90

48.1 Функции и переменные пакета f90
====================================

 -- Функция: f90 (<expr>)
     Команда ‘f90’ является исправлением оригинальной Maxima команды
     ‘fortran’.  Основная разница заключается в том, как осуществляется
     перенос длинных строк.

     В следующем примере, обратите внимание как команда ‘fortran’
     переносит строки внутри символов.  Команда ‘f90’ никогда не делает
     перенос внутри символа.

     (%i1) load("f90")$
     
     (%i2) expr:expand((xxx+yyy+7)^4);
              4            3         3        2    2
     (%o2) yyy  + 4 xxx yyy  + 28 yyy  + 6 xxx  yyy
                  2          2        3             2
      + 84 xxx yyy  + 294 yyy  + 4 xxx  yyy + 84 xxx  yyy
                                    4         3          2
      + 588 xxx yyy + 1372 yyy + xxx  + 28 xxx  + 294 xxx
      + 1372 xxx + 2401
     (%i3) fortran(expr);
           yyy**4+4*xxx*yyy**3+28*yyy**3+6*xxx**2*yyy**2+84*xxx*yyy**2+294*yy
          1   y**2+4*xxx**3*yyy+84*xxx**2*yyy+588*xxx*yyy+1372*yyy+xxx**4+28*
          2   xxx**3+294*xxx**2+1372*xxx+2401
     (%o3)                       done
     (%i4) f90(expr);
     yyy**4+4*xxx*yyy**3+28*yyy**3+6*xxx**2*yyy**2+84*xxx*yyy**2+294* &
          yyy**2+4*xxx**3*yyy+84*xxx**2*yyy+588*xxx*yyy+1372*yyy+xxx** &
          4+28*xxx**3+294*xxx**2+1372*xxx+2401
     (%o4)                       done

     Команда ‘f90’ реализована как быстрый хак.  Она не является хорошим
     примером того, как следует реализовывать трансляцию в другие языки.

     Для того, чтобы использовать эту функцию, сначала введите команду
     ‘load("f90")’.


File: maxima.info,  Node: Package ggf,  Next: Пакет graphs,  Prev: Пакет f90,  Up: Top

49 ggf
******

* Menu:

* Functions and Variables for ggf::


File: maxima.info,  Node: Functions and Variables for ggf,  Prev: Package ggf,  Up: Package ggf

49.1 Functions and Variables for ggf
====================================

 -- Option variable: GGFINFINITY
     Default value: 3

     This is an option variable for function ‘ggf’.

     When computing the continued fraction of the generating function, a
     partial quotient having a degree (strictly) greater than
     <GGFINFINITY> will be discarded and the current convergent will be
     considered as the exact value of the generating function; most
     often the degree of all partial quotients will be 0 or 1; if you
     use a greater value, then you should give enough terms in order to
     make the computation accurate enough.

     See also ‘ggf’.

 -- Option variable: GGFCFMAX
     Default value: 3

     This is an option variable for function ‘ggf’.

     When computing the continued fraction of the generating function,
     if no good result has been found (see the <GGFINFINITY> flag) after
     having computed <GGFCFMAX> partial quotients, the generating
     function will be considered as not being a fraction of two
     polynomials and the function will exit.  Put freely a greater value
     for more complicated generating functions.

     See also ‘ggf’.

 -- Function: ggf (<l>)
     Compute the generating function (if it is a fraction of two
     polynomials) of a sequence, its first terms being given.  <l> is a
     list of numbers.

     The solution is returned as a fraction of two polynomials.  If no
     solution has been found, it returns with ‘done’.

     This function is controlled by global variables <GGFINFINITY> and
     <GGFCFMAX>.  See also <GGFINFINITY> and <GGFCFMAX>.

     To use this function write first ‘load("ggf")’.

          (%i1) load("ggf")$
          (%i2) makelist(fib(n),n,0,10);
          (%o2)                [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
          (%i3) ggf(%);
                                                 x
          (%o3)                            - ----------
                                              2
                                             x  + x - 1
          (%i4) taylor(%,x,0,10);
                        2      3      4      5      6       7       8       9       10
          (%o4)/T/ x + x  + 2 x  + 3 x  + 5 x  + 8 x  + 13 x  + 21 x  + 34 x  + 55 x
                                                                                  + . . .
          (%i5) makelist(2*fib(n+1)-fib(n),n,0,10);
          (%o5)              [2, 1, 3, 4, 7, 11, 18, 29, 47, 76, 123]
          (%i6) ggf(%);
                                              x - 2
          (%o6)                             ----------
                                             2
                                            x  + x - 1
          (%i7) taylor(%,x,0,10);
                              2      3      4       5       6       7       8       9
          (%o7)/T/ 2 + x + 3 x  + 4 x  + 7 x  + 11 x  + 18 x  + 29 x  + 47 x  + 76 x
                                                                               10
                                                                        + 123 x   + . . .

     As these examples show, the generating function does create a
     function whose Taylor series has coefficients that are the elements
     of the original list.


File: maxima.info,  Node: Пакет graphs,  Next: Пакет grobner,  Prev: Package ggf,  Up: Top

50 Пакет graphs
***************

* Menu:

* Введение в пакет graphs::
* Функции и переменные пакета graphs::


File: maxima.info,  Node: Введение в пакет graphs,  Next: Функции и переменные пакета graphs,  Prev: Пакет graphs,  Up: Пакет graphs

50.1 Введение в пакет graphs
============================

Пакет ‘graphs’ предоставляет структуры для представления графов и
ориентированных графов в Maxima.  Графы и ориентированные графы являются
простыми, т.е.  не имеют кратных ребер и петель, но ориентированные
графы могут иметь ориентированное ребро из <u> в <v> и ориентированное
ребро из <v> в <u>.

   Внутренне графы представляются как списки смежности и реализованы в
виде Lisp структур.  Вершины обозначаются своими идентификаторами id (id
– есть целое число).  Ребра/дуги представлены списками длины 2.
Вершинам графов и ориентированных графов могут быть присвоены метки а
ребрам/дугам можно присвоить веса.

   Функция ‘draw_graph’ предназначена для рисования графов.  Графы
изображаются с использованием метода взаимодействия сил.  Функция
‘draw_graph’ может также использовать программу graphviz, доступную по
ссылке <http://www.graphviz.org>.  Функция ‘draw_graph’ основана на
пакете ‘draw’.

   Чтобы использовать пакет ‘graphs’, его сначала следует загрузить
командой ‘load("graphs")’.


File: maxima.info,  Node: Функции и переменные пакета graphs,  Prev: Введение в пакет graphs,  Up: Пакет graphs

50.2 Функции и переменные пакета graphs
=======================================

50.2.1 Построение графов
------------------------

 -- Функция: create_graph (<v_list>, <e_list>)
 -- Функция: create_graph (<n>, <e_list>)
 -- Функция: create_graph (<v_list>, <e_list>, <directed>)
     Создает новый граф с множеством вершин <v_list> и ребрами <e_list>.

     <v_list> – список вершин (‘[v1, v2,..., vn]’) или вершин вместе с
     метками (‘[[v1,l1], [v2,l2],..., [vn,ln]]’).

     Если <n> – число вершин, то они будут обозначаться целыми числами
     от 0 до n-1.

     <e_list> – список ребер вида (‘[e1, e2,..., em]’) или список ребер
     вместе с весами (‘[[e1, w1], ..., [em, wm]]’).

     Если <directed> отлично от ‘false’, то возвращается ориентированный
     граф.

     Пример 1: цикл с тремя вершинами:
          (%i1) load ("graphs")$
          (%i2) g : create_graph([1,2,3], [[1,2], [2,3], [1,3]])$
          (%i3) print_graph(g)$
          Graph on 3 vertices with 3 edges.
          Adjacencies:
            3 :  1  2
            2 :  3  1
            1 :  3  2

     Пример 2: цикл с тремя вершинами и весами ребер:
          (%i1) load ("graphs")$
          (%i2) g : create_graph([1,2,3], [[[1,2], 1.0], [[2,3], 2.0],
                                    [[1,3], 3.0]])$
          (%i3) print_graph(g)$
          Graph on 3 vertices with 3 edges.
          Adjacencies:
            3 :  1  2
            2 :  3  1
            1 :  3  2

     Пример 3: ориентированный граф:
          (%i1) load ("graphs")$
          (%i2) d : create_graph(
                  [1,2,3,4],
                  [
                   [1,3], [1,4],
                   [2,3], [2,4]
                  ],
                  'directed = true)$
          (%i3) print_graph(d)$
          Digraph on 4 vertices with 4 arcs.
          Adjacencies:
            4 :
            3 :
            2 :  4  3
            1 :  4  3

 -- Функция: copy_graph (<g>)
     Возвращает копию графа <g>.

 -- Функция: circulant_graph (<n>, <d>)
     Возвращает циркулянтный граф граф с параметрами <n> и <d>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) g : circulant_graph(10, [1,3])$
          (%i3) print_graph(g)$
          Graph on 10 vertices with 20 edges.
          Adjacencies:
            9 :  2  6  0  8
            8 :  1  5  9  7
            7 :  0  4  8  6
            6 :  9  3  7  5
            5 :  8  2  6  4
            4 :  7  1  5  3
            3 :  6  0  4  2
            2 :  9  5  3  1
            1 :  8  4  2  0
            0 :  7  3  9  1

 -- Функция: clebsch_graph ()
     Возвращает граф Клебша (Clebsch graph).

 -- Функция: complement_graph (<g>)
     Возвращает граф, дополнительный графу <g>.

 -- Функция: complete_bipartite_graph (<n>, <m>)
     Возвращает полный двудольный граф с <n+m> вершинами.

 -- Функция: complete_graph (<n>)
     Возвращает полный граф с <n> вершинами.

 -- Функция: cycle_digraph (<n>)
     Возвращает ориентированный циклический граф с <n> вершинами.

 -- Функция: cycle_graph (<n>)
     Возвращает циклический граф с <n> вершинами.

 -- Функция: cube_graph (<n>)
     Возвращает <n>-мерный куб.

 -- Функция: dodecahedron_graph ()
     Возвращает граф додекаэдра.

 -- Функция: empty_graph (<n>)
     Возвращает пустой граф с <n> вершинами.

 -- Функция: flower_snark (<n>)
     Возвращает цветочный граф (flower graph) с <4n> вершинами.

     Пример:
          (%i1) load ("graphs")$
          (%i2) f5 : flower_snark(5)$
          (%i3) chromatic_index(f5);
          (%o3)                           4

 -- Функция: from_adjacency_matrix (<A>)
     Возвращает граф с матрицей смежности <A>.

 -- Функция: frucht_graph ()
     Возвращает граф Фручта (Frucht graph).

 -- Функция: graph_product (<g1>, <g1>)
     Возвращает прямое произведение графов <g1> и <g2>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) grid : graph_product(path_graph(3), path_graph(4))$
          (%i3) draw_graph(grid)$

 -- Функция: graph_union (<g1>, <g1>)
     Возвращает объединение (сумму) графов <g1> и <g2>.

 -- Функция: grid_graph (<n>, <m>)
     Возвращает решетку <n x m>.

 -- Функция: grotzch_graph ()
     Возвращает граф Гротча (Grotzch graph).

 -- Функция: heawood_graph ()
     Возвращает граф Хейвуда (Heawood graph).

 -- Функция: icosahedron_graph ()
     Возвращает граф икосаэдра.

 -- Функция: induced_subgraph (<V>, <g>)
     Возвращает граф, состоящий из подмножества вершин <V> графа <g>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) p : petersen_graph()$
          (%i3) V : [0,1,2,3,4]$
          (%i4) g : induced_subgraph(V, p)$
          (%i5) print_graph(g)$
          Graph on 5 vertices with 5 edges.
          Adjacencies:
            4 :  3  0
            3 :  2  4
            2 :  1  3
            1 :  0  2
            0 :  1  4

 -- Функция: line_graph (<g>)
     Возвращает граф двойственный (line graph) графу <g>.

 -- Функция: make_graph (<vrt>, <f>)
 -- Функция: make_graph (<vrt>, <f>, <oriented>)
     Создает граф, используя функцию предикат <f>.

     <vrt> – есть список/множество вкршин или целое число.  Если <vrt>
     есть целое число, то вершины графа будут целыми от 1 до <vrt>.

     <f> – функция предикат.  Вершины <a> и <b> будут соединены, если
     ‘f(a,b)=true’.

     Если <directed> не равно <false>, то граф будет ориентированным.

     Пример 1:
          (%i1) load("graphs")$
          (%i2) g : make_graph(powerset({1,2,3,4,5}, 2), disjointp)$
          (%i3) is_isomorphic(g, petersen_graph());
          (%o3)                         true
          (%i4) get_vertex_label(1, g);
          (%o4)                        {1, 2}

     Пример 2:
          (%i1) load("graphs")$
          (%i2) f(i, j) := is (mod(j, i)=0)$
          (%i3) g : make_graph(20, f, directed=true)$
          (%i4) out_neighbors(4, g);
          (%o4)                    [8, 12, 16, 20]
          (%i5) in_neighbors(18, g);
          (%o5)                    [1, 2, 3, 6, 9]

 -- Функция: mycielski_graph (<g>)
     Возвращает граф Мицельского (mycielskian graph) графа <g>.

 -- Функция: new_graph ()
     Возвращает граф без вершин и ребер.

 -- Функция: path_digraph (<n>)
     Возвращает ориентированный путь с <n> вершинами.

 -- Функция: path_graph (<n>)
     Возвращает путь с <n> вершинами.

 -- Функция: petersen_graph ()
 -- Функция: petersen_graph (<n>, <d>)
     Возвращает граф Петерсена <P_{n,d}>.  Значения по умолчанию для <n>
     и <d> есть ‘n=5’ и ‘d=2’.

 -- Функция: random_bipartite_graph (<a>, <b>, <p>)
     Возвращает случайный двудольный граф с ‘a+b’ вершинами.  Каждая
     вершина присутствует с вероятностью <p>.

 -- Функция: random_digraph (<n>, <p>)
     Возвращает случайный ориентированный граф с <n> вершинами.  Каждое
     ребро присутствует с вероятностью <p>.

 -- Функция: random_regular_graph (<n>)
 -- Функция: random_regular_graph (<n>, <d>)
     Возвращает случайный <d>-регулярный граф с <n> вершинами.  Значение
     по умолчанию для <d> есть ‘d=3’.

 -- Функция: random_graph (<n>, <p>)
     Возвращает случайный граф с <n> вершинами.  Каждое ребро
     присутствует с вероятностью <p>.

 -- Функция: random_graph1 (<n>, <m>)
     Возвращает случайный граф с <n> вершинами и <m> случайными ребрами.

 -- Функция: random_network (<n>, <p>, <w>)
     Возвращает случайную сеть на <n> вершинах.  Каждое ребро
     присутствует с вероятностью <p> и имеет вес в интервале ‘[0,w]’.
     Эта функция возвращает список ‘[network, source, sink]’.

     Пример:
          (%i1) load ("graphs")$
          (%i2) [net, s, t] : random_network(50, 0.2, 10.0);
          (%o2)                   [DIGRAPH, 50, 51]
          (%i3) max_flow(net, s, t)$
          (%i4) first(%);
          (%o4)                   27.65981397932507

 -- Функция: random_tournament (<n>)
     Возвращает случайный полный ориентированный граф (tournament) с <n>
     вершинами.

 -- Функция: random_tree (<n>)
     Возвращает случайное дерево с <n> вершинами.

 -- Функция: tutte_graph ()
     Возвращает граф Татта (Tutte).

 -- Функция: underlying_graph (<g>)
     Возвращает неориентированный граф, получаемый заменой ребер
     ориентированного графа <g> на неориентированные.

 -- Функция: wheel_graph (<n>)
     Возвращает колесный граф (wheel graph) с <n+1> вершинами.

50.2.2 Свойства графов
----------------------

 -- Функция: adjacency_matrix (<gr>)
     Возвращает матрицу смежности графа <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) c5 : cycle_graph(4)$
          (%i3) adjacency_matrix(c5);
                                   [ 0  1  0  1 ]
                                   [            ]
                                   [ 1  0  1  0 ]
          (%o3)                    [            ]
                                   [ 0  1  0  1 ]
                                   [            ]
                                   [ 1  0  1  0 ]

 -- Функция: average_degree (<gr>)
     Возвращает среднюю степень вершин графа <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) average_degree(grotzch_graph());
                                         40
          (%o2)                          --
                                         11

 -- Функция: biconected_components (<gr>)
     Возвращает (наборы вершин) 2-связных компонент графа <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) g : create_graph(
                      [1,2,3,4,5,6,7],
                      [
                       [1,2],[2,3],[2,4],[3,4],
                       [4,5],[5,6],[4,6],[6,7]
                      ])$
          (%i3) biconnected_components(g);
          (%o3)        [[6, 7], [4, 5, 6], [1, 2], [2, 3, 4]]

 -- Функция: bipartition (<gr>)
     Возвращает двудольное разложение графа <gr> или пустой список, если
     <gr> не является двудольным.

     Пример:

          (%i1) load ("graphs")$
          (%i2) h : heawood_graph()$
          (%i3) [A,B]:bipartition(h);
          (%o3)  [[8, 12, 6, 10, 0, 2, 4], [13, 5, 11, 7, 9, 1, 3]]
          (%i4) draw_graph(h, show_vertices=A, program=circular)$

 -- Функция: chromatic_index (<gr>)
     Возвращает хроматический индекс графа <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) p : petersen_graph()$
          (%i3) chromatic_index(p);
          (%o3)                           4

 -- Функция: chromatic_number (<gr>)
     Возвращает хроматическое число графа <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) chromatic_number(cycle_graph(5));
          (%o2)                           3
          (%i3) chromatic_number(cycle_graph(6));
          (%o3)                           2

 -- Функция: clear_edge_weight (<e>, <gr>)
     Удаляет вес ребра <e> в графе <gr>.

     Пример:

          (%i1) load ("graphs")$
          (%i2) g : create_graph(3, [[[0,1], 1.5], [[1,2], 1.3]])$
          (%i3) get_edge_weight([0,1], g);
          (%o3)                          1.5
          (%i4) clear_edge_weight([0,1], g)$
          (%i5) get_edge_weight([0,1], g);
          (%o5)                           1

 -- Функция: clear_vertex_label (<v>, <gr>)
     Удаляет метку вершины <v> в графе <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) g : create_graph([[0,"Zero"], [1, "One"]], [[0,1]])$
          (%i3) get_vertex_label(0, g);
          (%o3)                        Zero
          (%i4) clear_vertex_label(0, g);
          (%o4)                        done
          (%i5) get_vertex_label(0, g);
          (%o5)                        false

 -- Функция: connected_components (<gr>)
     Возвращает (наборы вершин) компоненты связности графа <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) g: graph_union(cycle_graph(5), path_graph(4))$
          (%i3) connected_components(g);
          (%o3)           [[1, 2, 3, 4, 0], [8, 7, 6, 5]]

 -- Функция: diameter (<gr>)
     Возвращает диаметр графа <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) diameter(dodecahedron_graph());
          (%o2)                          5

 -- Функция: edge_coloring (<gr>)
     Возвращает оптимальную раскраску ребер графа <gr>.

     Эта функция возвращает хроматический индекс и список,
     представляющий раскраску ребер графа <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) p : petersen_graph()$
          (%i3) [ch_index, col] : edge_coloring(p);
          (%o3) [4, [[[0, 5], 3], [[5, 7], 1], [[0, 1], 1], [[1, 6], 2],
          [[6, 8], 1], [[1, 2], 3], [[2, 7], 4], [[7, 9], 2], [[2, 3], 2],
          [[3, 8], 3], [[5, 8], 2], [[3, 4], 1], [[4, 9], 4], [[6, 9], 3],
          [[0, 4], 2]]]
          (%i4) assoc([0,1], col);
          (%o4)                           1
          (%i5) assoc([0,5], col);
          (%o5)                           3

 -- Функция: degree_sequence (<gr>)
     Возвращает список степеней вершин графа <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) degree_sequence(random_graph(10, 0.4));
          (%o2)            [3, 3, 3, 4, 4, 4, 5, 5, 6, 7]

 -- Функция: edges (<gr>)
     Возвращает список ребер/дуг ориентированного или неориентированного
     графа <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) edges(complete_graph(4));
          (%o2)   [[2, 3], [1, 3], [1, 2], [0, 3], [0, 2], [0, 1]]

 -- Функция: get_edge_weight (<e>, <gr>)
 -- Функция: get_edge_weight (<e>, <gr>, <ifnot>)
     Возвращает вес ребра <e> графа <gr>.

     Если вес не присвоен ребру, то возвращается 1.  Если ребро в графе
     отсутствует, то выдается ошибка или возвращает необязательный
     аргумент <ifnot>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) c5 : cycle_graph(5)$
          (%i3) get_edge_weight([1,2], c5);
          (%o3)                           1
          (%i4) set_edge_weight([1,2], 2.0, c5);
          (%o4)                         done
          (%i5) get_edge_weight([1,2], c5);
          (%o5)                          2.0

 -- Функция: get_vertex_label (<v>, <gr>)
     Возвращает метку вершины <v> графа <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) g : create_graph([[0,"Zero"], [1, "One"]], [[0,1]])$
          (%i3) get_vertex_label(0, g);
          (%o3)                         Zero

 -- Функция: graph_charpoly (<gr>, <x>)
     Возвращает характеристический многочлен (от переменной <x>) графа
     <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) p : petersen_graph()$
          (%i3) graph_charpoly(p, x), factor;
                                             5        4
          (%o3)               (x - 3) (x - 1)  (x + 2)

 -- Функция: graph_center (<gr>)
     Возвращает центр графа <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) g : grid_graph(5,5)$
          (%i3) graph_center(g);
          (%o3)                         [12]

 -- Функция: graph_eigenvalues (<gr>)
     Возвращает собственные значения графа <gr>.  Значение возвращаются
     в том же формате, что возвращает Maxima функция ‘eigenvalue’.

     Пример:
          (%i1) load ("graphs")$
          (%i2) p : petersen_graph()$
          (%i3) graph_eigenvalues(p);
          (%o3)               [[3, - 2, 1], [1, 4, 5]]

 -- Функция: graph_periphery (<gr>)
     Возвращает периферию графа <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) g : grid_graph(5,5)$
          (%i3) graph_periphery(g);
          (%o3)                    [24, 20, 4, 0]

 -- Функция: graph_size (<gr>)
     Возвращает число вершин в графе <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) p : petersen_graph()$
          (%i3) graph_size(p);
          (%o3)                          10

 -- Функция: graph_order (<gr>)
     Возвращает число ребер в графе <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) p : petersen_graph()$
          (%i3) graph_order(p);
          (%o3)                          15

 -- Функция: girth (<gr>)
     Возвращает длину наикратчайшего цикла в графе <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) g : heawood_graph()$
          (%i3) girth(g);
          (%o3)                           5

 -- Функция: hamilton_cycle (<gr>)
     Возвращает гамильтонов цикл графа <gr> или пустой список, если граф
     <gr> не является гамильтоновым.

     Пример:
          (%i1) load ("graphs")$
          (%i2) c : cube_graph(3)$
          (%i3) hc : hamilton_cycle(c);
          (%o3)              [7, 3, 2, 6, 4, 0, 1, 5, 7]
          (%i4) draw_graph(c, show_edges=vertices_to_cycle(hc))$

 -- Функция: hamilton_path (<gr>)
     Возвращает гамильтонов путь графа <gr> или пустой список, если граф
     <gr> не имеет гамильтонова пути.

     Пример:
          (%i1) load ("graphs")$
          (%i2) p : petersen_graph()$
          (%i3) hp : hamilton_path(p);
          (%o3)            [0, 5, 7, 2, 1, 6, 8, 3, 4, 9]
          (%i4) draw_graph(p, show_edges=vertices_to_path(hp))$

 -- Функция: isomorphism (<gr1>, <gr2>)

     Возвращает хэш-таблицу изоморфизма между (ориентированными) графами
     <gr1> и <gr2>.  Если <gr1> и <gr2> не изоморфны, то возвращается
     ‘false’.

     Пример:
          (%i1) load ("graphs")$
          (%i2) clk5:complement_graph(line_graph(complete_graph(5)))$
          (%i3) hash_table_data(isomorphism(clk5, petersen_graph()));
          (%o3) [8 -> 9, 7 -> 8, 4 -> 7, 3 -> 6, 1 -> 5, 0 -> 4, 5 -> 3,
                                                    6 -> 2, 2 -> 1, 9 -> 0]

 -- Функция: in_neighbors (<v>, <gr>)
     Возвращает список входящих соседей (in-neighbors) вершины <v>
     ориентированного графа <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) p : path_digraph(3)$
          (%i3) in_neighbors(2, p);
          (%o3)                          [1]
          (%i4) out_neighbors(2, p);
          (%o4)                          []

 -- Функция: is_biconnected (<gr>)
     Возвращает ‘true’, если граф <gr> 2-связный, и ‘false’ в противном
     случае.

     Пример:
          (%i1) load ("graphs")$
          (%i2) is_biconnected(cycle_graph(5));
          (%o2)                         true
          (%i3) is_biconnected(path_graph(5));
          (%o3)                         false

 -- Функция: is_bipartite (<gr>)
     Возвращает ‘true’, если граф <gr> двудольный, и ‘false’ в противном
     случае.

     Пример:
          (%i1) load ("graphs")$
          (%i2) is_bipartite(petersen_graph());
          (%o2)                        false
          (%i3) is_bipartite(heawood_graph());
          (%o3)                        true

 -- Функция: is_connected (<gr>)
     Возвращает ‘true’, если граф <gr> связный, и ‘false’ в противном
     случае.

     Пример:
          (%i1) load ("graphs")$
          (%i2) is_connected(graph_union(cycle_graph(4), path_graph(3)));
          (%o2)                        false

 -- Функция: is_digraph (<gr>)
     Возвращает ‘true’, если <gr> является ориентированным графом, и
     ‘false’ в противном случае.

     Пример:
          (%i1) load ("graphs")$
          (%i2) is_digraph(path_graph(5));
          (%o2)                        false
          (%i3) is_digraph(path_digraph(5));
          (%o3)                        true

 -- Функция: is_edge_in_graph (<e>, <gr>)
     Возвращает ‘true’, если <e> есть ребро (ориентированного) графа
     <g>, и ‘false’ в противном случае.

     Пример:
          (%i1) load ("graphs")$
          (%i2) c4 : cycle_graph(4)$
          (%i3) is_edge_in_graph([2,3], c4);
          (%o3)                        true
          (%i4) is_edge_in_graph([3,2], c4);
          (%o4)                        true
          (%i5) is_edge_in_graph([2,4], c4);
          (%o5)                        false
          (%i6) is_edge_in_graph([3,2], cycle_digraph(4));
          (%o6)                        false

 -- Функция: is_graph (<gr>)
     Возвращает ‘true’, если <gr> является графом, и ‘false’ в противном
     случае.

     Пример:
          (%i1) load ("graphs")$
          (%i2) is_graph(path_graph(5));
          (%o2)                        true
          (%i3) is_graph(path_digraph(5));
          (%o3)                        false

 -- Функция: is_graph_or_digraph (<gr>)
     Возвращает ‘true’, если <gr> является графом или ориентированным
     графом, и ‘false’ в противном случае.

     Пример:
          (%i1) load ("graphs")$
          (%i2) is_graph_or_digraph(path_graph(5));
          (%o2)                        true
          (%i3) is_graph_or_digraph(path_digraph(5));
          (%o3)                        true

 -- Функция: is_isomorphic (<gr1>, <gr2>)

     Возвращает ‘true’, если (ориентированные) графы <gr1> и <gr2>
     изоморфны, и ‘false’ в противном случае.

     См.  также ‘isomorphism’.

     Пример:
          (%i1) load ("graphs")$
          (%i2) clk5:complement_graph(line_graph(complete_graph(5)))$
          (%i3) is_isomorphic(clk5, petersen_graph());
          (%o3)                       true

 -- Функция: is_planar (<gr>)

     Возвращает ‘true’, если <gr> является планарным графом, и ‘false’ в
     противном случае.

     Используется алгоритм Демукрона, который является квадратичным по
     времени.

     Пример:
          (%i1) load ("graphs")$
          (%i2) is_planar(dodecahedron_graph());
          (%o2)                         true
          (%i3) is_planar(petersen_graph());
          (%o3)                         false
          (%i4) is_planar(petersen_graph(10,2));
          (%o4)                         true

 -- Функция: is_sconnected (<gr>)
     Возвращает ‘true’, если ориентированный граф <gr> является сильно
     связным, и ‘false’ в противном случае.

     Пример:
          (%i1) load ("graphs")$
          (%i2) is_sconnected(cycle_digraph(5));
          (%o2)                        true
          (%i3) is_sconnected(path_digraph(5));
          (%o3)                        false

 -- Функция: is_vertex_in_graph (<v>, <gr>)
     Возвращает ‘true’, если <v> есть вершина в графе <g>, и ‘false’ в
     противном случае.

     Пример:
          (%i1) load ("graphs")$
          (%i2) c4 : cycle_graph(4)$
          (%i3) is_vertex_in_graph(0, c4);
          (%o3)                        true
          (%i4) is_vertex_in_graph(6, c4);
          (%o4)                        false

 -- Функция: is_tree (<gr>)
     Возвращает ‘true’, если граф <gr> является деревом, и ‘false’ в
     противном случае.

     Пример:
          (%i1) load ("graphs")$
          (%i2) is_tree(random_tree(4));
          (%o2)                        true
          (%i3) is_tree(graph_union(random_tree(4), random_tree(5)));
          (%o3)                        false

 -- Функция: laplacian_matrix (<gr>)
     Возвращает матрицу Лапласа графа <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) laplacian_matrix(cycle_graph(5));
                             [  2   - 1   0    0   - 1 ]
                             [                         ]
                             [ - 1   2   - 1   0    0  ]
                             [                         ]
          (%o2)              [  0   - 1   2   - 1   0  ]
                             [                         ]
                             [  0    0   - 1   2   - 1 ]
                             [                         ]
                             [ - 1   0    0   - 1   2  ]

 -- Функция: max_clique (<gr>)
     Возвращает максимальную клику графа <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) g : random_graph(100, 0.5)$
          (%i3) max_clique(g);
          (%o3)          [2, 6, 13, 17, 21, 23, 31, 62, 65]

 -- Функция: max_degree (<gr>)
     Возвращает максимальную степень вершины графа <gr> и саму вершину с
     максимальной степенью.

     Пример:
          (%i1) load ("graphs")$
          (%i2) g : random_graph(100, 0.02)$
          (%i3) max_degree(g);
          (%o3)                        [6, 70]
          (%i4) vertex_degree(95, g);
          (%o4)                           3

 -- Функция: max_flow (<net>, <s>, <t>)
     Возвращает максимальный поток через сеть <net> с истоком <s> и
     стоком <t>.

     Функция возвращает значение максимального потока и список весов
     ребер оптимального потока.

     Пример:
          (%i1) load ("graphs")$
          (%i2) net : create_graph(
            [1,2,3,4,5,6],
            [[[1,2], 1.0],
             [[1,3], 0.3],
             [[2,4], 0.2],
             [[2,5], 0.3],
             [[3,4], 0.1],
             [[3,5], 0.1],
             [[4,6], 1.0],
             [[5,6], 1.0]],
            directed=true)$
          (%i3) [flow_value, flow] : max_flow(net, 1, 6);
          (%o3) [0.7, [[[1, 2], 0.5], [[1, 3], 0.2], [[2, 4], 0.2],
          [[2, 5], 0.3], [[3, 4], 0.1], [[3, 5], 0.1], [[4, 6], 0.3],
          [[5, 6], 0.4]]]
          (%i4) fl : 0$
          (%i5) for u in out_neighbors(1, net)
               do fl : fl + assoc([1, u], flow)$
          (%i6) fl;
          (%o6)                          0.7

 -- Функция: max_independent_set (<gr>)
     Возвращает максимальное независимое множество графа <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) d : dodecahedron_graph()$
          (%i3) mi : max_independent_set(d);
          (%o3)             [0, 3, 5, 9, 10, 11, 18, 19]
          (%i4) draw_graph(d, show_vertices=mi)$

 -- Функция: max_matching (<gr>)
     Возвращает максимальный набор ребер, не имеющих общих вершин
     (maximal matching), для графа <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) d : dodecahedron_graph()$
          (%i3) m : max_matching(d);
          (%o3) [[1, 2], [3, 4], [0, 15], [11, 16], [12, 17], [13, 18],
                                         [14, 19], [6, 10], [8, 9], [5, 7]]
          (%i4) draw_graph(d, show_edges=m)$

 -- Функция: min_degree (<gr>)
     Возвращает минимальную степень вершины графа <gr> и саму вершину с
     минимальной степенью.

     Пример:
          (%i1) load ("graphs")$
          (%i2) g : random_graph(100, 0.1)$
          (%i3) min_degree(g);
          (%o3)                        [4, 83]
          (%i4) vertex_degree(21, g);
          (%o4)                          12

 -- Функция: min_vertex_cover (<gr>)

     Возвращает минимальное вершинное покрытие графа <gr>.

 -- Функция: minimum_spanning_tree (<gr>)
     Возвращает минимальный каркас (минимальное остовное дерево) графа
     <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) g : graph_product(path_graph(10), path_graph(10))$
          (%i3) t : minimum_spanning_tree(g)$
          (%i4) draw_graph(g, show_edges=edges(t))$

 -- Функция: neighbors (<v>, <gr>)
     Возвращает список соседей вершины <v> в графе <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) p : petersen_graph()$
          (%i3) neighbors(3, p);
          (%o3)                       [4, 8, 2]

 -- Функция: odd_girth (<gr>)
     Возвращает длину наикратчайшего нечетного цикла в графе <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) g : graph_product(cycle_graph(4), cycle_graph(7))$
          (%i3) girth(g);
          (%o3)                           4
          (%i4) odd_girth(g);
          (%o4)                           7

 -- Функция: out_neighbors (<v>, <gr>)
     Возвращает список исходящих соседей (out-neighbors) вершины <v>
     ориентированного графа <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) p : path_digraph(3)$
          (%i3) in_neighbors(2, p);
          (%o3)                           [1]
          (%i4) out_neighbors(2, p);
          (%o4)                           []

 -- Функция: planar_embedding (<gr>)

     Возвращает список поверхностных маршрутов (facial walks) в плоской
     укладке графа <gr>, и ‘false’, если граф <gr> не является
     планарным.

     Граф <gr> должен быть бисвязным.

     Используется алгоритм Демукрона, который является квадратичным по
     времени.

     Пример:
          (%i1) load ("graphs")$
          (%i2) planar_embedding(grid_graph(3,3));
          (%o2) [[3, 6, 7, 8, 5, 2, 1, 0], [4, 3, 0, 1], [3, 4, 7, 6],
                                                [8, 7, 4, 5], [1, 2, 5, 4]]

 -- Функция: print_graph (<gr>)
     Выводит некоторую информацию о графе <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) c5 : cycle_graph(5)$
          (%i3) print_graph(c5)$
          Graph on 5 vertices with 5 edges.
          Adjacencies:
            4 :  0  3
            3 :  4  2
            2 :  3  1
            1 :  2  0
            0 :  4  1
          (%i4) dc5 : cycle_digraph(5)$
          (%i5) print_graph(dc5)$
          Digraph on 5 vertices with 5 arcs.
          Adjacencies:
            4 :  0
            3 :  4
            2 :  3
            1 :  2
            0 :  1
          (%i6) out_neighbors(0, dc5);
          (%o6)                          [1]

 -- Функция: radius (<gr>)
     Возвращает радиус графа <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) radius(dodecahedron_graph());
          (%o2)                           5

 -- Функция: set_edge_weight (<e>, <w>, <gr>)
     Присваивает вес <w> ребру <e> графа <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) g : create_graph([1, 2], [[[1,2], 1.2]])$
          (%i3) get_edge_weight([1,2], g);
          (%o3)                          1.2
          (%i4) set_edge_weight([1,2], 2.1, g);
          (%o4)                         done
          (%i5) get_edge_weight([1,2], g);
          (%o5)                          2.1

 -- Функция: set_vertex_label (<v>, <l>, <gr>)
     Присваивает метку <l> вершине <v> графа <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) g : create_graph([[1, "One"], [2, "Two"]], [[1,2]])$
          (%i3) get_vertex_label(1, g);
          (%o3)                           One
          (%i4) set_vertex_label(1, "oNE", g);
          (%o4)                          done
          (%i5) get_vertex_label(1, g);
          (%o5)                           oNE

 -- Функция: shortest_path (<u>, <v>, <gr>)
     Возвращает кратчайший путь из вершины <u> в вершину <v> в графе
     <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) d : dodecahedron_graph()$
          (%i3) path : shortest_path(0, 7, d);
          (%o3)                    [0, 1, 19, 13, 7]
          (%i4) draw_graph(d, show_edges=vertices_to_path(path))$

 -- Функция: strong_components (<gr>)
     Возвращает сильную компоненту ориентированного графа <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) t : random_tournament(4)$
          (%i3) strong_components(t);
          (%o3)                 [[2], [0], [1], [3]]
          (%i4) vertex_out_degree(3, t);
          (%o4)                           2

 -- Функция: topological_sort (<dag>)

     Возвращает топологическую сортировку вершин ориентированного графа
     <dag>, или пустой список, если <dag> не является ориентированным
     ациклическим графом.

     Пример:
          (%i1) load ("graphs")$
          (%i2) g:create_graph(
                   [1,2,3,4,5],
                   [
                    [1,2], [2,5], [5,3],
                    [5,4], [3,4], [1,3]
                   ],
                   directed=true)$
          (%i3) topological_sort(g);
          (%o3)                     [1, 2, 5, 3, 4]

 -- Функция: vertex_degree (<v>, <gr>)
     Возвращает степень вершины <v> в графе <gr>.

 -- Функция: vertex_distance (<u>, <v>, <gr>)
     Возвращает длину кратчайшего пути между вершинами <u> и <v> в
     (ориентированном) графе <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) d : dodecahedron_graph()$
          (%i3) vertex_distance(0, 7, d);
          (%o3)                           4
          (%i4) shortest_path(0, 7, d);
          (%o4)                   [0, 1, 19, 13, 7]

 -- Функция: vertex_eccentricity (<v>, <gr>)

     Возвращает эксцентриситет вершины <v> графа <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) g:cycle_graph(7)$
          (%i3) vertex_eccentricity(0, g);
          (%o4)                            3

 -- Функция: vertex_in_degree (<v>, <gr>)
     Возвращает входящую степень вершины <v> ориентированного графа
     <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) p5 : path_digraph(5)$
          (%i3) print_graph(p5)$
          Digraph on 5 vertices with 4 arcs.
          Adjacencies:
            4 :
            3 :  4
            2 :  3
            1 :  2
            0 :  1
          (%i4) vertex_in_degree(4, p5);
          (%o4)                           1
          (%i5) in_neighbors(4, p5);
          (%o5)                          [3]

 -- Функция: vertex_out_degree (<v>, <gr>)
     Возвращает исходящую степень вершины <v> ориентированного графа
     <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) t : random_tournament(10)$
          (%i3) vertex_out_degree(0, t);
          (%o3)                           6
          (%i4) out_neighbors(0, t);
          (%o4)                  [9, 6, 4, 3, 2, 1]

 -- Функция: vertices (<gr>)
     Возвращает список вершин графа <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) vertices(complete_graph(4));
          (%o2)                     [3, 2, 1, 0]

50.2.3 Изменение графов
-----------------------

 -- Функция: add_edge (<e>, <gr>)
     Добавляет ребро <e> к графу <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) p : path_graph(4)$
          (%i3) neighbors(0, p);
          (%o3)                          [1]
          (%i4) add_edge([0,3], p);
          (%o4)                         done
          (%i5) neighbors(0, p);
          (%o5)                        [3, 1]

 -- Функция: add_edges (<e_list>, <gr>)
     Добавляет ребра из списка <e_list> к графу <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) g : empty_graph(3)$
          (%i3) add_edges([[0,1],[1,2]], g)$
          (%i4) print_graph(g)$
          Graph on 3 vertices with 2 edges.
          Adjacencies:
            2 :  1
            1 :  2  0
            0 :  1

 -- Функция: add_vertex (<v>, <gr>)
     Добавляет вершину <v> к графу <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) g : path_graph(2)$
          (%i3) add_vertex(2, g)$
          (%i4) print_graph(g)$
          Graph on 3 vertices with 1 edges.
          Adjacencies:
            2 :
            1 :  0
            0 :  1

 -- Функция: add_vertices (<v_list>, <gr>)
     Добавляет все вершины из списка <v_list> к графу <gr>.

 -- Функция: connect_vertices (<v_list>, <u_list>, <gr>)
     Соединяет все вершины из списка <v_list> с вершинами из списка
     <u_list> в графе <gr>.

     <v_list> и <u_list> могут быть отдельными вершинами или списками
     вершин.

     Пример:
          (%i1) load ("graphs")$
          (%i2) g : empty_graph(4)$
          (%i3) connect_vertices(0, [1,2,3], g)$
          (%i4) print_graph(g)$
          Graph on 4 vertices with 3 edges.
          Adjacencies:
            3 :  0
            2 :  0
            1 :  0
            0 :  3  2  1

 -- Функция: contract_edge (<e>, <gr>)
     Стягивает ребро <e> в графе <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) g: create_graph(
                8, [[0,3],[1,3],[2,3],[3,4],[4,5],[4,6],[4,7]])$
          (%i3) print_graph(g)$
          Graph on 8 vertices with 7 edges.
          Adjacencies:
            7 :  4
            6 :  4
            5 :  4
            4 :  7  6  5  3
            3 :  4  2  1  0
            2 :  3
            1 :  3
            0 :  3
          (%i4) contract_edge([3,4], g)$
          (%i5) print_graph(g)$
          Graph on 7 vertices with 6 edges.
          Adjacencies:
            7 :  3
            6 :  3
            5 :  3
            3 :  5  6  7  2  1  0
            2 :  3
            1 :  3
            0 :  3

 -- Функция: remove_edge (<e>, <gr>)
     Удаляет ребро <e> из графа <gr>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) c3 : cycle_graph(3)$
          (%i3) remove_edge([0,1], c3)$
          (%i4) print_graph(c3)$
          Graph on 3 vertices with 2 edges.
          Adjacencies:
            2 :  0  1
            1 :  2
            0 :  2

 -- Функция: remove_vertex (<v>, <gr>)
     Удаляет вершину <v> из графа <gr>.

 -- Функция: vertex_coloring (<gr>)
     Возвращает оптимальную раскраску вершин графа <gr>.

     Функция возвращает хроматическое число и список, описывающий
     раскраску вершин графа <g>.

     Пример:
          (%i1) load ("graphs")$
          (%i2) p:petersen_graph()$
          (%i3) vertex_coloring(p);
          (%o3) [3, [[0, 2], [1, 3], [2, 2], [3, 3], [4, 1], [5, 3],
                                           [6, 1], [7, 1], [8, 2], [9, 2]]]

50.2.4 Чтение и запись файлов
-----------------------------

 -- Функция: dimacs_export (<gr>, <fl>)
 -- Функция: dimacs_export (<gr>, <fl>, <comment1>, ..., <commentn>)

     Экспортирует граф в файл <fl> в формате DIMACS. Необязательный
     комментарий будет добавлен к началу файла.

 -- Функция: dimacs_import (<fl>)

     Возвращает граф из файла <fl>, в котором он записан в формате
     DIMACS.

 -- Функция: graph6_decode (<str>)

     Возвращает граф, закодированный в формате graph6 в строке <str>.

 -- Функция: graph6_encode (<gr>)

     Возвращает строку – закодированное представление графа <gr> в
     формате graph6.

 -- Функция: graph6_export (<gr_list>, <fl>)

     Экспортирует графы из списка <gr_list> в файл <fl> в формате
     graph6.

 -- Функция: graph6_import (<fl>)

     Возвращает список графов из файла <fl>, где они закодированы в
     формате graph6.

 -- Функция: sparse6_decode (<str>)

     Возвращает граф, закодированный в формате sparse6 в строке <str>.

 -- Функция: sparse6_encode (<gr>)

     Возвращает строку – закодированное представление графа <gr> в
     формате sparse6.

 -- Функция: sparse6_export (<gr_list>, <fl>)

     Экспортирует графы из списка <gr_list> в файл <fl> в формате
     sparse6.

 -- Функция: sparse6_import (<fl>)

     Возвращает список графов из файла <fl>, где они закодированы в
     формате sparse6.

50.2.5 Визуализация
-------------------

 -- Функция: draw_graph (<graph>)
 -- Функция: draw_graph (<graph>, <option1>, ..., <optionk>)
     Изображает граф с помощью пакета ‘draw’.

     Алгоритм, используемый для размещения вершин, определяется
     необязательной переменной <program>.  Значение по умолчанию
     ‘program=spring_embedding’.  Может также использоваться программа
     graphviz, но она должна быть установлена отдельно.

     Необязательные аргументы <draw_graph> могут быть:
        • “show_id=show”: если <show> равно <true>, то изображаются
          идентификаторы (id) вершин.
        • “show_label=show”: если <show> равно <true>, то изображаются
          метки вершин.
        • “label_alignment=pos”: как разместить метку или идентификатор
          вершины.  Может быть ‘left’, ‘center’ или ‘right’.  По
          умолчанию ‘left’.
        • “show_weight=show”: если <show> равно <true>, то изображаются
          веса ребер.
        • “vertex_type=type”: определяет, как изображаются вершины.  См.
          опцию <point_type> пакета ‘draw’.
        • “vertex_size=size”: размер вершин.
        • “vertex_color=c”: цвет вершин.
        • “show_vertices=v_list”: изобразить вершины из списка <v_list>
          другим цветом.
        • “show_vertex_type=type”: определяет, как изображаются вершины
          из списка <show_vertices>.  См.  опцию <point_type> пакета
          ‘draw’.
        • “show_vertex_size=size”: размер вершин в списке
          <show_vertices>.
        • “show_vertex_color=c”: цвет вершин в списке <show_vertices>.
        • “vertex_partition=part”: разбиение
          ‘[[v1,v2,...],...,[vk,...,vn]]’ вершин графа.  Вершины в
          каждом списка будут изображаться разными цветами.
        • “vertex_coloring=col”: раскраска вершин.  Раскраска <col>
          должна быть задана в формате, возвращаемом <vertex_coloring>.
        • “edge_color=c”: цвет, используемый для изображения ребер.
        • “edge_width=width”: толщина ребер.
        • “edge_type=type”: определяет способ изображения ребер.  См.
          опцию <line_type> пакета ‘draw’.
        • “show_edges=e_list”: изображать ребра из списка <e_list>
          другим цветом.
        • “show_edge_color=c”: цвет, используемый для изображения ребер
          из списка <show_edges>.
        • “show_edge_width=width”: ширина ребер <show_edges>.
        • “show_edge_type=type”: определяет, как изображаются ребра из
          списка <show_edges>.  См.  опцию <line_type> пакета ‘draw’.
        • “edge_partition=partition”: разбиение
          ‘[[e1,e2,...],...,[ek,...,em]]’ ребер графа.  Ребра в каждом
          списке будут изображаться разными цветами.
        • “edge_coloring=col”: раскраска ребер.  Раскраска <col> должна
          быть задана в формате, возвращаемом функцией <edge_coloring>.
        • “redraw=r”: если <redraw> равно ‘true’, то положение вершин
          вычисляется снова, даже если оно было сохранено с предыдущего
          изображения графа.
        • “head_angle=angle”: угол наконечников стрелок, изображаемых на
          ребрах ориентированных графов.  Значение по умолчанию: 15.
        • “head_length=len”: длина наконечников стрелок, изображаемых на
          ребрах ориентированных графов.  Значение по умолчанию: 0.1.
        • “spring_embedding_depth=depth”: число итераций в алгоритме
          пружин (метод взаимодействия сил).  Значение по умолчанию: 50.
        • “terminal=term”: терминал, используемый для изображения (см.
          опцию <terminal> пакета ‘draw’).
        • “file_name=file”: имя файла изображения, если терминал не
          является дисплеем.
        • “program=prg”: определяет программу, используемую для
          расположения вершин графа.  Может быть одной из опций
          программы graphviz (dot, neato, twopi, circ, fdp), <circular>,
          <spring_embedding> или <planar_embedding>.  <planar_embedding>
          примеменимо только 2-связным планарным графам.  Когда
          ‘program=spring_embedding’, то набор вершин с фиксированным
          расположением может быть задан с помощью опции
          <fixed_vertices>.
        • “fixed_vertices=[]”: задает список вершин, которые будут
          расположены в фиксорованных позициях по правильному
          многограннику.  Может использоваться совместно с
          ‘program=spring_embedding’.

     Пример 1:

          (%i1) load ("graphs")$
          (%i2) g:grid_graph(10,10)$
          (%i3) m:max_matching(g)$
          (%i4) draw_graph(g,
             spring_embedding_depth=100,
             show_edges=m, edge_type=dots,
             vertex_size=0)$

     Пример 2:

          (%i1) load ("graphs")$
          (%i2) g:create_graph(16,
              [
               [0,1],[1,3],[2,3],[0,2],[3,4],[2,4],
               [5,6],[6,4],[4,7],[6,7],[7,8],[7,10],[7,11],
               [8,10],[11,10],[8,9],[11,12],[9,15],[12,13],
               [10,14],[15,14],[13,14]
              ])$
          (%i3) t:minimum_spanning_tree(g)$
          (%i4) draw_graph(
              g,
              show_edges=edges(t),
              show_edge_width=4,
              show_edge_color=green,
              vertex_type=filled_square,
              vertex_size=2
              )$

     Пример 3:

          (%i1) load ("graphs")$
          (%i2) g:create_graph(16,
              [
               [0,1],[1,3],[2,3],[0,2],[3,4],[2,4],
               [5,6],[6,4],[4,7],[6,7],[7,8],[7,10],[7,11],
               [8,10],[11,10],[8,9],[11,12],[9,15],[12,13],
               [10,14],[15,14],[13,14]
              ])$
          (%i3) mi : max_independent_set(g)$
          (%i4) draw_graph(
              g,
              show_vertices=mi,
              show_vertex_type=filled_up_triangle,
              show_vertex_size=2,
              edge_color=cyan,
              edge_width=3,
              show_id=true,
              text_color=brown
              )$

     Пример 4:

          (%i1) load ("graphs")$
          (%i2) net : create_graph(
              [0,1,2,3,4,5],
              [
               [[0,1], 3], [[0,2], 2],
               [[1,3], 1], [[1,4], 3],
               [[2,3], 2], [[2,4], 2],
               [[4,5], 2], [[3,5], 2]
              ],
              directed=true
              )$
          (%i3) draw_graph(
              net,
              show_weight=true,
              vertex_size=0,
              show_vertices=[0,5],
              show_vertex_type=filled_square,
              head_length=0.2,
              head_angle=10,
              edge_color="dark-green",
              text_color=blue
              )$

 -- Управляющая переменная: draw_graph_program
     Значение по умолчанию: <spring_embedding>.

     Значение по умолчанию, которое используется для расположения вершин
     в программе ‘draw_graph’.

 -- Функция: vertices_to_path (<v_list>)
     Преобразует список вершин <v_list> в список ребер пути,
     определяемого списком <v_list>.

 -- Функция: vertices_to_cycle (<v_list>)
     Преобразует список вершин <v_list> в список ребер цикла,
     определяемого списком <v_list>.


File: maxima.info,  Node: Пакет grobner,  Next: Пакет impdiff,  Prev: Пакет graphs,  Up: Top

51 Пакет grobner
****************

* Menu:

* Введение в пакет grobner::
* Функции и переменные пакета grobner::


File: maxima.info,  Node: Введение в пакет grobner,  Next: Функции и переменные пакета grobner,  Prev: Top,  Up: Top

51.1 Введение в пакет grobner
=============================

Пакет ‘grobner’ предназначен для работы с базисами Гребнера в Maxima.

Учебные материалы по _базисам Гребнера_ могут быть найдены по адресу

<http://www.geocities.com/CapeCanaveral/Hall/3131/>

Для использования, описанных ниже функций, необходимо загрузить пакет
‘grobner.lisp’.

     load("grobner");

Демонстрация может быть запущена так
     demo("grobner.demo");

или так
     batch("grobner.demo")

Некоторые вычисления в данной демонстрации занимают длительное время,
поэтому вывод демонстрации, записанный в файл ‘grobner-demo.output’,
может быть обнаружен в той же директории, где расположена демонстрация.

51.1.1 О пакете grobner
-----------------------

Пакет написан

Marek Rychlik

<http://alamos.math.arizona.edu>

и выпущен 2002-05-24 под лицензией General Public License (GPL) (см.
файл ‘grobner.lisp’.  Эта документация извлечена из файлов
‘README’, ‘grobner.lisp’, ‘grobner.demo’, ‘grobner-demo.output’

Günter Nowak.  Предложения по усовершенствованию документации можно
обсудить в списке рассылки _maxima_-mailing-list
<maxima@math.utexas.edu>.  Код несколько устарел.  Современные
реализации используют быстрый алгоритм _F4_, описанный в
A new efficient algorithm for computing Gröbner bases (F4)
Jean-Charles Faugère
LIP6/CNRS Université Paris VI
January 20, 1999

51.1.2 Реализации и допустимые способы упорядочивания одночленов в пакете grobner
---------------------------------------------------------------------------------

   • ‘lex’

     чисто лексикографический, используется по умолчанию для сравнения
     порядка одночленов
   • ‘grlex’

     порядок общей степени, совпадения разрешаются лексикографическим
     упорядочиванием

   • ‘grevlex’

     общая степень, совпадения разрешаются обратным лексикографическим
     упорядочиванием

   • ‘invlex’

     обратный лексикографический порядок


File: maxima.info,  Node: Функции и переменные пакета grobner,  Prev: Введение в пакет grobner,  Up: Top

51.2 Функции и переменные пакета grobner
========================================

51.2.1 Глобальные переключатели пакета grobner
----------------------------------------------

 -- Управляющая переменная: poly_monomial_order
     Значение по умолчанию: ‘lex’

     Этот глобальный переключатель управляет тем, какой порядок
     одночленов используется с многочленах и в вычислении базиса
     Гребнера.  Если значение не задано, то будет использовано ‘lex’.

 -- Управляющая переменная: poly_coefficient_ring
     Значение по умолчанию: ‘expression_ring’

     Этот переключатель указывает кольцо коэффициентов многочленов,
     используемое в вычислениях базиса Гребнера.  Если значение не
     задано, то используется общее кольцо выражений _maxima_.  Если
     необходимо, значение переключателя может быть установлено равным
     ‘ring_of_integers’.

 -- Управляющая переменная: poly_primary_elimination_order
     Значение по умолчанию: ‘false’

     Определяет порядок исключения переменных в функциях, основанных на
     исключении переменных.  Если значение не задано, то будет
     использовано ‘lex’.

 -- Управляющая переменная: poly_secondary_elimination_order
     Значение по умолчанию: ‘false’

     Определяет порядок сохраняемых переменных в функциях, основанных на
     исключении переменных.  Если значение не задано, то будет
     использовано ‘lex’.

 -- Управляющая переменная: poly_elimination_order
     Значение по умолчанию: ‘false’

     Определяет порядок исключения в вычислениях, основанных на
     исключении переменных.  Если значение задано, то оно перекрывает
     значение переменных ‘poly_primary_elimination_order’ и
     ‘poly_secondary_elimination_order’.  Пользователь должен
     обеспечить, что заданный порядок исключения применим для данного
     числа исключаемых переменных.

 -- Управляющая переменная: poly_return_term_list
     Значение по умолчанию: ‘false’

     Если равно ‘true’, то все функции пакета возвращают многочлены в
     виде списков членов с текущим порядком одночленов, а не в виде
     выражений _maxima_.

 -- Управляющая переменная: poly_grobner_debug
     Значение по умолчанию: ‘false’

     Если равно ‘true’, то выводится трассировка и отладочная
     информация.

 -- Управляющая переменная: poly_grobner_algorithm
     Значение по умолчанию: ‘buchberger’

     Возможные значения:
        • ‘buchberger’
        • ‘parallel_buchberger’
        • ‘gebauer_moeller’

     Определяет алгоритм, используемый для поиска базиса Гребнера.

 -- Управляющая переменная: poly_top_reduction_only
     Значение по умолчанию: ‘false’

     Если не равно ‘false’, то когда возможно используется только
     приведение верхнего уровня.  Приведение верхнего уровня означает,
     что алгоритм деления останавливается после первого приведения.

51.2.2 Простые операторы в пакете grobner
-----------------------------------------

‘poly_add’, ‘poly_subtract’, ‘poly_multiply’ и ‘poly_expt’ являются
арифметическими операциями над многочленами.  Они осуществляются над
внутренним представлением, но результат преобразуется обратно в
выражение _maxima_.

 -- Функция: poly_add (<poly1>, <poly2>, <varlist>)
     Складывает два многочлена <poly1> и <poly2>.

          (%i1) poly_add(z+x^2*y,x-z,[x,y,z]);
                                              2
          (%o1)                              x  y + x

 -- Функция: poly_subtract (<poly1>, <poly2>, <varlist>)
     Вычитает многочлен <poly2> из <poly1>.

          (%i1) poly_subtract(z+x^2*y,x-z,[x,y,z]);
                                                2
          (%o1)                          2 z + x  y - x

 -- Функция: poly_multiply (<poly1>, <poly2>, <varlist>)
     Возвращает произведение многочленов <poly1> и <poly2>.

          (%i2) poly_multiply(z+x^2*y,x-z,[x,y,z])-(z+x^2*y)*(x-z),expand;
          (%o1)                                  0

 -- Функция: poly_s_polynomial (<poly1>, <poly2>, <varlist>)
     Возвращает S-многочлен (_syzygy polynomial_) двух многочленов
     <poly1> и <poly2>.

 -- Функция: poly_primitive_part (<poly1>, <varlist>)
     Возвращает многочлен <poly> деленный на НОД своих коэффициентов.

          (%i1) poly_primitive_part(35*y+21*x,[x,y]);
          (%o1)                              5 y + 3 x

 -- Функция: poly_normalize (<poly>, <varlist>)
     Возвращает многочлен <poly> деленный на свой старший коэффициент.
     Подразумевается, что деление возможно, что может быть не всегда
     верно в случае колец не являющихся полями.

51.2.3 Другие функции пакета grobner
------------------------------------

 -- Функция: poly_expand (<poly>, <varlist>)
     Эта функция преобразует многочлен во внутреннее представление и
     обратно.  Она эквивалентна ‘expand(<poly>)’, если <poly> корректно
     преобразуется в многочлен.  Если представление не совместимо с
     многочленом от переменных <varlist>, то это приводит к ошибке.
     Данная функция может быть использована для проверки, возможно ли
     преобразование выражения во внутреннее представление.
     Нижеследующие примеры демонстрируют, что допустимы переменные с
     индексом или в виде трансцендентных функций.

          (%i1) poly_expand((x-y)*(y+x),[x,y]);
                                               2    2
          (%o1)                               x  - y
          (%i2) poly_expand((y+x)^2,[x,y]);
                                          2            2
          (%o2)                          y  + 2 x y + x
          (%i3) poly_expand((y+x)^5,[x,y]);
                            5      4         2  3       3  2      4      5
          (%o3)            y  + 5 x y  + 10 x  y  + 10 x  y  + 5 x  y + x
          (%i4) poly_expand(-1-x*exp(y)+x^2/sqrt(y),[x]);
                                                    2
                                            y      x
          (%o4)                       - x %e  + ------- - 1
                                                 sqrt(y)

          (%i5) poly_expand(-1-sin(x)^2+sin(x),[sin(x)]);
                                          2
          (%o5)                      - sin (x) + sin(x) - 1


 -- Функция: poly_expt (<poly>, <number>, <varlist>)
     возводит многочлен <poly> в положительную целую степень <number>.
     Если <number> не есть целое положительное число, то сигнализируется
     ошибка.

          (%i1) poly_expt(x-y,3,[x,y])-(x-y)^3,expand;
          (%o1)                                  0

 -- Функция: poly_content (<poly>. <varlist>)
     ‘poly_content’ вычисляет НОД коэффициентов многочлена

          (%i1) poly_content(35*y+21*x,[x,y]);
          (%o1)                                  7

 -- Функция: poly_pseudo_divide (<poly>, <polylist>, <varlist>)
     Псевдо-деление многочлена <poly> на список из n многочленов
     <polylist>.  Возвращает несколько значений.  Первое значение –
     список частных a.  Второе значение – остаток r.  Третье значение –
     скалярный коэффициент c, такой что c*poly делимо на <polylist> в
     кольце коэффициентов, не обязательно являющимся полем.  И наконец,
     четвертое значение – целое число, дающее число выполненных
     приведение.  Результирующие величины удовлетворяют выражению:

     c*poly=sum(a[i]*polylist[i],i=1...n)+r.

 -- Функция: poly_exact_divide (<poly1>, <poly2>, <varlist>)
     Делит многочлен <poly1> на многочлен <poly2>.  Предполагается, что
     деление без остатка возможно.  Возвращает частное.

 -- Функция: poly_normal_form (<poly>, <polylist>, <varlist>)
     Функция ‘poly_normal_form’ вычисляет нормальную форму многочлена
     <poly> по отношению к множеству многочленов <polylist>.

 -- Функция: poly_buchberger_criterion (<polylist>, <varlist>)
     Возвращает ‘true’ если <polylist> является базисом Гребнера с
     учетом текущего упорядочивания членов.  Использует критерий
     Бухбергера: для любых двух многочленов h1 и h2 из <polylist> e
     S-многочлен S(h1,h2) приводим к 0 по модулю <polylist>.

 -- Функция: poly_buchberger (<polylist_fl> <varlist>)
     ‘poly_buchberger’ применяет алгоритм Бухбергера к списку
     многочленов и возвращает результирующий базис Гребнера.

51.2.4 Стандартная пост-обработка для базиса Гребнера
-----------------------------------------------------

_Идеал k-го исключения_ I_k идеала I над K[ x[1],...,x[n] ] есть идеал
intersect(I, K[ x[k+1],...,x[n] ]).
_Частное идеалов_ I:J есть идеал {h| для всех w в J: w*h в I}.
Идеал I:p^inf есть идеал {h| существует n в N: p^n*h в I}.
Идеал I:J^inf есть идеал {h| существуют n в N и p в J: p^n*h в I}.
_Радикал идеала_ sqrt(I) есть идеал {h| существует n в N : h^n в I }.

 -- Функция: poly_reduction (<polylist>, <varlist>)
     ‘poly_reduction’ приводит список многочленов <polylist>, так что
     каждый многочлен полностью приведен по отношению к другим.

 -- Функция: poly_minimization (<polylist>, <varlist>)
     Возвращает подмножество списка многочленов <polylist>, порождающих
     тот же мономиальный идеал, что и <polylist> но минимальный, т.е.
     старшие одночлены многочленов из подмножества не делят ни один из
     других старших одночленов других многочленов этого подмножества.

 -- Функция: poly_normalize_list (<polylist>, <varlist>)
     ‘poly_normalize_list’ применяет ‘poly_normalize’ к каждому
     многочлену в списке.  Т.е.  делит каждый из многочленов списка
     <polylist> на его старший коэффициент.

 -- Функция: poly_grobner (<polylist>, <varlist>)
     Возвращает базис Гребнера идеала, порожденного многочленами
     <polylist>.  Зависит от глобальных флагов.

 -- Функция: poly_reduced_grobner (<polylist>, <varlist>)
     Возвращает приведенный базис Гребнера идеала, порожденного
     многочленами <polylist>.  Зависит от глобальных флагов.

 -- Функция: poly_depends_p (<poly>, <var>, <varlist>)
     ‘poly_depends’ проверяет, зависит ли многочлен от переменной <var>.

 -- Функция: poly_elimination_ideal (<polylist>, <number>, <varlist>)

     ‘poly_elimination_ideal’ возвращает базис Гребнера идеала number-го
     исключения идеала, порожденного списком многочленов (не обязательно
     образующих базис Гребнера).

 -- Функция: poly_colon_ideal (<polylist1>, <polylist2>, <varlist>)

     Возвращает приведенный базис Гребнера частного идеала

     I(polylist1):I(polylist2)

     где polylist1 и polylist2 – два списка многочленов.

 -- Функция: poly_ideal_intersection (<polylist1>, <polylist2>,
          <varlist>)

     ‘poly_ideal_intersection’ возвращает пересечение двух идеалов.

 -- Функция: poly_lcm (<poly1>, <poly2>, <varlist>)
     Возвращает наименьший общий множитель многочленов <poly1> и
     <poly2>.

 -- Функция: poly_gcd (<poly1>, <poly2>, <varlist>)
     Возвращает наибольший общий делитель многочленов <poly1> и <poly2>.

 -- Функция: poly_grobner_equal (<polylist1>, <polylist2>, <varlist>)
     ‘poly_grobner_equal’ проверяет порождают ли два базиса Гребнера
     один и тот же идеал.  Возвращает ‘true’ если два списка многочленов
     <polylist1> и <polylist2>, предполагаемые базисами Гребнера,
     порождают один и тот же идеал, и ‘false’ в противном случае.  Это
     эквивалентно проверке, что каждый многочлен первого базиса
     приводится к 0 по модулю второго и обратно.  Заметим, что в примере
     ниже первый список не есть базис Гребнера, и по этому результат
     есть ‘false’.

          (%i1) poly_grobner_equal([y+x,x-y],[x,y],[x,y]);
          (%o1)                         false

 -- Функция: poly_grobner_subsetp (<polylist1>, <polylist2>, <varlist>)

     ‘poly_grobner_subsetp’ проверяет содержится ли идеал, порожденный
     <polylist1>, в идеале, порожденном <polylist2>.  Чтобы тест всегда
     выполнялся, нужно чтобы <polylist2> был бы базисом Гребнера.

 -- Функция: poly_grobner_member (<poly>, <polylist>, <varlist>)

     Возвращает ‘true’, если многочлен <poly> принадлежит к идеалу,
     порожденному списком многочленов <polylist>, который предполагается
     базисом Гребнера.  Иначе возвращает ‘false’.

 -- Функция: poly_ideal_saturation1 (<polylist>, <poly>, <varlist>)
     Возвращает приведенный базис Гребнера насыщения идеала

     I(polylist):poly^inf

     Геометрически, над алгебраически замкнутым полем, это есть
     множество многочленов в идеале, порожденном <polylist>, которые не
     исчезают на многообразии <poly>.

 -- Функция: poly_ideal_saturation (<polylist1>, <polylist2>, <varlist>)
     Возвращает приведенный базис Гребнера насыщения идеала

     I(polylist1):I(polylist2)^inf

     Геометрически, над алгебраически замкнутым полем, это есть
     множество многочленов в идеале, порожденном <polylist1>, которые не
     исчезают на многообразии <polylist2>.

 -- Функция: poly_ideal_polysaturation1 (<polylist1>, <polylist2>,
          <varlist>)
     <polylist2> – есть список n многочленов ‘[poly1,...,polyn]’.
     Возвращает приведенный базис Гребнера идеала

     I(polylist):poly1^inf:...:polyn^inf

     полученного последовательным насыщением многочленами из списка
     <polylist2> идеала, порожденного списком многочленов <polylist1>.

 -- Функция: poly_ideal_polysaturation (<polylist>, <polylistlist>,
          <varlist>)
     <polylistlist> – есть список n списков многочленов
     ‘[polylist1,...,polylistn]’.  Возвращает приведенный базис Гребнера
     насыщения идеала

     I(polylist):I(polylist_1)^inf:...:I(polylist_n)^inf

 -- Функция: poly_saturation_extension (<poly>, <polylist>, <varlist1>,
          <varlist2>)

     ‘poly_saturation_extension’ реализует знаменитый трюк Рабиновича.

 -- Функция: poly_polysaturation_extension (<poly>, <polylist>,
          <varlist1>, <varlist2>)


File: maxima.info,  Node: Пакет impdiff,  Next: Пакет implicit_plot,  Prev: Пакет grobner,  Up: Top

52 Пакет impdiff
****************

* Menu:

* Функции и переменные пакета impdiff::


File: maxima.info,  Node: Функции и переменные пакета impdiff,  Prev: Пакет impdiff,  Up: Пакет impdiff

52.1 Функции и переменные пакета impdiff
========================================

 -- Функция: implicit_derivative (<f>,<indvarlist>,<orderlist>,<depvar>)
     Эта процедура вычисляет неявную производную функции многих
     переменных.  <f> – функция-массив, с индексами, обозначающими
     порядок производных по переменным из <indvarlist>; <indvarlist> –
     список независимых переменных; <orderlist> – требуемый порядок; и
     <depvar> – зависимая переменная.

     Для того, чтобы использовать эту функцию, сначала напишите
     ‘load("impdiff")’.


File: maxima.info,  Node: Пакет implicit_plot,  Next: Пакет interpol,  Prev: Пакет impdiff,  Up: Top

53 Пакет implicit_plot
**********************

* Menu:

* Функции и переменные пакета implicit_plot::


File: maxima.info,  Node: Функции и переменные пакета implicit_plot,  Prev: Пакет implicit_plot,  Up: Пакет implicit_plot

53.1 Функции и переменные пакета implicit_plot
==============================================

 -- Функция: implicit_plot (<expr>, <x_range>, <y_range>)
 -- Функция: implicit_plot ([<expr_1>, ..., <expr_n>], <x_range>,
          <y_range>)

     Строит график одного или более неявных выражений.  <expr> –
     изображаемое выражение, <x_range> – пределы по горизонтальной оси,
     <y_range> – пределы по вертикальной оси.  ‘implicit_plot’ учитывает
     глобальные установки для gnuplot, задаваемые при помощи функции
     <set_plot_option>.  Опции могут быть указаны в ‘implicit_plot’ как
     дополнительные необязательные аргументы.

     Функция ‘implicit_plot’ работает, отслеживая изменения знака в
     области, заданной пределами <x_range> и <y_range>, и может
     ошибаться в сложных случаях.

     Команда ‘load("implicit_plot")’ загружает данную функцию.

     Пример:
          (%i1) implicit_plot (x^2 = y^3 - 3*y + 1, [x, -4, 4], [y, -4, 4],
           [gnuplot_preamble, "set zeroaxis"]);


File: maxima.info,  Node: Пакет interpol,  Next: Package lapack,  Prev: Пакет implicit_plot,  Up: Top

54 Пакет interpol
*****************

* Menu:

* Введение в пакет interpol::
* Функции и переменные пакета interpol::


File: maxima.info,  Node: Введение в пакет interpol,  Next: Функции и переменные пакета interpol,  Prev: Пакет interpol,  Up: Пакет interpol

54.1 Введение в пакет interpol
==============================

Пакет ‘interpol’ определяет методы Лагранжа, линейный и и метод
кубических сплайнов для полиномиальной интерполяции.

   С комментариями, сообщениями об ошибках и предложениями, пожалуйста
обращайтесь ко мне по адресу <’mario AT edu DOT xunta DOT es’>.


File: maxima.info,  Node: Функции и переменные пакета interpol,  Prev: Введение в пакет interpol,  Up: Пакет interpol

54.2 Функции и переменные пакета interpol
=========================================

 -- Функция: lagrange (<points>)
 -- Функция: lagrange (<points>, <option>)
     Вычисляет полиномиальную интерполяцию методом Лагранжа.  Аргумент
     <points> должен быть либо:

        • матрицей из двух колонок, ‘p:matrix([2,4],[5,6],[9,3])’,
        • списком пар, ‘p: [[2,4],[5,6],[9,3]]’,
        • списком чисел ‘p: [4,6,3]’, в этом случае абсцисса будет
          назначена автоматически равной 1, 2, 3 и т.д.

     В первых двух случаях, перед проведением вычислений, пары
     упорядочиваются в соответствии со значением первой координаты.

     Аргумент <option> позволяет выбрать имя независимой переменной, по
     умолчанию равной ‘'x’.  Чтобы задать другую переменную напишите
     ‘varname='z’.

     Отметим, что при работе с многочленами высокого порядка, вычисления
     с плавающей точкой нестабильны.

     Примеры:

          (%i1) load("interpol")$
          (%i2) p:[[7,2],[8,2],[1,5],[3,2],[6,7]]$
          (%i3) lagrange(p);
                           4        3         2
                       73 x    701 x    8957 x    5288 x   186
          (%o3)        ----- - ------ + ------- - ------ + ---
                        420     210       420      105      5
          (%i4) f(x):=''%;
                               4        3         2
                           73 x    701 x    8957 x    5288 x   186
          (%o4)    f(x) := ----- - ------ + ------- - ------ + ---
                            420     210       420      105      5
          (%i5) /* Evaluate the polynomial at some points */
                map(f,[2.3,5/7,%pi]);
                                       919062
          (%o5)  [- 1.567534999999992, ------,
                                       84035
                                   4          3           2
                             73 %pi    701 %pi    8957 %pi    5288 %pi   186
                             ------- - -------- + --------- - -------- + ---]
                               420       210         420        105       5
          (%i6) %,numer;
          (%o6) [- 1.567534999999992, 10.9366573451538, 2.89319655125692]
          (%i7) load("draw")$  /* load draw package */
          (%i8) /* Plot the polynomial together with points */
                draw2d(
                  color      = red,
                  key        = "Lagrange polynomial",
                  explicit(f(x),x,0,10),
                  point_size = 3,
                  color      = blue,
                  key        = "Sample points",
                  points(p))$
          (%i9) /* Change variable name */
                lagrange(p, varname=w);
                           4        3         2
                       73 w    701 w    8957 w    5288 w   186
          (%o9)        ----- - ------ + ------- - ------ + ---
                        420     210       420      105      5

 -- Функция: charfun2 (<x>, <a>, <b>)
     Возвращает ‘true’ если число <x> принадлежит интервалу [a, b), и
     ‘false’ в противном случае.

 -- Функция: linearinterpol (<points>)
 -- Функция: linearinterpol (<points>, <option>)
     Вычисляет полиномиальную интерполяцию линейным методом.  Аргумент
     <points> должен быть либо:

        • матрицей из двух колонок, ‘p:matrix([2,4],[5,6],[9,3])’,
        • списком пар, ‘p: [[2,4],[5,6],[9,3]]’,
        • списком чисел ‘p: [4,6,3]’, в этом случае абсцисса будет
          назначена автоматически равной 1, 2, 3 и т.д.

     В первых двух случаях, перед проведением вычислений, пары
     упорядочиваются в соответствии со значением первой координаты.

     Аргумент <option> позволяет выбрать имя независимой переменной, по
     умолчанию равной ‘'x’.  Чтобы задать другую переменную напишите
     ‘varname='z’.

     Примеры:
          (%i1) load("interpol")$
          (%i2) p: matrix([7,2],[8,3],[1,5],[3,2],[6,7])$
          (%i3) linearinterpol(p);
                  13   3 x
          (%o3)  (-- - ---) charfun2(x, minf, 3)
                  2     2
           + (x - 5) charfun2(x, 7, inf) + (37 - 5 x) charfun2(x, 6, 7)
              5 x
           + (--- - 3) charfun2(x, 3, 6)
               3

          (%i4) f(x):=''%;
                          13   3 x
          (%o4)  f(x) := (-- - ---) charfun2(x, minf, 3)
                          2     2
           + (x - 5) charfun2(x, 7, inf) + (37 - 5 x) charfun2(x, 6, 7)
              5 x
           + (--- - 3) charfun2(x, 3, 6)
               3
          (%i5)  /* Evaluate the polynomial at some points */
                 map(f,[7.3,25/7,%pi]);
                                      62  5 %pi
          (%o5)                 [2.3, --, ----- - 3]
                                      21    3
          (%i6) %,numer;
          (%o6)  [2.3, 2.952380952380953, 2.235987755982989]
          (%i7) load("draw")$  /* load draw package */
          (%i8)  /* Plot the polynomial together with points */
                 draw2d(
                   color      = red,
                   key        = "Linear interpolator",
                   explicit(f(x),x,-5,20),
                   point_size = 3,
                   color      = blue,
                   key        = "Sample points",
                   points(args(p)))$
          (%i9)  /* Change variable name */
                 linearinterpol(p, varname='s);
                 13   3 s
          (%o9) (-- - ---) charfun2(s, minf, 3)
                 2     2
           + (s - 5) charfun2(s, 7, inf) + (37 - 5 s) charfun2(s, 6, 7)
              5 s
           + (--- - 3) charfun2(s, 3, 6)
               3

 -- Функция: cspline (<points>)
 -- Функция: cspline (<points>, <option1>, <option2>, ...)
     Вычисляет полиномиальную интерполяцию методом кубических сплайнов.
     Аргумент <points> должен быть либо:

        • матрицей из двух колонок, ‘p:matrix([2,4],[5,6],[9,3])’,
        • списком пар, ‘p: [[2,4],[5,6],[9,3]]’,
        • списком чисел ‘p: [4,6,3]’, в этом случае абсцисса будет
          назначена автоматически равной 1, 2, 3 и т.д.

     В первых двух случаях, перед проведением вычислений, пары
     упорядочиваются в соответствии со значением первой координаты.

     Существует три специальные опции:
        • ‘'d1’, по умолчанию ‘'unknown’, – первая производная в точке
          x_1.  Если ‘'unknown’, то вторая производная в точке x_1
          предполагается равной 0 (натуральный кубический сплайн).  Если
          задана, то вторая производная вычисляется исходя из этого
          числа.

        • ‘'dn’, по умолчанию ‘'unknown’, – первая производная в точке
          x_n.  Если ‘'unknown’, то вторая производная в точке x_n
          предполагается равной 0 (натуральный кубический сплайн).  Если
          задана, то вторая производная вычисляется исходя из этого
          числа.

        • ‘'varname’, по умолчанию ‘'x’, – имя независимой переменной.

     Примеры:
          (%i1) load("interpol")$
          (%i2) p:[[7,2],[8,2],[1,5],[3,2],[6,7]]$
          (%i3) /* Unknown first derivatives at the extremes
                   is equivalent to natural cubic splines */
                cspline(p);
                        3         2
                  1159 x    1159 x    6091 x   8283
          (%o3)  (------- - ------- - ------ + ----) charfun2(x, minf, 3)
                   3288      1096      3288    1096
                      3         2
                2587 x    5174 x    494117 x   108928
           + (- ------- + ------- - -------- + ------) charfun2(x, 7, inf)
                 1644       137       1644      137
                    3          2
              4715 x    15209 x    579277 x   199575
           + (------- - -------- + -------- - ------) charfun2(x, 6, 7)
               1644       274        1644      274
                      3         2
                3287 x    2223 x    48275 x   9609
           + (- ------- + ------- - ------- + ----) charfun2(x, 3, 6)
                 4932       274      1644     274

          (%i4) f(x):=''%$
          (%i5) /* Some evaluations */
                map(f,[2.3,5/7,%pi]), numer;
          (%o5) [1.991460766423356, 5.823200187269903, 2.227405312429507]
          (%i6) load("draw")$  /* load draw package */
          (%i7) /* Plotting interpolating function */
                draw2d(
                  color      = red,
                  key        = "Cubic splines",
                  explicit(f(x),x,0,10),
                  point_size = 3,
                  color      = blue,
                  key        = "Sample points",
                  points(p))$
          (%i8) /* New call, but giving values at the derivatives */
                cspline(p,d1=0,dn=0);
                        3          2
                  1949 x    11437 x    17027 x   1247
          (%o8)  (------- - -------- + ------- + ----) charfun2(x, minf, 3)
                   2256       2256      2256     752
                      3          2
                1547 x    35581 x    68068 x   173546
           + (- ------- + -------- - ------- + ------) charfun2(x, 7, inf)
                  564       564        141      141
                   3          2
              607 x    35147 x    55706 x   38420
           + (------ - -------- + ------- - -----) charfun2(x, 6, 7)
               188       564        141      47
                      3         2
                3895 x    1807 x    5146 x   2148
           + (- ------- + ------- - ------ + ----) charfun2(x, 3, 6)
                 5076       188      141      47
          (%i8) /* Defining new interpolating function */
                g(x):=''%$
          (%i9) /* Plotting both functions together */
                draw2d(
                  color      = black,
                  key        = "Cubic splines (default)",
                  explicit(f(x),x,0,10),
                  color      = red,
                  key        = "Cubic splines (d1=0,dn=0)",
                  explicit(g(x),x,0,10),
                  point_size = 3,
                  color      = blue,
                  key        = "Sample points",
                  points(p))$


File: maxima.info,  Node: Package lapack,  Next: Package lbfgs,  Prev: Пакет interpol,  Up: Top

55 lapack
*********

* Menu:

* Introduction to lapack::
* Functions and Variables for lapack::


File: maxima.info,  Node: Introduction to lapack,  Next: Functions and Variables for lapack,  Prev: Package lapack,  Up: Package lapack

55.1 Introduction to lapack
===========================

‘lapack’ is a Common Lisp translation (via the program ‘f2cl’) of the
Fortran library LAPACK, as obtained from the SLATEC project.


File: maxima.info,  Node: Functions and Variables for lapack,  Prev: Introduction to lapack,  Up: Package lapack

55.2 Functions and Variables for lapack
=======================================

 -- Function: dgeev
          dgeev (<A>)
          dgeev (<A>, <right_p>, <left_p>)

     Computes the eigenvalues and, optionally, the eigenvectors of a
     matrix <A>.  All elements of <A> must be integer or floating point
     numbers.  <A> must be square (same number of rows and columns).
     <A> might or might not be symmetric.

     To make use of this function, you must load the LaPack package via
     ‘load("lapack")’.

     ‘dgeev(<A>)’ computes only the eigenvalues of <A>.  ‘dgeev(<A>,
     <right_p>, <left_p>)’ computes the eigenvalues of <A> and the right
     eigenvectors when <right_p> = ‘true’ and the left eigenvectors when
     <left_p> = ‘true’.

     A list of three items is returned.  The first item is a list of the
     eigenvalues.  The second item is ‘false’ or the matrix of right
     eigenvectors.  The third item is ‘false’ or the matrix of left
     eigenvectors.

     The right eigenvector v_j (the j-th column of the right eigenvector
     matrix) satisfies

     A . v_j = lambda_j . v_j

     where lambda_j is the corresponding eigenvalue.  The left
     eigenvector u_j (the j-th column of the left eigenvector matrix)
     satisfies

     u_j^H . A = lambda_j . u_j^H

     where u_j^H denotes the conjugate transpose of u_j. For a Maxima
     function to compute the conjugate transpose, *note ctranspose::.

     The computed eigenvectors are normalized to have Euclidean norm
     equal to 1, and largest component has imaginary part equal to zero.

     Example:

          (%i1) load ("lapack")$
          (%i2) fpprintprec : 6;
          (%o2)                           6
          (%i3) M : matrix ([9.5, 1.75], [3.25, 10.45]);
                                   [ 9.5   1.75  ]
          (%o3)                    [             ]
                                   [ 3.25  10.45 ]
          (%i4) dgeev (M);
          (%o4)          [[7.54331, 12.4067], false, false]
          (%i5) [L, v, u] : dgeev (M, true, true);
                                     [ - 0.666642  - 0.515792 ]
          (%o5) [[7.54331, 12.4067], [                        ],
                                     [  0.745378   - 0.856714 ]
                                                [ - 0.856714  - 0.745378 ]
                                                [                        ]]
                                                [  0.515792   - 0.666642 ]
          (%i6) D : apply (diag_matrix, L);
                                [ 7.54331     0    ]
          (%o6)                 [                  ]
                                [    0     12.4067 ]
          (%i7) M . v - v . D;
                          [      0.0       - 8.88178e-16 ]
          (%o7)           [                              ]
                          [ - 8.88178e-16       0.0      ]
          (%i8) transpose (u) . M - D . transpose (u);
                               [ 0.0  - 4.44089e-16 ]
          (%o8)                [                    ]
                               [ 0.0       0.0      ]

 -- Function: dgeqrf (<A>)

     Computes the QR decomposition of the matrix <A>.  All elements of
     <A> must be integer or floating point numbers.  <A> may or may not
     have the same number of rows and columns.

     To make use of this function, you must load the LaPack package via
     ‘load("lapack")’.

     The real square matrix A can be decomposed as

     A = QR

     where Q is a square orthogonal matrix with the same number of rows
     as A and R is an upper triangular matrix and is the same size as A.

     A list of two items is returned.  The first item is the matrix Q.
     The second item is the matrix R, The product Q . R, where "."  is
     the noncommutative multiplication operator, is equal to <A>
     (ignoring floating point round-off errors).

          (%i1) load ("lapack")$
          (%i2) fpprintprec : 6;
          (%o2)                           6
          (%i3) M : matrix ([1, -3.2, 8], [-11, 2.7, 5.9]);
                                [  1    - 3.2   8  ]
          (%o3)                 [                  ]
                                [ - 11   2.7   5.9 ]
          (%i4) [q, r] : dgeqrf (M);
                 [ - 0.0905357  0.995893  ]
          (%o4) [[                        ],
                 [  0.995893    0.0905357 ]
                                         [ - 11.0454   2.97863   5.15148 ]
                                         [                               ]]
                                         [    0.0     - 2.94241  8.50131 ]
          (%i5) q . r - M;
                   [ - 7.77156e-16   1.77636e-15   - 8.88178e-16 ]
          (%o5)    [                                             ]
                   [      0.0       - 1.33227e-15   8.88178e-16  ]
          (%i6) mat_norm (%, 1);
          (%o6)                      3.10862e-15

 -- Function: dgesv (<A>, <b>)

     Computes the solution <x> of the linear equation <A> <x> = <b>,
     where <A> is a square matrix, and b is a matrix of the same number
     of rows as <A> and any number of columns.  The return value x is
     the same size as b.

     To make use of this function, you must load the LaPack package via
     ‘load("lapack")’.

     The elements of <A> and <b> must evaluate to real floating point
     numbers via ‘float’; thus elements may be any numeric type,
     symbolic numerical constants, or expressions which evaluate to
     floats.  The elements of <x> are always floating point numbers.
     All arithmetic is carried out as floating point operations.

     ‘dgesv’ computes the solution via the LU decomposition of <A>.

     Examples:

     ‘dgesv’ computes the solution of the linear equation <A> <x> = <b>.

          (%i1) load("lapack")$
          (%i2) A : matrix ([1, -2.5], [0.375, 5]);
                                  [   1    - 2.5 ]
          (%o2)                   [              ]
                                  [ 0.375    5   ]
          (%i3) b : matrix ([1.75], [-0.625]);
                                     [  1.75   ]
          (%o3)                      [         ]
                                     [ - 0.625 ]
          (%i4) x : dgesv (A, b);
                              [  1.2105263157894737   ]
          (%o4)               [                       ]
                              [ - 0.21578947368421053 ]
          (%i5) dlange (inf_norm, b - A . x);
          (%o5)                          0.0

     <b> is a matrix with the same number of rows as <A> and any number
     of columns.  <x> is the same size as <b>.

          (%i1) load ("lapack")$
          (%i2) A : matrix ([1, -0.15], [1.82, 2]);
                                  [  1    - 0.15 ]
          (%o2)                   [              ]
                                  [ 1.82    2    ]
          (%i3) b : matrix ([3.7, 1, 8], [-2.3, 5, -3.9]);
                                 [  3.7   1    8   ]
          (%o3)                  [                 ]
                                 [ - 2.3  5  - 3.9 ]
          (%i4) x : dgesv (A, b);
          (%o4)
           [ 3.1038275406951175   1.2098548174219095  6.7817861856577215  ]
           [                                                              ]
           [ - 3.974483062032557  1.3990321161460624  - 8.121425428948527 ]
          (%i5) dlange (inf_norm, b - A . x);
          (%o5)                1.1102230246251565e-15

     The elements of <A> and <b> must evaluate to real floating point
     numbers.

          (%i1) load ("lapack")$
          (%i2) A : matrix ([5, -%pi], [1b0, 11/17]);
                                  [   5    - %pi ]
                                  [              ]
          (%o2)                   [         11   ]
                                  [ 1.0b0   --   ]
                                  [         17   ]
          (%i3) b : matrix ([%e], [sin(1)]);
                                     [   %e   ]
          (%o3)                      [        ]
                                     [ sin(1) ]
          (%i4) x : dgesv (A, b);
                               [ 0.6903756431559864  ]
          (%o4)                [                     ]
                               [ 0.23351098255295172 ]
          (%i5) dlange (inf_norm, b - A . x);
          (%o5)                 2.220446049250313e-16

 -- Function: dgesvd
          dgesvd (<A>)
          dgesvd (<A>, <left_p>, <right_p>)

     Computes the singular value decomposition (SVD) of a matrix <A>,
     comprising the singular values and, optionally, the left and right
     singular vectors.  All elements of <A> must be integer or floating
     point numbers.  <A> might or might not be square (same number of
     rows and columns).

     To make use of this function, you must load the LaPack package via
     ‘load("lapack")’.

     Let m be the number of rows, and n the number of columns of <A>.
     The singular value decomposition of A comprises three matrices, U,
     Sigma, and V, such that

     {A} = {U} . {Sigma} . {V}^T

     where U is an m-by-m unitary matrix, Sigma is an m-by-n diagonal
     matrix, and V is an n-by-n unitary matrix.

     Let sigma[i] be a diagonal element of Sigma, that is, <Sigma>[i, i]
     = <sigma>[i]. The elements sigma[i] are the so-called singular
     values of A; these are real and nonnegative, and returned in
     descending order.  The first min(m, n) columns of U and V are the
     left and right singular vectors of A. Note that ‘dgesvd’ returns
     the transpose of V, not V itself.

     ‘dgesvd(<A>)’ computes only the singular values of <A>.
     ‘dgesvd(<A>, <left_p>, <right_p>)’ computes the singular values of
     <A> and the left singular vectors when <left_p> = ‘true’ and the
     right singular vectors when <right_p> = ‘true’.

     A list of three items is returned.  The first item is a list of the
     singular values.  The second item is ‘false’ or the matrix of left
     singular vectors.  The third item is ‘false’ or the matrix of right
     singular vectors.

     Example:

          (%i1) load ("lapack")$
          (%i2) fpprintprec : 6;
          (%o2)                           6
          (%i3) M: matrix([1, 2, 3], [3.5, 0.5, 8], [-1, 2, -3], [4, 9, 7]);
                                  [  1    2    3  ]
                                  [               ]
                                  [ 3.5  0.5   8  ]
          (%o3)                   [               ]
                                  [ - 1   2   - 3 ]
                                  [               ]
                                  [  4    9    7  ]
          (%i4) dgesvd (M);
          (%o4)     [[14.4744, 6.38637, 0.452547], false, false]
          (%i5) [sigma, U, VT] : dgesvd (M, true, true);
          (%o5) [[14.4744, 6.38637, 0.452547],
          [ - 0.256731  0.00816168   0.959029    - 0.119523 ]
          [                                                 ]
          [ - 0.526456   0.672116   - 0.206236   - 0.478091 ]
          [                                                 ],
          [  0.107997   - 0.532278  - 0.0708315  - 0.83666  ]
          [                                                 ]
          [ - 0.803287  - 0.514659  - 0.180867    0.239046  ]
          [ - 0.374486  - 0.538209  - 0.755044 ]
          [                                    ]
          [  0.130623   - 0.836799    0.5317   ]]
          [                                    ]
          [ - 0.917986   0.100488    0.383672  ]
          (%i6) m : length (U);
          (%o6)                           4
          (%i7) n : length (VT);
          (%o7)                           3
          (%i8) Sigma:
            genmatrix(lambda ([i, j], if i=j then sigma[i] else 0),
                      m, n);
                           [ 14.4744     0        0     ]
                           [                            ]
                           [    0     6.38637     0     ]
          (%o8)            [                            ]
                           [    0        0     0.452547 ]
                           [                            ]
                           [    0        0        0     ]
          (%i9) U . Sigma . VT - M;
                    [  1.11022e-15        0.0       1.77636e-15 ]
                    [                                           ]
                    [  1.33227e-15    1.66533e-15       0.0     ]
          (%o9)     [                                           ]
                    [ - 4.44089e-16  - 8.88178e-16  4.44089e-16 ]
                    [                                           ]
                    [  8.88178e-16    1.77636e-15   8.88178e-16 ]
          (%i10) transpose (U) . U;
                 [     1.0      5.55112e-17    2.498e-16     2.77556e-17  ]
                 [                                                        ]
                 [ 5.55112e-17      1.0       5.55112e-17    4.16334e-17  ]
          (%o10) [                                                        ]
                 [  2.498e-16   5.55112e-17       1.0       - 2.08167e-16 ]
                 [                                                        ]
                 [ 2.77556e-17  4.16334e-17  - 2.08167e-16       1.0      ]
          (%i11) VT . transpose (VT);
                    [      1.0           0.0      - 5.55112e-17 ]
                    [                                           ]
          (%o11)    [      0.0           1.0       5.55112e-17  ]
                    [                                           ]
                    [ - 5.55112e-17  5.55112e-17       1.0      ]

 -- Function: dlange (<norm>, <A>)
 -- Function: zlange (<norm>, <A>)

     Computes a norm or norm-like function of the matrix <A>.  If <A> is
     a real matrix, use ‘dlange’.  For a matrix with complex elements,
     use ‘zlange’.

     To make use of this function, you must load the LaPack package via
     ‘load("lapack")’.

     ‘norm’ specifies the kind of norm to be computed:
     ‘max’
          Compute max(abs(A(i, j))) where i and j range over the rows
          and columns, respectively, of A. Note that this function is
          not a proper matrix norm.
     ‘one_norm’
          Compute the L[1] norm of A, that is, the maximum of the sum of
          the absolute value of elements in each column.
     ‘inf_norm’
          Compute the L[inf] norm of A, that is, the maximum of the sum
          of the absolute value of elements in each row.
     ‘frobenius’
          Compute the Frobenius norm of A, that is, the square root of
          the sum of squares of the matrix elements.

 -- Function: dgemm
          dgemm (<A>, <B>)
          dgemm (<A>, <B>, <options>)
     Compute the product of two matrices and optionally add the product
     to a third matrix.

     In the simplest form, ‘dgemm(<A>, <B>)’ computes the product of the
     two real matrices, <A> and <B>.

     To make use of this function, you must load the LaPack package via
     ‘load("lapack")’.

     In the second form, ‘dgemm’ computes <alpha> * <A> * <B> + <beta> *
     <C> where <A>, <B>, and <C> are real matrices of the appropriate
     sizes and alpha and beta are real numbers.  Optionally, <A> and/or
     <B> can be transposed before computing the product.  The extra
     parameters are specified by optional keyword arguments: The keyword
     arguments are optional and may be specified in any order.  They all
     take the form ‘key=val’.  The keyword arguments are:

     ‘C’
          The matrix <C> that should be added.  The default is ‘false’,
          which means no matrix is added.
     ‘alpha’
          The product of <A> and <B> is multiplied by this value.  The
          default is 1.
     ‘beta’
          If a matrix <C> is given, this value multiplies <C> before it
          is added.  The default value is 0, which implies that <C> is
          not added, even if <C> is given.  Hence, be sure to specify a
          non-zero value for beta.
     ‘transpose_a’
          If ‘true’, the transpose of <A> is used instead of <A> for the
          product.  The default is ‘false’.
     ‘transpose_b’
          If ‘true’, the transpose of <B> is used instead of <B> for the
          product.  The default is ‘false’.

          (%i1) load ("lapack")$
          (%i2) A : matrix([1,2,3],[4,5,6],[7,8,9]);
                                     [ 1  2  3 ]
                                     [         ]
          (%o2)                      [ 4  5  6 ]
                                     [         ]
                                     [ 7  8  9 ]
          (%i3) B : matrix([-1,-2,-3],[-4,-5,-6],[-7,-8,-9]);
                                  [ - 1  - 2  - 3 ]
                                  [               ]
          (%o3)                   [ - 4  - 5  - 6 ]
                                  [               ]
                                  [ - 7  - 8  - 9 ]
          (%i4) C : matrix([3,2,1],[6,5,4],[9,8,7]);
                                     [ 3  2  1 ]
                                     [         ]
          (%o4)                      [ 6  5  4 ]
                                     [         ]
                                     [ 9  8  7 ]
          (%i5) dgemm(A,B);
                            [ - 30.0   - 36.0   - 42.0  ]
                            [                           ]
          (%o5)             [ - 66.0   - 81.0   - 96.0  ]
                            [                           ]
                            [ - 102.0  - 126.0  - 150.0 ]
          (%i6) A . B;
                               [ - 30   - 36   - 42  ]
                               [                     ]
          (%o6)                [ - 66   - 81   - 96  ]
                               [                     ]
                               [ - 102  - 126  - 150 ]
          (%i7) dgemm(A,B,transpose_a=true);
                            [ - 66.0  - 78.0   - 90.0  ]
                            [                          ]
          (%o7)             [ - 78.0  - 93.0   - 108.0 ]
                            [                          ]
                            [ - 90.0  - 108.0  - 126.0 ]
          (%i8) transpose(A) . B;
                               [ - 66  - 78   - 90  ]
                               [                    ]
          (%o8)                [ - 78  - 93   - 108 ]
                               [                    ]
                               [ - 90  - 108  - 126 ]
          (%i9) dgemm(A,B,c=C,beta=1);
                            [ - 27.0  - 34.0   - 41.0  ]
                            [                          ]
          (%o9)             [ - 60.0  - 76.0   - 92.0  ]
                            [                          ]
                            [ - 93.0  - 118.0  - 143.0 ]
          (%i10) A . B + C;
                               [ - 27  - 34   - 41  ]
                               [                    ]
          (%o10)               [ - 60  - 76   - 92  ]
                               [                    ]
                               [ - 93  - 118  - 143 ]
          (%i11) dgemm(A,B,c=C,beta=1, alpha=-1);
                               [ 33.0   38.0   43.0  ]
                               [                     ]
          (%o11)               [ 72.0   86.0   100.0 ]
                               [                     ]
                               [ 111.0  134.0  157.0 ]
          (%i12) -A . B + C;
                                  [ 33   38   43  ]
                                  [               ]
          (%o12)                  [ 72   86   100 ]
                                  [               ]
                                  [ 111  134  157 ]

 -- Function: zgeev
          zgeev (<A>)
          zgeev (<A>, <right_p>, <left_p>)

     Like ‘dgeev’, but the matrix <A> is complex.

     To make use of this function, you must load the LaPack package via
     ‘load("lapack")’.

 -- Function: zheev
          zheev (<A>)
          zheev (<A>, <eigvec_p>)

     Like ‘dgeev’, but the matrix <A> is assumed to be a square complex
     Hermitian matrix.  If <eigvec_p> is ‘true’, then the eigenvectors
     of the matrix are also computed.

     To make use of this function, you must load the LaPack package via
     ‘load("lapack")’.

     No check is made that the matrix <A> is, in fact, Hermitian.

     A list of two items is returned, as in ‘dgeev’: a list of
     eigenvalues, and ‘false’ or the matrix of the eigenvectors.

          (%i1) load("lapack")$
          (%i2) M: matrix(
               [9.14 +%i*0.00 ,   -4.37 -%i*9.22 ,  -1.98 -%i*1.72 ,  -8.96 -%i*9.50],
               [-4.37 +%i*9.22 ,  -3.35 +%i*0.00 ,   2.25 -%i*9.51 ,   2.57 +%i*2.40],
               [-1.98 +%i*1.72 ,   2.25 +%i*9.51 ,  -4.82 +%i*0.00 ,  -3.24 +%i*2.04],
               [-8.96 +%i*9.50 ,   2.57 -%i*2.40 ,  -3.24 -%i*2.04 ,   8.44 +%i*0.00]);
                         [      9.14      ]         [ - 9.22 %i - 4.37 ]
                         [                ]         [                  ]
                         [ 9.22 %i - 4.37 ]         [      - 3.35      ]
          (%o2)  Col 1 = [                ] Col 2 = [                  ]
                         [ 1.72 %i - 1.98 ]         [  9.51 %i + 2.25  ]
                         [                ]         [                  ]
                         [ 9.5 %i - 8.96  ]         [  2.57 - 2.4 %i   ]
                           [ - 1.72 %i - 1.98 ]         [ - 9.5 %i - 8.96 ]
                           [                  ]         [                 ]
                           [  2.25 - 9.51 %i  ]         [  2.4 %i + 2.57  ]
                   Col 3 = [                  ] Col 4 = [                 ]
                           [      - 4.82      ]         [ 2.04 %i - 3.24  ]
                           [                  ]         [                 ]
                           [ - 2.04 %i - 3.24 ]         [      8.44       ]
          (%i3) zheev(M);
          (%o3) [[- 16.004746472094734, - 6.764970154793324,
                             6.6657114535070985, 25.51400517338097], false]
          (%i4) E: zheev(M,true)$
          (%i5) E[1];
          (%o5) [- 16.004746472094737, - 6.764970154793325,
                                     6.665711453507101, 25.514005173380962]
          (%i6) E[2];
                         [  0.26746505331727455 %i + 0.21754535866650165  ]
                         [                                                ]
                         [  0.002696730886619885 %i + 0.6968836773391712  ]
          (%o6)  Col 1 = [                                                ]
                         [ - 0.6082406376714117 %i - 0.012106142926979313 ]
                         [                                                ]
                         [              0.15930818580950368               ]
                   [  0.26449374706674444 %i + 0.4773693349937472   ]
                   [                                                ]
                   [ - 0.28523890360316206 %i - 0.14143627420116733 ]
           Col 2 = [                                                ]
                   [  0.2654607680986639 %i + 0.44678181171841735   ]
                   [                                                ]
                   [               0.5750762708542709               ]
                   [  0.28106497673059216 %i - 0.13352639282451817  ]
                   [                                                ]
                   [  0.28663101328695556 %i - 0.4536971347853274   ]
           Col 3 = [                                                ]
                   [ - 0.29336843237542953 %i - 0.49549724255410565 ]
                   [                                                ]
                   [               0.5325337537576771               ]
                   [ - 0.5737316575503476 %i - 0.39661467994277055 ]
                   [                                               ]
                   [ 0.018265026190214573 %i + 0.35305577043870173 ]
           Col 4 = [                                               ]
                   [ 0.16737009000854253 %i + 0.01476684746229564  ]
                   [                                               ]
                   [              0.6002632636961784               ]


File: maxima.info,  Node: Package lbfgs,  Next: Package lindstedt,  Prev: Package lapack,  Up: Top

56 lbfgs
********

* Menu:

* Introduction to lbfgs::
* Functions and Variables for lbfgs::


File: maxima.info,  Node: Introduction to lbfgs,  Next: Functions and Variables for lbfgs,  Up: Package lbfgs

56.1 Introduction to lbfgs
==========================

‘lbfgs’ is an implementation of the L-BFGS algorithm [1] to solve
unconstrained minimization problems via a limited-memory quasi-Newton
(BFGS) algorithm.  It is called a limited-memory method because a
low-rank approximation of the Hessian matrix inverse is stored instead
of the entire Hessian inverse.  The program was originally written in
Fortran [2] by Jorge Nocedal, incorporating some functions originally
written by Jorge J. Moré and David J. Thuente, and translated into Lisp
automatically via the program ‘f2cl’.  The Maxima package ‘lbfgs’
comprises the translated code plus an interface function which manages
some details.

   References:

   [1] D. Liu and J. Nocedal.  "On the limited memory BFGS method for
large scale optimization".  Mathematical Programming B 45:503–528 (1989)

   [2] <https://www.netlib.org/opt/lbfgs_um.shar>


File: maxima.info,  Node: Functions and Variables for lbfgs,  Prev: Introduction to lbfgs,  Up: Package lbfgs

56.2 Functions and Variables for lbfgs
======================================

 -- Function: lbfgs
          lbfgs (<FOM>, <X>, <X0>, <epsilon>, <iprint>)
          lbfgs ([<FOM>, <grad>] <X>, <X0>, <epsilon>, <iprint>)

     Finds an approximate solution of the unconstrained minimization of
     the figure of merit <FOM> over the list of variables <X>, starting
     from initial estimates <X0>, such that norm(grad(FOM)) <
     epsilon*max(1, norm(X)).

     <grad>, if present, is the gradient of <FOM> with respect to the
     variables <X>.  <grad> may be a list or a function that returns a
     list, with one element for each element of <X>.  If not present,
     the gradient is computed automatically by symbolic differentiation.
     If <FOM> is a function, the gradient <grad> must be supplied by the
     user.

     The algorithm applied is a limited-memory quasi-Newton (BFGS)
     algorithm [1].  It is called a limited-memory method because a
     low-rank approximation of the Hessian matrix inverse is stored
     instead of the entire Hessian inverse.  Each iteration of the
     algorithm is a line search, that is, a search along a ray in the
     variables <X>, with the search direction computed from the
     approximate Hessian inverse.  The FOM is always decreased by a
     successful line search.  Usually (but not always) the norm of the
     gradient of FOM also decreases.

     <iprint> controls progress messages printed by ‘lbfgs’.

     ‘iprint[1]’
          ‘<iprint>[1]’ controls the frequency of progress messages.
          ‘iprint[1] < 0’
               No progress messages.
          ‘iprint[1] = 0’
               Messages at the first and last iterations.
          ‘iprint[1] > 0’
               Print a message every ‘<iprint>[1]’ iterations.
     ‘iprint[2]’
          ‘<iprint>[2]’ controls the verbosity of progress messages.
          ‘iprint[2] = 0’
               Print out iteration count, number of evaluations of
               <FOM>, value of <FOM>, norm of the gradient of <FOM>, and
               step length.
          ‘iprint[2] = 1’
               Same as ‘<iprint>[2] = 0’, plus <X0> and the gradient of
               <FOM> evaluated at <X0>.
          ‘iprint[2] = 2’
               Same as ‘<iprint>[2] = 1’, plus values of <X> at each
               iteration.
          ‘iprint[2] = 3’
               Same as ‘<iprint>[2] = 2’, plus the gradient of <FOM> at
               each iteration.

     The columns printed by ‘lbfgs’ are the following.

     ‘I’
          Number of iterations.  It is incremented for each line search.
     ‘NFN’
          Number of evaluations of the figure of merit.
     ‘FUNC’
          Value of the figure of merit at the end of the most recent
          line search.
     ‘GNORM’
          Norm of the gradient of the figure of merit at the end of the
          most recent line search.
     ‘STEPLENGTH’
          An internal parameter of the search algorithm.

     Additional information concerning details of the algorithm are
     found in the comments of the original Fortran code [2].

     See also ‘lbfgs_nfeval_max’ and ‘lbfgs_ncorrections’.

     References:

     [1] D. Liu and J. Nocedal.  "On the limited memory BFGS method for
     large scale optimization".  Mathematical Programming B 45:503–528
     (1989)

     [2] <https://www.netlib.org/opt/lbfgs_um.shar>

     Examples:

     The same FOM as computed by FGCOMPUTE in the program sdrive.f in
     the LBFGS package from Netlib.  Note that the variables in question
     are subscripted variables.  The FOM has an exact minimum equal to
     zero at u[k] = 1 for k = 1, ..., 8.

          (%i1) load ("lbfgs")$
          (%i2) t1[j] := 1 - u[j];
          (%o2)                     t1  := 1 - u
                                      j         j
          (%i3) t2[j] := 10*(u[j + 1] - u[j]^2);
                                                    2
          (%o3)                t2  := 10 (u      - u )
                                 j         j + 1    j
          (%i4) n : 8;
          (%o4)                           8
          (%i5) FOM : sum (t1[2*j - 1]^2 + t2[2*j - 1]^2, j, 1, n/2);
                           2 2           2              2 2           2
          (%o5) 100 (u  - u )  + (1 - u )  + 100 (u  - u )  + (1 - u )
                      8    7           7           6    5           5
                               2 2           2              2 2           2
                  + 100 (u  - u )  + (1 - u )  + 100 (u  - u )  + (1 - u )
                          4    3           3           2    1           1
          (%i6) lbfgs (FOM, '[u[1],u[2],u[3],u[4],u[5],u[6],u[7],u[8]],
                 [-1.2, 1, -1.2, 1, -1.2, 1, -1.2, 1], 1e-3, [1, 0]);
          *************************************************
            N=    8   NUMBER OF CORRECTIONS=25
                 INITIAL VALUES
           F=  9.680000000000000D+01   GNORM=  4.657353755084533D+02
          *************************************************
           I NFN   FUNC                    GNORM                   STEPLENGTH

           1   3   1.651479526340304D+01   4.324359291335977D+00   7.926153934390631D-04
           2   4   1.650209316638371D+01   3.575788161060007D+00   1.000000000000000D+00
           3   5   1.645461701312851D+01   6.230869903601577D+00   1.000000000000000D+00
           4   6   1.636867301275588D+01   1.177589920974980D+01   1.000000000000000D+00
           5   7   1.612153014409201D+01   2.292797147151288D+01   1.000000000000000D+00
           6   8   1.569118407390628D+01   3.687447158775571D+01   1.000000000000000D+00
           7   9   1.510361958398942D+01   4.501931728123679D+01   1.000000000000000D+00
           8  10   1.391077875774293D+01   4.526061463810630D+01   1.000000000000000D+00
           9  11   1.165625686278198D+01   2.748348965356907D+01   1.000000000000000D+00
          10  12   9.859422687859144D+00   2.111494974231706D+01   1.000000000000000D+00
          11  13   7.815442521732282D+00   6.110762325764183D+00   1.000000000000000D+00
          12  15   7.346380905773044D+00   2.165281166715009D+01   1.285316401779678D-01
          13  16   6.330460634066464D+00   1.401220851761508D+01   1.000000000000000D+00
          14  17   5.238763939854303D+00   1.702473787619218D+01   1.000000000000000D+00
          15  18   3.754016790406625D+00   7.981845727632704D+00   1.000000000000000D+00
          16  20   3.001238402313225D+00   3.925482944745832D+00   2.333129631316462D-01
          17  22   2.794390709722064D+00   8.243329982586480D+00   2.503577283802312D-01
          18  23   2.563783562920545D+00   1.035413426522664D+01   1.000000000000000D+00
          19  24   2.019429976373283D+00   1.065187312340952D+01   1.000000000000000D+00
          20  25   1.428003167668592D+00   2.475962450735100D+00   1.000000000000000D+00
          21  27   1.197874264859232D+00   8.441707983339661D+00   4.303451060697367D-01
          22  28   9.023848942003913D-01   1.113189216665625D+01   1.000000000000000D+00
          23  29   5.508226405855795D-01   2.380830599637816D+00   1.000000000000000D+00
          24  31   3.902893258879521D-01   5.625595817143044D+00   4.834988416747262D-01
          25  32   3.207542206881058D-01   1.149444645298493D+01   1.000000000000000D+00
          26  33   1.874468266118200D-01   3.632482152347445D+00   1.000000000000000D+00
          27  34   9.575763380282112D-02   4.816497449000391D+00   1.000000000000000D+00
          28  35   4.085145106760390D-02   2.087009347116811D+00   1.000000000000000D+00
          29  36   1.931106005512628D-02   3.886818624052740D+00   1.000000000000000D+00
          30  37   6.894000636920714D-03   3.198505769992936D+00   1.000000000000000D+00
          31  38   1.443296008850287D-03   1.590265460381961D+00   1.000000000000000D+00
          32  39   1.571766574930155D-04   3.098257002223532D-01   1.000000000000000D+00
          33  40   1.288011779655132D-05   1.207784334505595D-02   1.000000000000000D+00
          34  41   1.806140190993455D-06   4.587890258846915D-02   1.000000000000000D+00
          35  42   1.769004612050548D-07   1.790537363138099D-02   1.000000000000000D+00
          36  43   3.312164244118216D-10   6.782068546986653D-04   1.000000000000000D+00

           THE MINIMIZATION TERMINATED WITHOUT DETECTING ERRORS.
           IFLAG = 0
          (%o6) [u  = 1.000005339816132, u  = 1.000009942840108,
                  1                       2
          u  = 1.000005339816132, u  = 1.000009942840108,
           3                       4
          u  = 1.000005339816132, u  = 1.000009942840108,
           5                       6
          u  = 1.000005339816132, u  = 1.000009942840108]
           7                       8

     A regression problem.  The FOM is the mean square difference
     between the predicted value F(X[i]) and the observed value Y[i].
     The function F is a bounded monotone function (a so-called
     "sigmoidal" function).  In this example, ‘lbfgs’ computes
     approximate values for the parameters of F and ‘plot2d’ displays a
     comparison of F with the observed data.

          (%i1) load ("lbfgs")$
          (%i2) FOM : '((1/length(X))*sum((F(X[i]) - Y[i])^2, i, 1,
                                                          length(X)));
                                         2
                         sum((F(X ) - Y ) , i, 1, length(X))
                                 i     i
          (%o2)          -----------------------------------
                                      length(X)
          (%i3) X : [1, 2, 3, 4, 5];
          (%o3)                    [1, 2, 3, 4, 5]
          (%i4) Y : [0, 0.5, 1, 1.25, 1.5];
          (%o4)                [0, 0.5, 1, 1.25, 1.5]
          (%i5) F(x) := A/(1 + exp(-B*(x - C)));
                                             A
          (%o5)            F(x) := ----------------------
                                   1 + exp((- B) (x - C))
          (%i6) ''FOM;
                          A               2            A                2
          (%o6) ((----------------- - 1.5)  + (----------------- - 1.25)
                    - B (5 - C)                  - B (4 - C)
                  %e            + 1            %e            + 1
                      A             2            A               2
           + (----------------- - 1)  + (----------------- - 0.5)
                - B (3 - C)                - B (2 - C)
              %e            + 1          %e            + 1
                       2
                      A
           + --------------------)/5
                - B (1 - C)     2
             (%e            + 1)
          (%i7) estimates : lbfgs (FOM, '[A, B, C], [1, 1, 1], 1e-4, [1, 0]);
          *************************************************
            N=    3   NUMBER OF CORRECTIONS=25
                 INITIAL VALUES
           F=  1.348738534246918D-01   GNORM=  2.000215531936760D-01
          *************************************************

          I  NFN  FUNC                    GNORM                   STEPLENGTH
          1    3  1.177820636622582D-01   9.893138394953992D-02   8.554435968992371D-01
          2    6  2.302653892214013D-02   1.180098521565904D-01   2.100000000000000D+01
          3    8  1.496348495303004D-02   9.611201567691624D-02   5.257340567840710D-01
          4    9  7.900460841091138D-03   1.325041647391314D-02   1.000000000000000D+00
          5   10  7.314495451266914D-03   1.510670810312226D-02   1.000000000000000D+00
          6   11  6.750147275936668D-03   1.914964958023037D-02   1.000000000000000D+00
          7   12  5.850716021108202D-03   1.028089194579382D-02   1.000000000000000D+00
          8   13  5.778664230657800D-03   3.676866074532179D-04   1.000000000000000D+00
          9   14  5.777818823650780D-03   3.010740179797108D-04   1.000000000000000D+00

           THE MINIMIZATION TERMINATED WITHOUT DETECTING ERRORS.
           IFLAG = 0
          (%o7) [A = 1.461933911464101, B = 1.601593973254801,
                                                     C = 2.528933072164855]
          (%i8) plot2d ([F(x), [discrete, X, Y]], [x, -1, 6]), ''estimates;
          (%o8)

     Gradient of FOM is specified (instead of computing it
     automatically).  Both the FOM and its gradient are passed as
     functions to ‘lbfgs’.

          (%i1) load ("lbfgs")$
          (%i2) F(a, b, c) := (a - 5)^2 + (b - 3)^4 + (c - 2)^6$
          (%i3) define(F_grad(a, b, c),
                       map (lambda ([x], diff (F(a, b, c), x)), [a, b, c]))$
          (%i4) estimates : lbfgs ([F, F_grad],
                             [a, b, c], [0, 0, 0], 1e-4, [1, 0]);
          *************************************************
            N=    3   NUMBER OF CORRECTIONS=25
                 INITIAL VALUES
           F=  1.700000000000000D+02   GNORM=  2.205175729958953D+02
          *************************************************

             I  NFN     FUNC                    GNORM                   STEPLENGTH

             1    2     6.632967565917637D+01   6.498411132518770D+01   4.534785987412505D-03
             2    3     4.368890936228036D+01   3.784147651974131D+01   1.000000000000000D+00
             3    4     2.685298972775191D+01   1.640262125898520D+01   1.000000000000000D+00
             4    5     1.909064767659852D+01   9.733664001790506D+00   1.000000000000000D+00
             5    6     1.006493272061515D+01   6.344808151880209D+00   1.000000000000000D+00
             6    7     1.215263596054292D+00   2.204727876126877D+00   1.000000000000000D+00
             7    8     1.080252896385329D-02   1.431637116951845D-01   1.000000000000000D+00
             8    9     8.407195124830860D-03   1.126344579730008D-01   1.000000000000000D+00
             9   10     5.022091686198525D-03   7.750731829225275D-02   1.000000000000000D+00
            10   11     2.277152808939775D-03   5.032810859286796D-02   1.000000000000000D+00
            11   12     6.489384688303218D-04   1.932007150271009D-02   1.000000000000000D+00
            12   13     2.075791943844547D-04   6.964319310814365D-03   1.000000000000000D+00
            13   14     7.349472666162258D-05   4.017449067849554D-03   1.000000000000000D+00
            14   15     2.293617477985238D-05   1.334590390856715D-03   1.000000000000000D+00
            15   16     7.683645404048675D-06   6.011057038099202D-04   1.000000000000000D+00

           THE MINIMIZATION TERMINATED WITHOUT DETECTING ERRORS.
           IFLAG = 0
          (%o4) [a = 5.000086823042934, b = 3.052395429705181,
                                                     c = 1.927980629919583]

 -- Variable: lbfgs_nfeval_max
     Default value: 100

     ‘lbfgs_nfeval_max’ is the maximum number of evaluations of the
     figure of merit (FOM) in ‘lbfgs’.  When ‘lbfgs_nfeval_max’ is
     reached, ‘lbfgs’ returns the result of the last successful line
     search.

 -- Variable: lbfgs_ncorrections
     Default value: 25

     ‘lbfgs_ncorrections’ is the number of corrections applied to the
     approximate inverse Hessian matrix which is maintained by ‘lbfgs’.


File: maxima.info,  Node: Package lindstedt,  Next: Package linearalgebra,  Prev: Package lbfgs,  Up: Top

57 lindstedt
************

* Menu:

* Functions and Variables for lindstedt::


File: maxima.info,  Node: Functions and Variables for lindstedt,  Prev: Package lindstedt,  Up: Package lindstedt

57.1 Functions and Variables for lindstedt
==========================================

 -- Function: Lindstedt (<eq>,<pvar>,<torder>,<ic>)
     This is a first pass at a Lindstedt code.  It can solve problems
     with initial conditions entered, which can be arbitrary constants,
     (just not <%k1> and <%k2>) where the initial conditions on the
     perturbation equations are z[i]=0, z'[i]=0 for i>0.  <ic> is the
     list of initial conditions.

     Problems occur when initial conditions are not given, as the
     constants in the perturbation equations are the same as the zero
     order equation solution.  Also, problems occur when the initial
     conditions for the perturbation equations are not z[i]=0, z'[i]=0
     for i>0, such as the Van der Pol equation.

     Example:
          (%i1) load("makeOrders")$

          (%i2) load("lindstedt")$

          (%i3) Lindstedt('diff(x,t,2)+x-(e*x^3)/6,e,2,[1,0]);
                    2
                   e  (cos(5 T) - 24 cos(3 T) + 23 cos(T))
          (%o3) [[[---------------------------------------
                                    36864
             e (cos(3 T) - cos(T))
           - --------------------- + cos(T)],
                      192
                    2
                 7 e    e
          T = (- ---- - -- + 1) t]]
                 3072   16

     To use this function write first ‘load("makeOrders")’ and
     ‘load("lindstedt")’.


File: maxima.info,  Node: Package linearalgebra,  Next: Package lsquares,  Prev: Package lindstedt,  Up: Top

58 linearalgebra
****************

* Menu:

* Introduction to linearalgebra::
* Functions and Variables for linearalgebra::


File: maxima.info,  Node: Introduction to linearalgebra,  Next: Functions and Variables for linearalgebra,  Prev: Package linearalgebra,  Up: Package linearalgebra

58.1 Introduction to linearalgebra
==================================

‘linearalgebra’ is a collection of functions for linear algebra.

   Example:

     (%i1) M : matrix ([1, 2], [1, 2]);
                                 [ 1  2 ]
     (%o1)                       [      ]
                                 [ 1  2 ]
     (%i2) nullspace (M);
                                    [  1  ]
                                    [     ]
     (%o2)                     span([   1 ])
                                    [ - - ]
                                    [   2 ]
     (%i3) columnspace (M);
                                     [ 1 ]
     (%o3)                      span([   ])
                                     [ 1 ]
     (%i4) ptriangularize (M - z*ident(2), z);
                              [ 1   2 - z   ]
     (%o4)                    [             ]
                              [           2 ]
                              [ 0  3 z - z  ]
     (%i5) M : matrix ([1, 2, 3], [4, 5, 6], [7, 8, 9]) - z*ident(3);
                          [ 1 - z    2      3   ]
                          [                     ]
     (%o5)                [   4    5 - z    6   ]
                          [                     ]
                          [   7      8    9 - z ]
     (%i6) MM : ptriangularize (M, z);
                   [ 4  5 - z            6            ]
                   [                                  ]
                   [                2                 ]
                   [     66        z    102 z   132   ]
                   [ 0   --      - -- + ----- + ---   ]
     (%o6)         [     49        7     49     49    ]
                   [                                  ]
                   [               3        2         ]
                   [           49 z    245 z    147 z ]
                   [ 0    0    ----- - ------ - ----- ]
                   [            264      88      44   ]
     (%i7) algebraic : true;
     (%o7)                         true
     (%i8) tellrat (MM [3, 3]);
                              3       2
     (%o8)                  [z  - 15 z  - 18 z]
     (%i9) MM : ratsimp (MM);
                    [ 4  5 - z           6           ]
                    [                                ]
                    [                2               ]
     (%o9)          [     66      7 z  - 102 z - 132 ]
                    [ 0   --    - ------------------ ]
                    [     49              49         ]
                    [                                ]
                    [ 0    0             0           ]
     (%i10) nullspace (MM);
                             [        1         ]
                             [                  ]
                             [   2              ]
                             [  z  - 14 z - 16  ]
                             [  --------------  ]
     (%o10)             span([        8         ])
                             [                  ]
                             [    2             ]
                             [   z  - 18 z - 12 ]
                             [ - -------------- ]
                             [         12       ]
     (%i11) M : matrix ([1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12],
                        [13, 14, 15, 16]);
                            [ 1   2   3   4  ]
                            [                ]
                            [ 5   6   7   8  ]
     (%o11)                 [                ]
                            [ 9   10  11  12 ]
                            [                ]
                            [ 13  14  15  16 ]
     (%i12) columnspace (M);
                                [ 1  ]  [ 2  ]
                                [    ]  [    ]
                                [ 5  ]  [ 6  ]
     (%o12)                span([    ], [    ])
                                [ 9  ]  [ 10 ]
                                [    ]  [    ]
                                [ 13 ]  [ 14 ]
     (%i13) apply ('orthogonal_complement, args (nullspace (transpose (M))));
                                [ 0 ]  [  1  ]
                                [   ]  [     ]
                                [ 1 ]  [  0  ]
     (%o13)                span([   ], [     ])
                                [ 2 ]  [ - 1 ]
                                [   ]  [     ]
                                [ 3 ]  [ - 2 ]


File: maxima.info,  Node: Functions and Variables for linearalgebra,  Prev: Introduction to linearalgebra,  Up: Package linearalgebra

58.2 Functions and Variables for linearalgebra
==============================================

 -- Function: addmatrices (<f>, <M_1>, ..., <M_n>)

     Using the function <f> as the addition function, return the sum of
     the matrices <M_1>, ..., <M_n>.  The function <f> must accept any
     number of arguments (a Maxima nary function).

     Examples:

          (%i1) m1 : matrix([1,2],[3,4])$
          (%i2) m2 : matrix([7,8],[9,10])$
          (%i3) addmatrices('max,m1,m2);
          (%o3) matrix([7,8],[9,10])
          (%i4) addmatrices('max,m1,m2,5*m1);
          (%o4) matrix([7,10],[15,20])

 -- Function: blockmatrixp (<M>)

     Return true if and only if <M> is a matrix and every entry of <M>
     is a matrix.

 -- Function: columnop (<M>, <i>, <j>, <theta>)

     If <M> is a matrix, return the matrix that results from doing the
     column operation ‘C_i <- C_i - <theta> * C_j’.  If <M> doesn’t have
     a row <i> or <j>, signal an error.

 -- Function: columnswap (<M>, <i>, <j>)

     If <M> is a matrix, swap columns <i> and <j>.  If <M> doesn’t have
     a column <i> or <j>, signal an error.

 -- Function: columnspace (<M>)

     If <M> is a matrix, return ‘span (v_1, ..., v_n)’, where the set
     ‘{v_1, ..., v_n}’ is a basis for the column space of <M>.  The span
     of the empty set is ‘{0}’.  Thus, when the column space has only
     one member, return ‘span ()’.

 -- Function: cholesky
          cholesky (<M>)
          cholesky (<M>, <field>)

     Return the Cholesky factorization of the matrix selfadjoint (or
     hermitian) matrix <M>.  The second argument defaults to
     ’generalring.’ For a description of the possible values for
     <field>, see ‘lu_factor’.

 -- Function: ctranspose (<M>)

     Return the complex conjugate transpose of the matrix <M>.  The
     function ‘ctranspose’ uses ‘matrix_element_transpose’ to transpose
     each matrix element.

 -- Function: diag_matrix (<d_1>, <d_2>, ..., <d_n>)

     Return a diagonal matrix with diagonal entries <d_1>, <d_2>, ...,
     <d_n>.  When the diagonal entries are matrices, the zero entries of
     the returned matrix are zero matrices of the appropriate size; for
     example:

          (%i1) diag_matrix(diag_matrix(1,2),diag_matrix(3,4));

                                      [ [ 1  0 ]  [ 0  0 ] ]
                                      [ [      ]  [      ] ]
                                      [ [ 0  2 ]  [ 0  0 ] ]
          (%o1)                       [                    ]
                                      [ [ 0  0 ]  [ 3  0 ] ]
                                      [ [      ]  [      ] ]
                                      [ [ 0  0 ]  [ 0  4 ] ]
          (%i2) diag_matrix(p,q);

                                             [ p  0 ]
          (%o2)                              [      ]
                                             [ 0  q ]

 -- Function: dotproduct (<u>, <v>)

     Return the dotproduct of vectors <u> and <v>.  This is the same as
     ‘conjugate (transpose (<u>)) . <v>’.  The arguments <u> and <v>
     must be column vectors.

 -- Function: eigens_by_jacobi
          eigens_by_jacobi (<A>)
          eigens_by_jacobi (<A>, <field_type>)

     Computes the eigenvalues and eigenvectors of <A> by the method of
     Jacobi rotations.  <A> must be a symmetric matrix (but it need not
     be positive definite nor positive semidefinite).  <field_type>
     indicates the computational field, either ‘floatfield’ or
     ‘bigfloatfield’.  If <field_type> is not specified, it defaults to
     ‘floatfield’.

     The elements of <A> must be numbers or expressions which evaluate
     to numbers via ‘float’ or ‘bfloat’ (depending on <field_type>).

     Examples:

          (%i1) S: matrix([1/sqrt(2), 1/sqrt(2)],[-1/sqrt(2), 1/sqrt(2)]);
                               [     1         1    ]
                               [  -------   ------- ]
                               [  sqrt(2)   sqrt(2) ]
          (%o1)                [                    ]
                               [      1        1    ]
                               [ - -------  ------- ]
                               [   sqrt(2)  sqrt(2) ]
          (%i2) L : matrix ([sqrt(3), 0], [0, sqrt(5)]);
                                [ sqrt(3)     0    ]
          (%o2)                 [                  ]
                                [    0     sqrt(5) ]
          (%i3) M : S . L . transpose (S);
                      [ sqrt(5)   sqrt(3)  sqrt(5)   sqrt(3) ]
                      [ ------- + -------  ------- - ------- ]
                      [    2         2        2         2    ]
          (%o3)       [                                      ]
                      [ sqrt(5)   sqrt(3)  sqrt(5)   sqrt(3) ]
                      [ ------- - -------  ------- + ------- ]
                      [    2         2        2         2    ]
          (%i4) eigens_by_jacobi (M);
          The largest percent change was 0.1454972243679
          The largest percent change was 0.0
          number of sweeps: 2
          number of rotations: 1
          (%o4) [[1.732050807568877, 2.23606797749979],
                                  [  0.70710678118655   0.70710678118655 ]
                                  [                                      ]]
                                  [ - 0.70710678118655  0.70710678118655 ]
          (%i5) float ([[sqrt(3), sqrt(5)], S]);
          (%o5) [[1.732050807568877, 2.23606797749979],
                                  [  0.70710678118655   0.70710678118655 ]
                                  [                                      ]]
                                  [ - 0.70710678118655  0.70710678118655 ]
          (%i6) eigens_by_jacobi (M, bigfloatfield);
          The largest percent change was 1.454972243679028b-1
          The largest percent change was 0.0b0
          number of sweeps: 2
          number of rotations: 1
          (%o6) [[1.732050807568877b0, 2.23606797749979b0],
                          [  7.071067811865475b-1   7.071067811865475b-1 ]
                          [                                              ]]
                          [ - 7.071067811865475b-1  7.071067811865475b-1 ]

 -- Function: get_lu_factors (<x>)

     When ‘<x> = lu_factor (<A>)’, then ‘get_lu_factors’ returns a list
     of the form ‘[P, L, U]’, where <P> is a permutation matrix, <L> is
     lower triangular with ones on the diagonal, and <U> is upper
     triangular, and ‘<A> = <P> <L> <U>’.

 -- Function: hankel
          hankel (<col>)
          hankel (<col>, <row>)

     Return a Hankel matrix <H>.  The first column of <H> is <col>;
     except for the first entry, the last row of <H> is <row>.  The
     default for <row> is the zero vector with the same length as <col>.

 -- Function: hessian (<f>, <x>)

     Returns the Hessian matrix of <f> with respect to the list of
     variables <x>.  The ‘(i, j)’-th element of the Hessian matrix is
     ‘diff(<f>, <x>[i], 1, <x>[j], 1)’.

     Examples:

          (%i1) hessian (x * sin (y), [x, y]);
                               [   0       cos(y)   ]
          (%o1)                [                    ]
                               [ cos(y)  - x sin(y) ]
          (%i2) depends (F, [a, b]);
          (%o2)                       [F(a, b)]
          (%i3) hessian (F, [a, b]);
                                  [   2      2   ]
                                  [  d F    d F  ]
                                  [  ---   ----- ]
                                  [    2   da db ]
                                  [  da          ]
          (%o3)                   [              ]
                                  [   2      2   ]
                                  [  d F    d F  ]
                                  [ -----   ---  ]
                                  [ da db     2  ]
                                  [         db   ]

 -- Function: hilbert_matrix (<n>)

     Return the <n> by <n> Hilbert matrix.  When <n> isn’t a positive
     integer, signal an error.

 -- Function: identfor
          identfor (<M>)
          identfor (<M>, <fld>)

     Return an identity matrix that has the same shape as the matrix
     <M>.  The diagonal entries of the identity matrix are the
     multiplicative identity of the field <fld>; the default for <fld>
     is <generalring>.

     The first argument <M> should be a square matrix or a non-matrix.
     When <M> is a matrix, each entry of <M> can be a square matrix –
     thus <M> can be a blocked Maxima matrix.  The matrix can be blocked
     to any (finite) depth.

     See also ‘zerofor’

 -- Function: invert_by_lu (<M>, <(rng generalring)>)

     Invert a matrix <M> by using the LU factorization.  The LU
     factorization is done using the ring <rng>.

 -- Function: jacobian (<f>, <x>)

     Returns the Jacobian matrix of the list of functions <f> with
     respect to the list of variables <x>.  The ‘(i, j)’-th element of
     the Jacobian matrix is ‘diff(<f>[i], <x>[j])’.

     Examples:

          (%i1) jacobian ([sin (u - v), sin (u * v)], [u, v]);
                            [ cos(v - u)  - cos(v - u) ]
          (%o1)             [                          ]
                            [ v cos(u v)   u cos(u v)  ]
          (%i2) depends ([F, G], [y, z]);
          (%o2)                  [F(y, z), G(y, z)]
          (%i3) jacobian ([F, G], [y, z]);
                                     [ dF  dF ]
                                     [ --  -- ]
                                     [ dy  dz ]
          (%o3)                      [        ]
                                     [ dG  dG ]
                                     [ --  -- ]
                                     [ dy  dz ]

 -- Function: kronecker_product (<A>, <B>)

     Return the Kronecker product of the matrices <A> and <B>.

 -- Function: locate_matrix_entry (<M>, <r_1>, <c_1>, <r_2>, <c_2>, <f>,
          <rel>)

     The first argument must be a matrix; the arguments <r_1> through
     <c_2> determine a sub-matrix of <M> that consists of rows <r_1>
     through <r_2> and columns <c_1> through <c_2>.

     Find an entry in the sub-matrix <M> that satisfies some property.
     Three cases:

     (1) ‘<rel> = 'bool’ and <f> a predicate:

     Scan the sub-matrix from left to right then top to bottom, and
     return the index of the first entry that satisfies the predicate
     <f>.  If no matrix entry satisfies <f>, return ‘false’.

     (2) ‘<rel> = 'max’ and <f> real-valued:

     Scan the sub-matrix looking for an entry that maximizes <f>.
     Return the index of a maximizing entry.

     (3) ‘<rel> = 'min’ and <f> real-valued:

     Scan the sub-matrix looking for an entry that minimizes <f>.
     Return the index of a minimizing entry.

 -- Function: lu_backsub (<M>, <b>)

     When ‘<M> = lu_factor (<A>, <field>)’, then ‘lu_backsub (<M>, <b>)’
     solves the linear system ‘<A> <x> = <b>’.

     The <n> by <m> matrix ‘<b>’, with <n> the number of rows of the
     matrix ‘<A>’, contains one right hand side per column.  If there is
     only one right hand side then ‘<b>’ must be a <n> by 1 matrix.

     Each column of the matrix ‘<x>=lu_backsub (<M>, <b>)’ is the
     solution corresponding to the respective column of ‘<b>’.

     Examples:

          (%i1) A : matrix ([1 - z, 3], [3, 8 - z]);
                                         [ 1 - z    3   ]
          (%o1)                          [              ]
                                         [   3    8 - z ]
          (%i2) M : lu_factor (A,generalring);
                         [ 1 - z          3         ]
                         [                          ]
          (%o2)         [[   3              9       ], [1, 2], generalring]
                         [ -----  (- z) - ----- + 8 ]
                         [ 1 - z          1 - z     ]
          (%i3) b : matrix([a],[c]);
                                               [ a ]
          (%o3)                                [   ]
                                               [ c ]
          (%i4) x : lu_backsub(M,b);
                                     [               3 a     ]
                                     [       3 (c - -----)   ]
                                     [              1 - z    ]
                                     [ a - ----------------- ]
                                     [               9       ]
                                     [     (- z) - ----- + 8 ]
                                     [             1 - z     ]
                                     [ --------------------- ]
          (%o4)                      [         1 - z         ]
                                     [                       ]
                                     [            3 a        ]
                                     [       c - -----       ]
                                     [           1 - z       ]
                                     [   -----------------   ]
                                     [             9         ]
                                     [   (- z) - ----- + 8   ]
                                     [           1 - z       ]
          (%i5) ratsimp(A . x - b);
                                               [ 0 ]
          (%o5)                                [   ]
                                               [ 0 ]
          (%i6) B : matrix([a,d],[c,f]);
                                             [ a  d ]
          (%o6)                              [      ]
                                             [ c  f ]
          (%i7) x : lu_backsub(M,B);
                         [               3 a                    3 d     ]
                         [       3 (c - -----)          3 (f - -----)   ]
                         [              1 - z                  1 - z    ]
                         [ a - -----------------  d - ----------------- ]
                         [               9                      9       ]
                         [     (- z) - ----- + 8      (- z) - ----- + 8 ]
                         [             1 - z                  1 - z     ]
                         [ ---------------------  --------------------- ]
          (%o7)          [         1 - z                  1 - z         ]
                         [                                              ]
                         [            3 a                    3 d        ]
                         [       c - -----              f - -----       ]
                         [           1 - z                  1 - z       ]
                         [   -----------------      -----------------   ]
                         [             9                      9         ]
                         [   (- z) - ----- + 8      (- z) - ----- + 8   ]
                         [           1 - z                  1 - z       ]
          (%i8) ratsimp(A . x - B);
                                             [ 0  0 ]
          (%o8)                              [      ]
                                             [ 0  0 ]

 -- Function: lu_factor (<M>, <field>)

     Return a list of the form ‘[<LU>, <perm>, <fld>]’, or ‘[<LU>,
     <perm>, <fld>, <lower-cnd> <upper-cnd>]’, where

     (1) The matrix <LU> contains the factorization of <M> in a packed
     form.  Packed form means three things: First, the rows of <LU> are
     permuted according to the list <perm>.  If, for example, <perm> is
     the list ‘[3,2,1]’, the actual first row of the <LU> factorization
     is the third row of the matrix <LU>.  Second, the lower triangular
     factor of m is the lower triangular part of <LU> with the diagonal
     entries replaced by all ones.  Third, the upper triangular factor
     of <M> is the upper triangular part of <LU>.

     (2) When the field is either ‘floatfield’ or ‘complexfield’, the
     numbers <lower-cnd> and <upper-cnd> are lower and upper bounds for
     the infinity norm condition number of <M>.  For all fields, the
     condition number might not be estimated; for such fields,
     ‘lu_factor’ returns a two item list.  Both the lower and upper
     bounds can differ from their true values by arbitrarily large
     factors.  (See also ‘mat_cond’.)

     The argument <M> must be a square matrix.

     The optional argument <fld> must be a symbol that determines a ring
     or field.  The pre-defined fields and rings are:

     (a) ‘generalring’ – the ring of Maxima expressions,

     (b) ‘floatfield’ – the field of floating point numbers of the type
     double,

     (c) ‘complexfield’ – the field of complex floating point numbers of
     the type double,

     (d) ‘crering’ – the ring of Maxima CRE expressions,

     (e) ‘rationalfield’ – the field of rational numbers,

     (f) ‘runningerror’ – track the all floating point rounding errors,

     (g) ‘noncommutingring’ – the ring of Maxima expressions where
     multiplication is the non-commutative dot operator.

     When the field is ‘floatfield’, ‘complexfield’, or ‘runningerror’,
     the algorithm uses partial pivoting; for all other fields, rows are
     switched only when needed to avoid a zero pivot.

     Floating point addition arithmetic isn’t associative, so the
     meaning of ’field’ differs from the mathematical definition.

     A member of the field ‘runningerror’ is a two member Maxima list of
     the form ‘[x,n]’,where <x> is a floating point number and ‘n’ is an
     integer.  The relative difference between the ’true’ value of ‘x’
     and ‘x’ is approximately bounded by the machine epsilon times ‘n’.
     The running error bound drops some terms that of the order the
     square of the machine epsilon.

     There is no user-interface for defining a new field.  A user that
     is familiar with Common Lisp should be able to define a new field.
     To do this, a user must define functions for the arithmetic
     operations and functions for converting from the field
     representation to Maxima and back.  Additionally, for ordered
     fields (where partial pivoting will be used), a user must define
     functions for the magnitude and for comparing field members.  After
     that all that remains is to define a Common Lisp structure ‘mring’.
     The file ‘mring’ has many examples.

     To compute the factorization, the first task is to convert each
     matrix entry to a member of the indicated field.  When conversion
     isn’t possible, the factorization halts with an error message.
     Members of the field needn’t be Maxima expressions.  Members of the
     ‘complexfield’, for example, are Common Lisp complex numbers.  Thus
     after computing the factorization, the matrix entries must be
     converted to Maxima expressions.

     See also ‘get_lu_factors’.

     Examples:

          (%i1) w[i,j] := random (1.0) + %i * random (1.0);
          (%o1)          w     := random(1.) + %i random(1.)
                          i, j
          (%i2) showtime : true$
          Evaluation took 0.00 seconds (0.00 elapsed)
          (%i3) M : genmatrix (w, 100, 100)$
          Evaluation took 7.40 seconds (8.23 elapsed)
          (%i4) lu_factor (M, complexfield)$
          Evaluation took 28.71 seconds (35.00 elapsed)
          (%i5) lu_factor (M, generalring)$
          Evaluation took 109.24 seconds (152.10 elapsed)
          (%i6) showtime : false$

          (%i7) M : matrix ([1 - z, 3], [3, 8 - z]);
                                  [ 1 - z    3   ]
          (%o7)                   [              ]
                                  [   3    8 - z ]
          (%i8) lu_factor (M, generalring);
                    [ 1 - z         3        ]
                    [                        ]
          (%o8)    [[   3            9       ], [1, 2], generalring]
                    [ -----  - z - ----- + 8 ]
                    [ 1 - z        1 - z     ]
          (%i9) get_lu_factors (%);
                            [   1    0 ]  [ 1 - z         3        ]
                  [ 1  0 ]  [          ]  [                        ]
          (%o9)  [[      ], [   3      ], [                9       ]]
                  [ 0  1 ]  [ -----  1 ]  [   0    - z - ----- + 8 ]
                            [ 1 - z    ]  [              1 - z     ]
          (%i10) %[1] . %[2] . %[3];
                                  [ 1 - z    3   ]
          (%o10)                  [              ]
                                  [   3    8 - z ]

 -- Function: mat_cond
          mat_cond (<M>, 1)
          mat_cond (<M>, inf)

     Return the <p>-norm matrix condition number of the matrix <m>.  The
     allowed values for <p> are 1 and <inf>.  This function uses the LU
     factorization to invert the matrix <m>.  Thus the running time for
     ‘mat_cond’ is proportional to the cube of the matrix size;
     ‘lu_factor’ determines lower and upper bounds for the infinity norm
     condition number in time proportional to the square of the matrix
     size.

 -- Function: mat_norm
          mat_norm (<M>, 1)
          mat_norm (<M>, inf)
          mat_norm (<M>, frobenius)

     Return the matrix <p>-norm of the matrix <M>.  The allowed values
     for <p> are 1, ‘inf’, and ‘frobenius’ (the Frobenius matrix norm).
     The matrix <M> should be an unblocked matrix.

 -- Function: matrixp
          matrixp (<e>, <p>)
          matrixp (<e>)

     Given an optional argument <p>, return ‘true’ if <e> is a matrix
     and <p> evaluates to ‘true’ for every matrix element.  When
     ‘matrixp’ is not given an optional argument, return ‘true’ if ‘e’
     is a matrix.  In all other cases, return ‘false’.

     See also ‘blockmatrixp’

 -- Function: matrix_size (<M>)

     Return a two member list that gives the number of rows and columns,
     respectively of the matrix <M>.

 -- Function: mat_fullunblocker (<M>)

     If <M> is a block matrix, unblock the matrix to all levels.  If <M>
     is a matrix, return <M>; otherwise, signal an error.

 -- Function: mat_trace (<M>)

     Return the trace of the matrix <M>.  If <M> isn’t a matrix, return
     a noun form.  When <M> is a block matrix, ‘mat_trace(M)’ returns
     the same value as does ‘mat_trace(mat_unblocker(m))’.

 -- Function: mat_unblocker (<M>)

     If <M> is a block matrix, unblock <M> one level.  If <M> is a
     matrix, ‘mat_unblocker (M)’ returns <M>; otherwise, signal an
     error.

     Thus if each entry of <M> is matrix, ‘mat_unblocker (M)’ returns an
     unblocked matrix, but if each entry of <M> is a block matrix,
     ‘mat_unblocker (M)’ returns a block matrix with one less level of
     blocking.

     If you use block matrices, most likely you’ll want to set
     ‘matrix_element_mult’ to ‘"."’ and ‘matrix_element_transpose’ to
     ‘'transpose’.  See also ‘mat_fullunblocker’.

     Example:

          (%i1) A : matrix ([1, 2], [3, 4]);
                                      [ 1  2 ]
          (%o1)                       [      ]
                                      [ 3  4 ]
          (%i2) B : matrix ([7, 8], [9, 10]);
                                      [ 7  8  ]
          (%o2)                       [       ]
                                      [ 9  10 ]
          (%i3) matrix ([A, B]);
                               [ [ 1  2 ]  [ 7  8  ] ]
          (%o3)                [ [      ]  [       ] ]
                               [ [ 3  4 ]  [ 9  10 ] ]
          (%i4) mat_unblocker (%);
                                   [ 1  2  7  8  ]
          (%o4)                    [             ]
                                   [ 3  4  9  10 ]

 -- Function: nullspace (<M>)

     If <M> is a matrix, return ‘span (v_1, ..., v_n)’, where the set
     ‘{v_1, ..., v_n}’ is a basis for the nullspace of <M>.  The span of
     the empty set is ‘{0}’.  Thus, when the nullspace has only one
     member, return ‘span ()’.

 -- Function: nullity (<M>)

     If <M> is a matrix, return the dimension of the nullspace of <M>.

 -- Function: orthogonal_complement (<v_1>, ..., <v_n>)

     Return ‘span (u_1, ..., u_m)’, where the set ‘{u_1, ..., u_m}’ is a
     basis for the orthogonal complement of the set ‘(v_1, ..., v_n)’.

     Each vector <v_1> through <v_n> must be a column vector.

 -- Function: polytocompanion (<p>, <x>)

     If <p> is a polynomial in <x>, return the companion matrix of <p>.
     For a monic polynomial <p> of degree <n>, we have ‘<p> = (-1)^<n>
     charpoly (polytocompanion (<p>, <x>))’.

     When <p> isn’t a polynomial in <x>, signal an error.

 -- Function: ptriangularize (<M>, <v>)

     If <M> is a matrix with each entry a polynomial in <v>, return a
     matrix <M2> such that

     (1) <M2> is upper triangular,

     (2) ‘<M2> = <E_n> ... <E_1> <M>’, where <E_1> through <E_n> are
     elementary matrices whose entries are polynomials in <v>,

     (3) ‘|det (<M>)| = |det (<M2>)|’,

     Note: This function doesn’t check that every entry is a polynomial
     in <v>.

 -- Function: rowop (<M>, <i>, <j>, <theta>)

     If <M> is a matrix, return the matrix that results from doing the
     row operation ‘R_i <- R_i - theta * R_j’.  If <M> doesn’t have a
     row <i> or <j>, signal an error.

 -- Function: linalg_rank (<M>)

     Return the rank of the matrix <M>.  This function is equivalent to
     function ‘rank’, but it uses a different algorithm: it finds the
     ‘columnspace’ of the matrix and counts its elements, since the rank
     of a matrix is the dimension of its column space.

          (%i1) linalg_rank(matrix([1,2],[2,4]));
          (%o1)                           1
          (%i2) linalg_rank(matrix([1,b],[c,d]));
          (%o2)                           2

 -- Function: rowswap (<M>, <i>, <j>)

     If <M> is a matrix, swap rows <i> and <j>.  If <M> doesn’t have a
     row <i> or <j>, signal an error.

 -- Function: toeplitz
          toeplitz (<col>)
          toeplitz (<col>, <row>)

     Return a Toeplitz matrix <T>.  The first first column of <T> is
     <col>; except for the first entry, the first row of <T> is <row>.
     The default for <row> is complex conjugate of <col>.  Example:

          (%i1)  toeplitz([1,2,3],[x,y,z]);
                                            [ 1  y  z ]
                                            [         ]
          (%o1)                             [ 2  1  y ]
                                            [         ]
                                            [ 3  2  1 ]
          (%i2)  toeplitz([1,1+%i]);

                                        [   1     1 - %I ]
          (%o2)                         [                ]
                                        [ %I + 1    1    ]

 -- Function: vandermonde_matrix ([<x_1>, ..., <x_n>])

     Return a <n> by <n> matrix whose <i>-th row is ‘[1, <x_i>, <x_i>^2,
     ... <x_i>^(<n>-1)]’.

 -- Function: zerofor
          zerofor (<M>)
          zerofor (<M>, <fld>)

     Return a zero matrix that has the same shape as the matrix <M>.
     Every entry of the zero matrix is the additive identity of the
     field <fld>; the default for <fld> is <generalring>.

     The first argument <M> should be a square matrix or a non-matrix.
     When <M> is a matrix, each entry of <M> can be a square matrix –
     thus <M> can be a blocked Maxima matrix.  The matrix can be blocked
     to any (finite) depth.

     See also ‘identfor’

 -- Function: zeromatrixp (<M>)

     If <M> is not a block matrix, return ‘true’ if ‘is (equal (<e>,
     0))’ is true for each element <e> of the matrix <M>.  If <M> is a
     block matrix, return ‘true’ if ‘zeromatrixp’ evaluates to ‘true’
     for each element of <e>.


File: maxima.info,  Node: Package lsquares,  Next: Package makeOrders,  Prev: Package linearalgebra,  Up: Top

59 lsquares
***********

* Menu:

* Introduction to lsquares::
* Functions and Variables for lsquares::


File: maxima.info,  Node: Introduction to lsquares,  Next: Functions and Variables for lsquares,  Prev: Package lsquares,  Up: Package lsquares

59.1 Introduction to lsquares
=============================

‘lsquares’ is a collection of functions to implement the method of least
squares to estimate parameters for a model from numerical data.


File: maxima.info,  Node: Functions and Variables for lsquares,  Prev: Introduction to lsquares,  Up: Package lsquares

59.2 Functions and Variables for lsquares
=========================================

 -- Function: lsquares_estimates
          lsquares_estimates (<D>, <x>, <e>, <a>)
          lsquares_estimates (<D>, <x>, <e>, <a>, initial = <L>, tol =
          <t>)

     Estimate parameters <a> to best fit the equation <e> in the
     variables <x> and <a> to the data <D>, as determined by the method
     of least squares.  ‘lsquares_estimates’ first seeks an exact
     solution, and if that fails, then seeks an approximate solution.

     The return value is a list of lists of equations of the form ‘[a =
     ..., b = ..., c = ...]’.  Each element of the list is a distinct,
     equivalent minimum of the mean square error.

     The data <D> must be a matrix.  Each row is one datum (which may be
     called a ‘record’ or ‘case’ in some contexts), and each column
     contains the values of one variable across all data.  The list of
     variables <x> gives a name for each column of <D>, even the columns
     which do not enter the analysis.  The list of parameters <a> gives
     the names of the parameters for which estimates are sought.  The
     equation <e> is an expression or equation in the variables <x> and
     <a>; if <e> is not an equation, it is treated the same as ‘<e> =
     0’.

     Additional arguments to ‘lsquares_estimates’ are specified as
     equations and passed on verbatim to the function ‘lbfgs’ which is
     called to find estimates by a numerical method when an exact result
     is not found.

     If some exact solution can be found (via ‘solve’), the data <D> may
     contain non-numeric values.  However, if no exact solution is
     found, each element of <D> must have a numeric value.  This
     includes numeric constants such as ‘%pi’ and ‘%e’ as well as
     literal numbers (integers, rationals, ordinary floats, and
     bigfloats).  Numerical calculations are carried out with ordinary
     floating-point arithmetic, so all other kinds of numbers are
     converted to ordinary floats for calculations.

     If ‘lsquares_estimates’ needs excessive amounts of time or runs out
     of memory ‘lsquares_estimates_approximate’, which skips the attempt
     to find an exact solution, might still succeed.

     ‘load("lsquares")’ loads this function.

     See also ‘lsquares_estimates_exact’,
     ‘lsquares_estimates_approximate’,
     ‘lsquares_mse’, ‘lsquares_residuals’, and ‘lsquares_residual_mse’.

     Examples:

     A problem for which an exact solution is found.

          (%i1) load ("lsquares")$
          (%i2) M : matrix (
                  [1,1,1], [3/2,1,2], [9/4,2,1], [3,2,2], [2,2,1]);
                                     [ 1  1  1 ]
                                     [         ]
                                     [ 3       ]
                                     [ -  1  2 ]
                                     [ 2       ]
                                     [         ]
          (%o2)                      [ 9       ]
                                     [ -  2  1 ]
                                     [ 4       ]
                                     [         ]
                                     [ 3  2  2 ]
                                     [         ]
                                     [ 2  2  1 ]
          (%i3) lsquares_estimates (
                   M, [z,x,y], (z+D)^2 = A*x+B*y+C, [A,B,C,D]);
                            59        27      10921        107
          (%o3)     [[A = - --, B = - --, C = -----, D = - ---]]
                            16        16      1024         32

     A problem for which no exact solution is found, so
     ‘lsquares_estimates’ resorts to numerical approximation.

          (%i1) load ("lsquares")$
          (%i2) M : matrix ([1, 1], [2, 7/4], [3, 11/4], [4, 13/4]);
                                      [ 1  1  ]
                                      [       ]
                                      [    7  ]
                                      [ 2  -  ]
                                      [    4  ]
                                      [       ]
          (%o2)                       [    11 ]
                                      [ 3  -- ]
                                      [    4  ]
                                      [       ]
                                      [    13 ]
                                      [ 4  -- ]
                                      [    4  ]
          (%i3) lsquares_estimates (
            M, [x,y], y=a*x^b+c, [a,b,c], initial=[3,3,3], iprint=[-1,0]);
          (%o3) [[a = 1.375751433061394, b = 0.7148891534417651,
                                                 c = - 0.4020908910062951]]

     Exponential functions aren’t well-conditioned for least min square
     fitting.  In case that fitting to them fails it might be possible
     to get rid of the exponential function using an logarithm.

          (%i1) load ("lsquares")$
          (%i2) yvalues: [1,3,5,60,200,203,80]$
          (%i3) time: [1,2,4,5,6,8,10]$
          (%i4) f: y=a*exp(b*t);
                                             b t
          (%o4)                      y = a %e
          (%i5) yvalues_log: log(yvalues)$
          (%i6) f_log: log(subst(y=exp(y),f));
                                              b t
          (%o6)                   y = log(a %e   )
          (%i7) lsquares_estimates (transpose(matrix(yvalues_log,time)),
                                    [y,t], f_log, [a,b]);
          *************************************************
            N=    2   NUMBER OF CORRECTIONS=25
                 INITIAL VALUES
           F=  6.802906290754687D+00   GNORM=  2.851243373781393D+01
          *************************************************

          I NFN FUNC                  GNORM                 STEPLENGTH

          1   3 1.141838765593467D+00 1.067358003667488D-01 1.390943719972406D-02
          2   5 1.141118195694385D+00 1.237977833033414D-01 5.000000000000000D+00
          3   6 1.136945723147959D+00 3.806696991691383D-01 1.000000000000000D+00
          4   7 1.133958243220262D+00 3.865103550379243D-01 1.000000000000000D+00
          5   8 1.131725773805499D+00 2.292258231154026D-02 1.000000000000000D+00
          6   9 1.131625585698168D+00 2.664440547017370D-03 1.000000000000000D+00
          7  10 1.131620564856599D+00 2.519366958715444D-04 1.000000000000000D+00

           THE MINIMIZATION TERMINATED WITHOUT DETECTING ERRORS.
           IFLAG = 0
          (%o7)   [[a = 1.155904145765554, b = 0.5772666876959847]]

 -- Function: lsquares_estimates_exact (<MSE>, <a>)

     Estimate parameters <a> to minimize the mean square error <MSE>, by
     constructing a system of equations and attempting to solve them
     symbolically via ‘solve’.  The mean square error is an expression
     in the parameters <a>, such as that returned by ‘lsquares_mse’.

     The return value is a list of lists of equations of the form ‘[a =
     ..., b = ..., c = ...]’.  The return value may contain zero, one,
     or two or more elements.  If two or more elements are returned,
     each represents a distinct, equivalent minimum of the mean square
     error.

     See also ‘lsquares_estimates’, ‘lsquares_estimates_approximate’,
     ‘lsquares_mse’, ‘lsquares_residuals’, and ‘lsquares_residual_mse’.

     Example:

          (%i1) load ("lsquares")$
          (%i2) M : matrix (
                   [1,1,1], [3/2,1,2], [9/4,2,1], [3,2,2], [2,2,1]);
                                     [ 1  1  1 ]
                                     [         ]
                                     [ 3       ]
                                     [ -  1  2 ]
                                     [ 2       ]
                                     [         ]
          (%o2)                      [ 9       ]
                                     [ -  2  1 ]
                                     [ 4       ]
                                     [         ]
                                     [ 3  2  2 ]
                                     [         ]
                                     [ 2  2  1 ]
          (%i3) mse : lsquares_mse (M, [z, x, y], (z + D)^2 = A*x + B*y + C);
                   5
                  ====
                  \                                         2     2
                   >    ((- B M    ) - A M     + (M     + D)  - C)
                  /            i, 3       i, 2     i, 1
                  ====
                  i = 1
          (%o3)   -------------------------------------------------
                                          5
          (%i4) lsquares_estimates_exact (mse, [A, B, C, D]);
                            59        27      10921        107
          (%o4)     [[A = - --, B = - --, C = -----, D = - ---]]
                            16        16      1024         32

 -- Function: lsquares_estimates_approximate (<MSE>, <a>, initial = <L>,
          tol = <t>)

     Estimate parameters <a> to minimize the mean square error <MSE>,
     via the numerical minimization function ‘lbfgs’.  The mean square
     error is an expression in the parameters <a>, such as that returned
     by ‘lsquares_mse’.

     The solution returned by ‘lsquares_estimates_approximate’ is a
     local (perhaps global) minimum of the mean square error.  For
     consistency with ‘lsquares_estimates_exact’, the return value is a
     nested list which contains one element, namely a list of equations
     of the form ‘[a = ..., b = ..., c = ...]’.

     Additional arguments to ‘lsquares_estimates_approximate’ are
     specified as equations and passed on verbatim to the function
     ‘lbfgs’.

     <MSE> must evaluate to a number when the parameters are assigned
     numeric values.  This requires that the data from which <MSE> was
     constructed comprise only numeric constants such as ‘%pi’ and ‘%e’
     and literal numbers (integers, rationals, ordinary floats, and
     bigfloats).  Numerical calculations are carried out with ordinary
     floating-point arithmetic, so all other kinds of numbers are
     converted to ordinary floats for calculations.

     ‘load("lsquares")’ loads this function.

     See also ‘lsquares_estimates’, ‘lsquares_estimates_exact’,
     ‘lsquares_mse’,
     ‘lsquares_residuals’, and ‘lsquares_residual_mse’.

     Example:

          (%i1) load ("lsquares")$
          (%i2) M : matrix (
                   [1,1,1], [3/2,1,2], [9/4,2,1], [3,2,2], [2,2,1]);
                                     [ 1  1  1 ]
                                     [         ]
                                     [ 3       ]
                                     [ -  1  2 ]
                                     [ 2       ]
                                     [         ]
          (%o2)                      [ 9       ]
                                     [ -  2  1 ]
                                     [ 4       ]
                                     [         ]
                                     [ 3  2  2 ]
                                     [         ]
                                     [ 2  2  1 ]
          (%i3) mse : lsquares_mse (M, [z, x, y], (z + D)^2 = A*x + B*y + C);
                   5
                  ====
                  \                                         2     2
                   >    ((- B M    ) - A M     + (M     + D)  - C)
                  /            i, 3       i, 2     i, 1
                  ====
                  i = 1
          (%o3)   -------------------------------------------------
                                          5
          (%i4) lsquares_estimates_approximate (
                  mse, [A, B, C, D], iprint = [-1, 0]);
          (%o4) [[A = - 3.678504947401971, B = - 1.683070351177937,
                           C = 10.63469950148714, D = - 3.340357993175297]]

 -- Function: lsquares_mse (<D>, <x>, <e>)

     Returns the mean square error (MSE), a summation expression, for
     the equation <e> in the variables <x>, with data <D>.

     The MSE is defined as:

                              n
                             ====
                         1   \                        2
                         -    >    (lhs(e ) - rhs(e ))
                         n   /           i         i
                             ====
                             i = 1

     where <n> is the number of data and ‘<e>[i]’ is the equation <e>
     evaluated with the variables in <x> assigned values from the ‘i’-th
     datum, ‘<D>[i]’.

     ‘load("lsquares")’ loads this function.

     Example:

          (%i1) load ("lsquares")$
          (%i2) M : matrix (
                   [1,1,1], [3/2,1,2], [9/4,2,1], [3,2,2], [2,2,1]);
                                     [ 1  1  1 ]
                                     [         ]
                                     [ 3       ]
                                     [ -  1  2 ]
                                     [ 2       ]
                                     [         ]
          (%o2)                      [ 9       ]
                                     [ -  2  1 ]
                                     [ 4       ]
                                     [         ]
                                     [ 3  2  2 ]
                                     [         ]
                                     [ 2  2  1 ]
          (%i3) mse : lsquares_mse (M, [z, x, y], (z + D)^2 = A*x + B*y + C);
                   5
                  ====
                  \                                         2     2
                   >    ((- B M    ) - A M     + (M     + D)  - C)
                  /            i, 3       i, 2     i, 1
                  ====
                  i = 1
          (%o3)   -------------------------------------------------
                                          5
          (%i4) diff (mse, D);
          (%o4)
                5
               ====
               \                                                     2
             4  >    (M     + D) ((- B M    ) - A M     + (M     + D)  - C)
               /       i, 1             i, 3       i, 2     i, 1
               ====
               i = 1
             --------------------------------------------------------------
                                           5
          (%i5) ''mse, nouns;
                         2                 2         9 2               2
          (%o5) (((D + 3)  - C - 2 B - 2 A)  + ((D + -)  - C - B - 2 A)
                                                     4
                     2               2         3 2               2
           + ((D + 2)  - C - B - 2 A)  + ((D + -)  - C - 2 B - A)
                                               2
                     2             2
           + ((D + 1)  - C - B - A) )/5
          (%i3) mse : lsquares_mse (M, [z, x, y], (z + D)^2 = A*x + B*y + C);
                     5
                    ====
                    \                 2                         2
                     >    ((D + M    )  - C - M     B - M     A)
                    /            i, 1          i, 3      i, 2
                    ====
                    i = 1
          (%o3)     ---------------------------------------------
                                          5
          (%i4) diff (mse, D);
                   5
                  ====
                  \                             2
                4  >    (D + M    ) ((D + M    )  - C - M     B - M     A)
                  /           i, 1         i, 1          i, 3      i, 2
                  ====
                  i = 1
          (%o4) ----------------------------------------------------------
                                            5
          (%i5) ''mse, nouns;
                         2                 2         9 2               2
          (%o5) (((D + 3)  - C - 2 B - 2 A)  + ((D + -)  - C - B - 2 A)
                                                     4
                     2               2         3 2               2
           + ((D + 2)  - C - B - 2 A)  + ((D + -)  - C - 2 B - A)
                                               2
                     2             2
           + ((D + 1)  - C - B - A) )/5

 -- Function: lsquares_residuals (<D>, <x>, <e>, <a>)

     Returns the residuals for the equation <e> with specified
     parameters <a> and data <D>.

     <D> is a matrix, <x> is a list of variables, <e> is an equation or
     general expression; if not an equation, <e> is treated as if it
     were ‘<e> = 0’.  <a> is a list of equations which specify values
     for any free parameters in <e> aside from <x>.

     The residuals are defined as:

                                  lhs(e ) - rhs(e )
                                       i         i

     where ‘<e>[i]’ is the equation <e> evaluated with the variables in
     <x> assigned values from the ‘i’-th datum, ‘<D>[i]’, and assigning
     any remaining free variables from <a>.

     ‘load("lsquares")’ loads this function.

     Example:

          (%i1) load ("lsquares")$
          (%i2) M : matrix (
                   [1,1,1], [3/2,1,2], [9/4,2,1], [3,2,2], [2,2,1]);
                                     [ 1  1  1 ]
                                     [         ]
                                     [ 3       ]
                                     [ -  1  2 ]
                                     [ 2       ]
                                     [         ]
          (%o2)                      [ 9       ]
                                     [ -  2  1 ]
                                     [ 4       ]
                                     [         ]
                                     [ 3  2  2 ]
                                     [         ]
                                     [ 2  2  1 ]
          (%i3) a : lsquares_estimates (
                    M, [z,x,y], (z+D)^2 = A*x+B*y+C, [A,B,C,D]);
                            59        27      10921        107
          (%o3)     [[A = - --, B = - --, C = -----, D = - ---]]
                            16        16      1024         32
          (%i4) lsquares_residuals (
                    M, [z,x,y], (z+D)^2 = A*x+B*y+C, first(a));
                               13    13    13  13  13
          (%o4)               [--, - --, - --, --, --]
                               64    64    32  64  64

 -- Function: lsquares_residual_mse (<D>, <x>, <e>, <a>)

     Returns the residual mean square error (MSE) for the equation <e>
     with specified parameters <a> and data <D>.

     The residual MSE is defined as:

                              n
                             ====
                         1   \                        2
                         -    >    (lhs(e ) - rhs(e ))
                         n   /           i         i
                             ====
                             i = 1

     where ‘<e>[i]’ is the equation <e> evaluated with the variables in
     <x> assigned values from the ‘i’-th datum, ‘<D>[i]’, and assigning
     any remaining free variables from <a>.

     ‘load("lsquares")’ loads this function.

     Example:

          (%i1) load ("lsquares")$
          (%i2) M : matrix (
                   [1,1,1], [3/2,1,2], [9/4,2,1], [3,2,2], [2,2,1]);
                                     [ 1  1  1 ]
                                     [         ]
                                     [ 3       ]
                                     [ -  1  2 ]
                                     [ 2       ]
                                     [         ]
          (%o2)                      [ 9       ]
                                     [ -  2  1 ]
                                     [ 4       ]
                                     [         ]
                                     [ 3  2  2 ]
                                     [         ]
                                     [ 2  2  1 ]
          (%i3) a : lsquares_estimates (
                 M, [z,x,y], (z+D)^2 = A*x+B*y+C, [A,B,C,D]);
                            59        27      10921        107
          (%o3)     [[A = - --, B = - --, C = -----, D = - ---]]
                            16        16      1024         32
          (%i4) lsquares_residual_mse (
                 M, [z,x,y], (z + D)^2 = A*x + B*y + C, first (a));
                                        169
          (%o4)                         ----
                                        2560

 -- Function: plsquares
          plsquares (<Mat>,<VarList>,<depvars>)
          plsquares (<Mat>,<VarList>,<depvars>,<maxexpon>)
          plsquares (<Mat>,<VarList>,<depvars>,<maxexpon>,<maxdegree>)
     Multivariable polynomial adjustment of a data table by the "least
     squares" method.  <Mat> is a matrix containing the data, <VarList>
     is a list of variable names (one for each Mat column, but use "-"
     instead of varnames to ignore Mat columns), <depvars> is the name
     of a dependent variable or a list with one or more names of
     dependent variables (which names should be in <VarList>),
     <maxexpon> is the optional maximum exponent for each independent
     variable (1 by default), and <maxdegree> is the optional maximum
     polynomial degree (<maxexpon> by default); note that the sum of
     exponents of each term must be equal or smaller than <maxdegree>,
     and if ‘maxdgree = 0’ then no limit is applied.

     If <depvars> is the name of a dependent variable (not in a list),
     ‘plsquares’ returns the adjusted polynomial.  If <depvars> is a
     list of one or more dependent variables, ‘plsquares’ returns a list
     with the adjusted polynomial(s).  The Coefficients of Determination
     are displayed in order to inform about the goodness of fit, which
     ranges from 0 (no correlation) to 1 (exact correlation).  These
     values are also stored in the global variable <DETCOEF> (a list if
     <depvars> is a list).

     A simple example of multivariable linear adjustment:
          (%i1) load("plsquares")$

          (%i2) plsquares(matrix([1,2,0],[3,5,4],[4,7,9],[5,8,10]),
                          [x,y,z],z);
               Determination Coefficient for z = .9897039897039897
                                 11 y - 9 x - 14
          (%o2)              z = ---------------
                                        3

     The same example without degree restrictions:
          (%i3) plsquares(matrix([1,2,0],[3,5,4],[4,7,9],[5,8,10]),
                          [x,y,z],z,1,0);
               Determination Coefficient for z = 1.0
                              x y + 23 y - 29 x - 19
          (%o3)           z = ----------------------
                                        6

     How many diagonals does a N-sides polygon have?  What polynomial
     degree should be used?
          (%i4) plsquares(matrix([3,0],[4,2],[5,5],[6,9],[7,14],[8,20]),
                          [N,diagonals],diagonals,5);
               Determination Coefficient for diagonals = 1.0
                                          2
                                         N  - 3 N
          (%o4)              diagonals = --------
                                            2
          (%i5) ev(%, N=9);   /* Testing for a 9 sides polygon */
          (%o5)                 diagonals = 27

     How many ways do we have to put two queens without they are
     threatened into a n x n chessboard?
          (%i6) plsquares(matrix([0,0],[1,0],[2,0],[3,8],[4,44]),
                          [n,positions],[positions],4);
               Determination Coefficient for [positions] = [1.0]
                                   4       3      2
                                3 n  - 10 n  + 9 n  - 2 n
          (%o6)    [positions = -------------------------]
                                            6
          (%i7) ev(%[1], n=8); /* Testing for a (8 x 8) chessboard */
          (%o7)                positions = 1288

     An example with six dependent variables:
          (%i8) mtrx:matrix([0,0,0,0,0,1,1,1],[0,1,0,1,1,1,0,0],
                            [1,0,0,1,1,1,0,0],[1,1,1,1,0,0,0,1])$
          (%i8) plsquares(mtrx,[a,b,_And,_Or,_Xor,_Nand,_Nor,_Nxor],
                               [_And,_Or,_Xor,_Nand,_Nor,_Nxor],1,0);
                Determination Coefficient for
          [_And, _Or, _Xor, _Nand, _Nor, _Nxor] =
          [1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
          (%o2) [_And = a b, _Or = - a b + b + a,
          _Xor = - 2 a b + b + a, _Nand = 1 - a b,
          _Nor = a b - b - a + 1, _Nxor = 2 a b - b - a + 1]

     To use this function write first ‘load("lsquares")’.


File: maxima.info,  Node: Package makeOrders,  Next: Package mnewton,  Prev: Package lsquares,  Up: Top

60 makeOrders
*************

* Menu:

* Functions and Variables for makeOrders::


File: maxima.info,  Node: Functions and Variables for makeOrders,  Prev: Package makeOrders,  Up: Package makeOrders

60.1 Functions and Variables for makeOrders
===========================================

 -- Function: makeOrders (<indvarlist>,<orderlist>)
     Returns a list of all powers for a polynomial up to and including
     the arguments.

          (%i1) load("makeOrders")$

          (%i2) makeOrders([a,b],[2,3]);
          (%o2) [[0, 0], [0, 1], [0, 2], [0, 3], [1, 0], [1, 1],
                      [1, 2], [1, 3], [2, 0], [2, 1], [2, 2], [2, 3]]
          (%i3) expand((1+a+a^2)*(1+b+b^2+b^3));
                 2  3      3    3    2  2      2    2    2
          (%o3) a  b  + a b  + b  + a  b  + a b  + b  + a  b + a b
                                                            2
                                                     + b + a  + a + 1
     where ‘[0, 1]’ is associated with the term b and ‘[2, 3]’ with a^2
     b^3.

     To use this function write first ‘load("makeOrders")’.


File: maxima.info,  Node: Package mnewton,  Next: Package numericalio,  Prev: Package makeOrders,  Up: Top

61 mnewton
**********

* Menu:

* Introduction to mnewton::
* Functions and Variables for mnewton::


File: maxima.info,  Node: Introduction to mnewton,  Next: Functions and Variables for mnewton,  Prev: Package mnewton,  Up: Package mnewton

61.1 Introduction to mnewton
============================

‘mnewton’ is an implementation of Newton’s method for solving nonlinear
equations in one or more variables.


File: maxima.info,  Node: Functions and Variables for mnewton,  Prev: Introduction to mnewton,  Up: Package mnewton

61.2 Functions and Variables for mnewton
========================================

 -- Option variable: newtonepsilon
     Default value: ‘10.0^(-fpprec/2)’

     Precision to determine when the ‘mnewton’ function has converged
     towards the solution.

     When ‘newtonepsilon’ is a bigfloat, ‘mnewton’ computations are done
     with bigfloats; otherwise, ordinary floats are used.

     See also ‘mnewton’.

 -- Option variable: newtonmaxiter
     Default value: ‘50’

     Maximum number of iterations to stop the ‘mnewton’ function if it
     does not converge or if it converges too slowly.

     See also ‘mnewton’.

 -- Option variable: newtondebug
     Default value: ‘false’

     When ‘newtondebug’ is ‘true’, ‘mnewton’ prints out debugging
     information while solving a problem.

 -- Function: mnewton
          mnewton (<FuncList>, <VarList>, <GuessList>)
          mnewton (<FuncList>, <VarList>, <GuessList>, <DF>)

     Approximate solution of multiple nonlinear equations by Newton’s
     method.

     <FuncList> is a list of functions to solve, <VarList> is a list of
     variable names, and <GuessList> is a list of initial
     approximations.  The optional argument <DF> is the Jacobian matrix
     of the list of functions; if not supplied, it is calculated
     automatically from <FuncList>.

     <FuncList> may be specified as a list of equations, in which case
     the function to be solved is the left-hand side of each equation
     minus the right-hand side.

     If there is only a single function, variable, and initial point,
     they may be specified as a single expression, variable, and initial
     value; they need not be lists of one element.

     A variable may be a simple symbol or a subscripted symbol.

     The solution, if any, is returned as a list of one element, which
     is a list of equations, one for each variable, specifying an
     approximate solution; this is the same format as returned by
     ‘solve’.  If the solution is not found, ‘[]’ is returned.

     Functions and initial points may contain complex numbers, and
     solutions likewise may contain complex numbers.

     ‘mnewton’ is governed by global variables ‘newtonepsilon’ and
     ‘newtonmaxiter’, and the global flag ‘newtondebug’.

     ‘load("mnewton")’ loads this function.

     See also ‘realroots’, ‘allroots’, ‘find_root’ and ‘newton’.

     Examples:

          (%i1) load("mnewton")$

          (%i2) mnewton([x1+3*log(x1)-x2^2, 2*x1^2-x1*x2-5*x1+1],
                        [x1, x2], [5, 5]);
          (%o2) [[x1 = 3.756834008012769, x2 = 2.779849592817897]]
          (%i3) mnewton([2*a^a-5],[a],[1]);
          (%o3)             [[a = 1.70927556786144]]
          (%i4) mnewton([2*3^u-v/u-5, u+2^v-4], [u, v], [2, 2]);
          (%o4) [[u = 1.066618389595407, v = 1.552564766841786]]

     The variable ‘newtonepsilon’ controls the precision of the
     approximations.  It also controls if computations are performed
     with floats or bigfloats.

          (%i1) load("mnewton")$

          (%i2) (fpprec : 25, newtonepsilon : bfloat(10^(-fpprec+5)))$

          (%i3) mnewton([2*3^u-v/u-5, u+2^v-4], [u, v], [2, 2]);
          (%o3) [[u = 1.066618389595406772591173b0,
                                         v = 1.552564766841786450100418b0]]


File: maxima.info,  Node: Package numericalio,  Next: Package opsubst,  Prev: Package mnewton,  Up: Top

62 numericalio
**************

* Menu:

* Introduction to numericalio::
* Functions and Variables for plain-text input and output::
* Functions and Variables for binary input and output::


File: maxima.info,  Node: Introduction to numericalio,  Next: Functions and Variables for plain-text input and output,  Prev: Package numericalio,  Up: Package numericalio

62.1 Introduction to numericalio
================================

‘numericalio’ is a collection of functions to read and write files and
streams.  Functions for plain-text input and output can read and write
numbers (integer, float, or bigfloat), symbols, and strings.  Functions
for binary input and output can read and write only floating-point
numbers.

   If there already exists a list, matrix, or array object to store
input data, ‘numericalio’ input functions can write data into that
object.  Otherwise, ‘numericalio’ can guess, to some degree, the
structure of an object to store the data, and return that object.

62.1.1 Plain-text input and output
----------------------------------

In plain-text input and output, it is assumed that each item to read or
write is an atom: an integer, float, bigfloat, string, or symbol, and
not a rational or complex number or any other kind of nonatomic
expression.  The ‘numericalio’ functions may attempt to do something
sensible faced with nonatomic expressions, but the results are not
specified here and subject to change.

   Atoms in both input and output files have the same format as in
Maxima batch files or the interactive console.  In particular, strings
are enclosed in double quotes, backslash ‘\’ prevents any special
interpretation of the next character, and the question mark ‘?’ is
recognized at the beginning of a symbol to mean a Lisp symbol (as
opposed to a Maxima symbol).  No continuation character (to join broken
lines) is recognized.

62.1.2 Separator flag values for input
--------------------------------------

The functions for plain-text input and output take an optional argument,
<separator_flag>, that tells what character separates data.

   For plain-text input, these values of <separator_flag> are
recognized: ‘comma’ for comma separated values, ‘pipe’ for values
separated by the vertical bar character ‘|’, ‘semicolon’ for values
separated by semicolon ‘;’, and ‘space’ for values separated by space or
tab characters.  Equivalently, the separator may be specified as a
string of one character: ‘","’ (comma), ‘"|"’ (pipe), ‘";"’ (semicolon),
‘" "’ (space), or ‘" "’ (tab).

   If the file name ends in ‘.csv’ and <separator_flag> is not
specified, ‘comma’ is assumed.  If the file name ends in something other
than ‘.csv’ and ‘separator_flag’ is not specified, ‘space’ is assumed.

   In plain-text input, multiple successive space and tab characters
count as a single separator.  However, multiple comma, pipe, or
semicolon characters are significant.  Successive comma, pipe, or
semicolon characters (with or without intervening spaces or tabs) are
considered to have ‘false’ between the separators.  For example,
‘1234,,Foo’ is treated the same as ‘1234,false,Foo’.

62.1.3 Separator flag values for output
---------------------------------------

For plain-text output, ‘tab’, for values separated by the tab character,
is recognized as a value of <separator_flag>, as well as ‘comma’,
‘pipe’, ‘semicolon’, and ‘space’.

   In plain-text output, ‘false’ atoms are written as such; a list
‘[1234, false, Foo]’ is written ‘1234,false,Foo’, and there is no
attempt to collapse the output to ‘1234,,Foo’.

62.1.4 Binary floating-point input and output
---------------------------------------------

‘numericalio’ functions can read and write 8-byte IEEE 754
floating-point numbers.  These numbers can be stored either least
significant byte first or most significant byte first, according to the
global flag set by ‘assume_external_byte_order’.  If not specified,
‘numericalio’ assumes the external byte order is most-significant byte
first.

   Other kinds of numbers are coerced to 8-byte floats; ‘numericalio’
cannot read or write binary non-numeric data.

   Some Lisp implementations do not recognize IEEE 754 special values
(positive and negative infinity, not-a-number values, denormalized
values).  The effect of reading such values with ‘numericalio’ is
undefined.

   ‘numericalio’ includes functions to open a stream for reading or
writing a stream of bytes.


File: maxima.info,  Node: Functions and Variables for plain-text input and output,  Next: Functions and Variables for binary input and output,  Prev: Introduction to numericalio,  Up: Package numericalio

62.2 Functions and Variables for plain-text input and output
============================================================

 -- Function: read_matrix
          read_matrix (<S>)
          read_matrix (<S>, <M>)
          read_matrix (<S>, <separator_flag>)
          read_matrix (<S>, <M>, <separator_flag>)

     ‘read_matrix(<S>)’ reads the source <S> and returns its entire
     content as a matrix.  The size of the matrix is inferred from the
     input data; each line of the file becomes one row of the matrix.
     If some lines have different lengths, ‘read_matrix’ complains.

     ‘read_matrix(<S>, <M>)’ read the source <S> into the matrix <M>,
     until <M> is full or the source is exhausted.  Input data are read
     into the matrix in row-major order; the input need not have the
     same number of rows and columns as <M>.

     The source <S> may be a file name or a stream which for example
     allows skipping the very first line of a file (that may be useful,
     if you read CSV data, where the first line often contains the
     description of the columns):
          s : openr("data.txt");
          readline(s);  /* skip the first line */
          M : read_matrix(s, 'comma);  /* read the following (comma-separated) lines into matrix M */
          close(s);

     The recognized values of <separator_flag> are ‘comma’, ‘pipe’,
     ‘semicolon’, and ‘space’.  Equivalently, the separator may be
     specified as a string of one character: ‘","’ (comma), ‘"|"’
     (pipe), ‘";"’ (semicolon), ‘" "’ (space), or ‘" "’ (tab).  If
     <separator_flag> is not specified, the file is assumed
     space-delimited.

     See also ‘openr’, ‘read_array’, ‘read_hashed_array’, ‘read_list’,
     ‘read_binary_matrix’, ‘write_data’ and ‘read_nested_list’.

 -- Function: read_array
          read_array (<S>, <A>)
          read_array (<S>, <A>, <separator_flag>)

     Reads the source <S> into the array <A>, until <A> is full or the
     source is exhausted.  Input data are read into the array in
     row-major order; the input need not conform to the dimensions of
     <A>.

     The source <S> may be a file name or a stream.

     The recognized values of <separator_flag> are ‘comma’, ‘pipe’,
     ‘semicolon’, and ‘space’.  Equivalently, the separator may be
     specified as a string of one character: ‘","’ (comma), ‘"|"’
     (pipe), ‘";"’ (semicolon), ‘" "’ (space), or ‘" "’ (tab).  If
     <separator_flag> is not specified, the file is assumed
     space-delimited.

     See also ‘openr’, ‘read_matrix’, ‘read_hashed_array’, ‘read_list’,
     ‘read_binary_array’ and ‘read_nested_list’.

 -- Function: read_hashed_array
          read_hashed_array (<S>, <A>)
          read_hashed_array (<S>, <A>, <separator_flag>)

     Reads the source <S> and returns its entire content as a ‘hashed
     array’.  The source <S> may be a file name or a stream.

     ‘read_hashed_array’ treats the first item on each line as a hash
     key, and associates the remainder of the line (as a list) with the
     key.  For example, the line ‘567 12 17 32 55’ is equivalent to
     ‘A[567]: [12, 17, 32, 55]$’.  Lines need not have the same numbers
     of elements.

     The recognized values of <separator_flag> are ‘comma’, ‘pipe’,
     ‘semicolon’, and ‘space’.  Equivalently, the separator may be
     specified as a string of one character: ‘","’ (comma), ‘"|"’
     (pipe), ‘";"’ (semicolon), ‘" "’ (space), or ‘" "’ (tab).  If
     <separator_flag> is not specified, the file is assumed
     space-delimited.

     See also ‘openr’, ‘read_matrix’, ‘read_array’, ‘read_list’ and
     ‘read_nested_list’.

 -- Function: read_nested_list
          read_nested_list (<S>)
          read_nested_list (<S>, <separator_flag>)

     Reads the source <S> and returns its entire content as a nested
     list.  The source <S> may be a file name or a stream.

     ‘read_nested_list’ returns a list which has a sublist for each line
     of input.  Lines need not have the same numbers of elements.  Empty
     lines are not ignored: an empty line yields an empty sublist.

     The recognized values of <separator_flag> are ‘comma’, ‘pipe’,
     ‘semicolon’, and ‘space’.  Equivalently, the separator may be
     specified as a string of one character: ‘","’ (comma), ‘"|"’
     (pipe), ‘";"’ (semicolon), ‘" "’ (space), or ‘" "’ (tab).  If
     <separator_flag> is not specified, the file is assumed
     space-delimited.

     See also ‘openr’, ‘read_matrix’, ‘read_array’, ‘read_list’ and
     ‘read_hashed_array’.

 -- Function: read_list
          read_list (<S>)
          read_list (<S>, <L>)
          read_list (<S>, <separator_flag>)
          read_list (<S>, <L>, <separator_flag>)

     ‘read_list(<S>)’ reads the source <S> and returns its entire
     content as a flat list.

     ‘read_list(<S>, <L>)’ reads the source <S> into the list <L>, until
     <L> is full or the source is exhausted.

     The source <S> may be a file name or a stream.

     The recognized values of <separator_flag> are ‘comma’, ‘pipe’,
     ‘semicolon’, and ‘space’.  Equivalently, the separator may be
     specified as a string of one character: ‘","’ (comma), ‘"|"’
     (pipe), ‘";"’ (semicolon), ‘" "’ (space), or ‘" "’ (tab).  If
     <separator_flag> is not specified, the file is assumed
     space-delimited.

     See also ‘openr’, ‘read_matrix’, ‘read_array’, ‘read_nested_list’,
     ‘read_binary_list’ and ‘read_hashed_array’.

 -- Function: write_data
          write_data (<X>, <D>)
          write_data (<X>, <D>, <separator_flag>)

     Writes the object <X> to the destination <D>.

     ‘write_data’ writes a matrix in row-major order, with one line per
     row.

     ‘write_data’ writes an array created by ‘array’ or ‘make_array’ in
     row-major order, with a new line at the end of every slab.
     Higher-dimensional slabs are separated by additional new lines.

     ‘write_data’ writes a hashed array with each key followed by its
     associated list on one line.

     ‘write_data’ writes a nested list with each sublist on one line.

     ‘write_data’ writes a flat list all on one line.

     The destination <D> may be a file name or a stream.  When the
     destination is a file name, the global variable
     ‘file_output_append’ governs whether the output file is appended or
     truncated.  When the destination is a stream, no special action is
     taken by ‘write_data’ after all the data are written; in
     particular, the stream remains open.

     The recognized values of <separator_flag> are ‘comma’, ‘pipe’,
     ‘semicolon’, ‘space’, and ‘tab’.  Equivalently, the separator may
     be specified as a string of one character: ‘","’ (comma), ‘"|"’
     (pipe), ‘";"’ (semicolon), ‘" "’ (space), or ‘" "’ (tab).  If
     <separator_flag> is not specified, the file is assumed
     space-delimited.

     See also ‘openw’ and ‘read_matrix’.


File: maxima.info,  Node: Functions and Variables for binary input and output,  Prev: Functions and Variables for plain-text input and output,  Up: Package numericalio

62.3 Functions and Variables for binary input and output
========================================================

 -- Function: assume_external_byte_order (<byte_order_flag>)
     Tells ‘numericalio’ the byte order for reading and writing binary
     data.  Two values of <byte_order_flag> are recognized: ‘lsb’ which
     indicates least-significant byte first, also called little-endian
     byte order; and ‘msb’ which indicates most-significant byte first,
     also called big-endian byte order.

     If not specified, ‘numericalio’ assumes the external byte order is
     most-significant byte first.

 -- Function: openr_binary (<file_name>)
     Returns an input stream of 8-bit unsigned bytes to read the file
     named by <file_name>.

     See also ‘openw_binary’ and ‘openr’.

 -- Function: openw_binary (<file_name>)
     Returns an output stream of 8-bit unsigned bytes to write the file
     named by <file_name>.

     See also ‘openr_binary’, ‘opena_binary’ and ‘openw’.

 -- Function: opena_binary (<file_name>)
     Returns an output stream of 8-bit unsigned bytes to append the file
     named by <file_name>.

 -- Function: read_binary_matrix (<S>, <M>)
     Reads binary 8-byte floating point numbers from the source <S> into
     the matrix <M> until <M> is full, or the source is exhausted.
     Elements of <M> are read in row-major order.

     The source <S> may be a file name or a stream.

     The byte order in elements of the source is specified by
     ‘assume_external_byte_order’.

     See also ‘read_matrix’.

 -- Function: read_binary_array (<S>, <A>)
     Reads binary 8-byte floating point numbers from the source <S> into
     the array <A> until <A> is full, or the source is exhausted.  <A>
     must be an array created by ‘array’ or ‘make_array’.  Elements of
     <A> are read in row-major order.

     The source <S> may be a file name or a stream.

     The byte order in elements of the source is specified by
     ‘assume_external_byte_order’.

     See also ‘read_array’.

 -- Function: read_binary_list
          read_binary_list (<S>)
          read_binary_list (<S>, <L>)

     ‘read_binary_list(<S>)’ reads the entire content of the source <S>
     as a sequence of binary 8-byte floating point numbers, and returns
     it as a list.  The source <S> may be a file name or a stream.

     ‘read_binary_list(<S>, <L>)’ reads 8-byte binary floating point
     numbers from the source <S> until the list <L> is full, or the
     source is exhausted.

     The byte order in elements of the source is specified by
     ‘assume_external_byte_order’.

     See also ‘read_list’.

 -- Function: write_binary_data (<X>, <D>)

     Writes the object <X>, comprising binary 8-byte IEEE 754
     floating-point numbers, to the destination <D>.  Other kinds of
     numbers are coerced to 8-byte floats.  ‘write_binary_data’ cannot
     write non-numeric data.

     The object <X> may be a list, a nested list, a matrix, or an array
     created by ‘array’ or ‘make_array’; <X> cannot be a hashed array or
     any other type of object.  ‘write_binary_data’ writes nested lists,
     matrices, and arrays in row-major order.

     The destination <D> may be a file name or a stream.  When the
     destination is a file name, the global variable
     ‘file_output_append’ governs whether the output file is appended or
     truncated.  When the destination is a stream, no special action is
     taken by ‘write_binary_data’ after all the data are written; in
     particular, the stream remains open.

     The byte order in elements of the destination is specified by
     ‘assume_external_byte_order’.

     See also ‘write_data’.


File: maxima.info,  Node: Package opsubst,  Next: Package orthopoly,  Prev: Package numericalio,  Up: Top

63 opsubst
**********

* Menu:

* Functions and Variables for opsubst::


File: maxima.info,  Node: Functions and Variables for opsubst,  Prev: Package opsubst,  Up: Package opsubst

63.1 Functions and Variables for opsubst
========================================

 -- Function: opsubst
          opsubst (<f>,<g>,<e>)
          opsubst (<g>=<f>,<e>)
          opsubst ([<g1>=<f1>,<g2>=<f2>,..., <gn>=<fn>],<e>)
     The function ‘opsubst’ is similar to the function ‘subst’, except
     that ‘opsubst’ only makes substitutions for the operators in an
     expression.  In general, When <f> is an operator in the expression
     <e>, substitute <g> for <f> in the expression <e>.

     To determine the operator, ‘opsubst’ sets ‘inflag’ to true.  This
     means ‘opsubst’ substitutes for the internal, not the displayed,
     operator in the expression.

     Examples:
          (%i1) load ("opsubst")$

          (%i2) opsubst(f,g,g(g(x)));
          (%o2)                     f(f(x))
          (%i3) opsubst(f,g,g(g));
          (%o3)                       f(g)
          (%i4) opsubst(f,g[x],g[x](z));
          (%o4)                       f(z)
          (%i5) opsubst(g[x],f, f(z));
          (%o5)                      g (z)
                                      x
          (%i6) opsubst(tan, sin, sin(sin));
          (%o6)                     tan(sin)
          (%i7) opsubst([f=g,g=h],f(x));
          (%o7)                       h(x)

     Internally, Maxima does not use the unary negation, division, or
     the subtraction operators; thus:
          (%i8) opsubst("+","-",a-b);
          (%o8)                     a - b
          (%i9) opsubst("f","-",-a);
          (%o9)                      - a
          (%i10) opsubst("^^","/",a/b);
                                       a
          (%o10)                       -
                                       b

     The internal representation of -a*b is *(-1,a,b); thus
          (%i11) opsubst("[","*", -a*b);
          (%o11)                  [- 1, a, b]

     When either operator isn’t a Maxima symbol, generally some other
     function will signal an error:
          (%i12) opsubst(a+b,f, f(x));

          Improper name or value in functional position:
          b + a
           -- an error.  Quitting.  To debug this try debugmode(true);

     However, subscripted operators are allowed:
          (%i13) opsubst(g[5],f, f(x));
          (%o13)                     g (x)
                                      5

     To use this function write first ‘load("opsubst")’.


File: maxima.info,  Node: Package orthopoly,  Next: Package romberg,  Prev: Package opsubst,  Up: Top

64 orthopoly
************

* Menu:

* Introduction to orthogonal polynomials::
* Functions and Variables for orthogonal polynomials::


File: maxima.info,  Node: Introduction to orthogonal polynomials,  Next: Functions and Variables for orthogonal polynomials,  Prev: Package orthopoly,  Up: Package orthopoly

64.1 Introduction to orthogonal polynomials
===========================================

‘orthopoly’ is a package for symbolic and numerical evaluation of
several kinds of orthogonal polynomials, including Chebyshev, Laguerre,
Hermite, Jacobi, Legendre, and ultraspherical (Gegenbauer) polynomials.
Additionally, ‘orthopoly’ includes support for the spherical Bessel,
spherical Hankel, and spherical harmonic functions.

   For the most part, ‘orthopoly’ follows the conventions of Abramowitz
and Stegun Handbook of Mathematical Functions, Chapter 22 (10th
printing, December 1972); additionally, we use Gradshteyn and Ryzhik,
Table of Integrals, Series, and Products (1980 corrected and enlarged
edition), and Eugen Merzbacher Quantum Mechanics (2nd edition, 1970).

   Barton Willis of the University of Nebraska at Kearney (UNK) wrote
the ‘orthopoly’ package and its documentation.  The package is released
under the GNU General Public License (GPL).

64.1.1 Getting Started with orthopoly
-------------------------------------

‘load ("orthopoly")’ loads the ‘orthopoly’ package.

   To find the third-order Legendre polynomial,

     (%i1) legendre_p (3, x);
                           3             2
                  5 (1 - x)    15 (1 - x)
     (%o1)      - ---------- + ----------- - 6 (1 - x) + 1
                      2             2

   To express this as a sum of powers of <x>, apply <ratsimp> or <rat>
to the result.

     (%i2) [ratsimp (%), rat (%)];
                             3           3
                          5 x  - 3 x  5 x  - 3 x
     (%o2)/R/            [----------, ----------]
                              2           2

   Alternatively, make the second argument to ‘legendre_p’ (its “main”
variable) a canonical rational expression (CRE).

     (%i1) legendre_p (3, rat (x));
                                   3
                                5 x  - 3 x
     (%o1)/R/                   ----------
                                    2

   For floating point evaluation, ‘orthopoly’ uses a running error
analysis to estimate an upper bound for the error.  For example,

     (%i1) jacobi_p (150, 2, 3, 0.2);
     (%o1) interval(- 0.062017037936715, 1.533267919277521E-11)

   Intervals have the form ‘interval (<c>, <r>)’, where <c> is the
center and <r> is the radius of the interval.  Since Maxima does not
support arithmetic on intervals, in some situations, such as graphics,
you want to suppress the error and output only the center of the
interval.  To do this, set the option variable
‘orthopoly_returns_intervals’ to ‘false’.

     (%i1) orthopoly_returns_intervals : false;
     (%o1)                         false
     (%i2) jacobi_p (150, 2, 3, 0.2);
     (%o2)                  - 0.062017037936715

   Refer to the section *note Floating point Evaluation:: for more
information.

   Most functions in ‘orthopoly’ have a ‘gradef’ property; thus

     (%i1) diff (hermite (n, x), x);
     (%o1)                     2 n H     (x)
                                    n - 1
     (%i2) diff (gen_laguerre (n, a, x), x);
                   (a)               (a)
                n L   (x) - (n + a) L     (x) unit_step(n)
                   n                 n - 1
     (%o2)      ------------------------------------------
                                    x

   The unit step function in the second example prevents an error that
would otherwise arise by evaluating with <n> equal to 0.

     (%i3) ev (%, n = 0);
     (%o3)                           0

   The ‘gradef’ property only applies to the “main” variable;
derivatives with respect other arguments usually result in an error
message; for example

     (%i1) diff (hermite (n, x), x);
     (%o1)                     2 n H     (x)
                                    n - 1
     (%i2) diff (hermite (n, x), n);

     Maxima doesn't know the derivative of hermite with respect the first
     argument
      -- an error.  Quitting.  To debug this try debugmode(true);

   Generally, functions in ‘orthopoly’ map over lists and matrices.  For
the mapping to fully evaluate, the option variables ‘doallmxops’ and
‘listarith’ must both be ‘true’ (the defaults).  To illustrate the
mapping over matrices, consider

     (%i1) hermite (2, x);
                                          2
     (%o1)                    - 2 (1 - 2 x )
     (%i2) m : matrix ([0, x], [y, 0]);
                                 [ 0  x ]
     (%o2)                       [      ]
                                 [ y  0 ]
     (%i3) hermite (2, m);
                    [                             2  ]
                    [      - 2        - 2 (1 - 2 x ) ]
     (%o3)          [                                ]
                    [             2                  ]
                    [ - 2 (1 - 2 y )       - 2       ]

   In the second example, the ‘i, j’ element of the value is ‘hermite
(2, m[i,j])’; this is not the same as computing ‘-2 + 4 m . m’, as seen
in the next example.

     (%i4) -2 * matrix ([1, 0], [0, 1]) + 4 * m . m;
                         [ 4 x y - 2      0     ]
     (%o4)               [                      ]
                         [     0      4 x y - 2 ]

   If you evaluate a function at a point outside its domain, generally
‘orthopoly’ returns the function unevaluated.  For example,

     (%i1) legendre_p (2/3, x);
     (%o1)                        P   (x)
                                   2/3

   ‘orthopoly’ supports translation into TeX; it also does
two-dimensional output on a terminal.

     (%i1) spherical_harmonic (l, m, theta, phi);
                               m
     (%o1)                    Y (theta, phi)
                               l
     (%i2) tex (%);
     $$Y_{l}^{m}\left(\vartheta,\varphi\right)$$
     (%o2)                         false
     (%i3) jacobi_p (n, a, a - b, x/2);
                               (a, a - b) x
     (%o3)                    P          (-)
                               n          2
     (%i4) tex (%);
     $$P_{n}^{\left(a,a-b\right)}\left({{x}\over{2}}\right)$$
     (%o4)                         false

64.1.2 Limitations
------------------

When an expression involves several orthogonal polynomials with symbolic
orders, it’s possible that the expression actually vanishes, yet Maxima
is unable to simplify it to zero.  If you divide by such a quantity,
you’ll be in trouble.  For example, the following expression vanishes
for integers <n> greater than 1, yet Maxima is unable to simplify it to
zero.

     (%i1) (2*n - 1) * legendre_p (n - 1, x) * x - n * legendre_p (n, x)
           + (1 - n) * legendre_p (n - 2, x);
     (%o1)  (2 n - 1) P     (x) x - n P (x) + (1 - n) P     (x)
                       n - 1           n               n - 2

   For a specific <n>, we can reduce the expression to zero.

     (%i2) ev (% ,n = 10, ratsimp);
     (%o2)                           0

   Generally, the polynomial form of an orthogonal polynomial is
ill-suited for floating point evaluation.  Here’s an example.

     (%i1) p : jacobi_p (100, 2, 3, x)$

     (%i2) subst (0.2, x, p);
     (%o2)                3.4442767023833592E+35
     (%i3) jacobi_p (100, 2, 3, 0.2);
     (%o3)  interval(0.18413609135169, 6.8990300925815987E-12)
     (%i4) float(jacobi_p (100, 2, 3, 2/10));
     (%o4)                   0.18413609135169

   The true value is about 0.184; this calculation suffers from extreme
subtractive cancellation error.  Expanding the polynomial and then
evaluating, gives a better result.
     (%i5) p : expand(p)$
     (%i6) subst (0.2, x, p);
     (%o6) 0.18413609766122982

   This isn’t a general rule; expanding the polynomial does not always
result in an expression that is better suited for numerical evaluation.
By far, the best way to do numerical evaluation is to make one or more
of the function arguments floating point numbers.  By doing that,
specialized floating point algorithms are used for evaluation.

   Maxima’s ‘float’ function is somewhat indiscriminate; if you apply
‘float’ to an expression involving an orthogonal polynomial with a
symbolic degree or order parameter, these parameters may be converted
into floats; after that, the expression will not evaluate fully.
Consider

     (%i1) assoc_legendre_p (n, 1, x);
                                    1
     (%o1)                         P (x)
                                    n
     (%i2) float (%);
                                   1.0
     (%o2)                        P   (x)
                                   n
     (%i3) ev (%, n=2, x=0.9);
                                  1.0
     (%o3)                       P   (0.9)
                                  2

   The expression in (%o3) will not evaluate to a float; ‘orthopoly’
doesn’t recognize floating point values where it requires an integer.
Similarly, numerical evaluation of the ‘pochhammer’ function for orders
that exceed ‘pochhammer_max_index’ can be troublesome; consider

     (%i1) x :  pochhammer (1, 10), pochhammer_max_index : 5;
     (%o1)                         (1)
                                      10

   Applying ‘float’ doesn’t evaluate <x> to a float

     (%i2) float (x);
     (%o2)                       (1.0)
                                      10.0

   To evaluate <x> to a float, you’ll need to bind
‘pochhammer_max_index’ to 11 or greater and apply ‘float’ to <x>.

     (%i3) float (x), pochhammer_max_index : 11;
     (%o3)                       3628800.0

   The default value of ‘pochhammer_max_index’ is 100; change its value
after loading ‘orthopoly’.

   Finally, be aware that reference books vary on the definitions of the
orthogonal polynomials; we’ve generally used the conventions of
Abramowitz and Stegun.

   Before you suspect a bug in orthopoly, check some special cases to
determine if your definitions match those used by ‘orthopoly’.
Definitions often differ by a normalization; occasionally, authors use
“shifted” versions of the functions that makes the family orthogonal on
an interval other than (-1, 1).  To define, for example, a Legendre
polynomial that is orthogonal on (0, 1), define

     (%i1) shifted_legendre_p (n, x) := legendre_p (n, 2*x - 1)$

     (%i2) shifted_legendre_p (2, rat (x));
                                 2
     (%o2)/R/                 6 x  - 6 x + 1
     (%i3) legendre_p (2, rat (x));
                                    2
                                 3 x  - 1
     (%o3)/R/                    --------
                                    2

64.1.3 Floating point Evaluation
--------------------------------

Most functions in ‘orthopoly’ use a running error analysis to estimate
the error in floating point evaluation; the exceptions are the spherical
Bessel functions and the associated Legendre polynomials of the second
kind.  For numerical evaluation, the spherical Bessel functions call
SLATEC functions.  No specialized method is used for numerical
evaluation of the associated Legendre polynomials of the second kind.

   The running error analysis ignores errors that are second or higher
order in the machine epsilon (also known as unit roundoff).  It also
ignores a few other errors.  It’s possible (although unlikely) that the
actual error exceeds the estimate.

   Intervals have the form ‘interval (<c>, <r>)’, where <c> is the
center of the interval and <r> is its radius.  The center of an interval
can be a complex number, and the radius is always a positive real
number.

   Here is an example.

     (%i1) fpprec : 50$

     (%i2) y0 : jacobi_p (100, 2, 3, 0.2);
     (%o2) interval(0.1841360913516871, 6.8990300925815987E-12)
     (%i3) y1 : bfloat (jacobi_p (100, 2, 3, 1/5));
     (%o3) 1.8413609135168563091370224958913493690868904463668b-1

   Let’s test that the actual error is smaller than the error estimate

     (%i4) is (abs (part (y0, 1) - y1) < part (y0, 2));
     (%o4)                         true

   Indeed, for this example the error estimate is an upper bound for the
true error.

   Maxima does not support arithmetic on intervals.

     (%i1) legendre_p (7, 0.1) + legendre_p (8, 0.1);
     (%o1) interval(0.18032072148437508, 3.1477135311021797E-15)
             + interval(- 0.19949294375000004, 3.3769353084291579E-15)

   A user could define arithmetic operators that do interval math.  To
define interval addition, we can define

     (%i1) infix ("@+")$

     (%i2) "@+"(x,y) := interval (part (x, 1) + part (y, 1), part (x, 2)
           + part (y, 2))$

     (%i3) legendre_p (7, 0.1) @+ legendre_p (8, 0.1);
     (%o3) interval(- 0.019172222265624955, 6.5246488395313372E-15)

   The special floating point routines get called when the arguments are
complex.  For example,

     (%i1) legendre_p (10, 2 + 3.0*%i);
     (%o1) interval(- 3.876378825E+7 %i - 6.0787748E+7,
                                                1.2089173052721777E-6)

   Let’s compare this to the true value.

     (%i1) float (expand (legendre_p (10, 2 + 3*%i)));
     (%o1)          - 3.876378825E+7 %i - 6.0787748E+7

   Additionally, when the arguments are big floats, the special floating
point routines get called; however, the big floats are converted into
double floats and the final result is a double.

     (%i1) ultraspherical (150, 0.5b0, 0.9b0);
     (%o1) interval(- 0.043009481257265, 3.3750051301228864E-14)

64.1.4 Graphics and ‘orthopoly’
-------------------------------

To plot expressions that involve the orthogonal polynomials, you must do
two things:
  1. Set the option variable ‘orthopoly_returns_intervals’ to ‘false’,
  2. Quote any calls to ‘orthopoly’ functions.
   If function calls aren’t quoted, Maxima evaluates them to polynomials
before plotting; consequently, the specialized floating point code
doesn’t get called.  Here is an example of how to plot an expression
that involves a Legendre polynomial.

     (%i1) plot2d ('(legendre_p (5, x)), [x, 0, 1]),
                             orthopoly_returns_intervals : false;
     (%o1)


   (Figure orthopoly1: Plot of the Legrende polynomial of order 5)

   The entire expression ‘legendre_p (5, x)’ is quoted; this is
different than just quoting the function name using ‘'legendre_p (5,
<x>)’.

64.1.5 Miscellaneous Functions
------------------------------

The ‘orthopoly’ package defines the Pochhammer symbol and a unit step
function.  ‘orthopoly’ uses the Kronecker delta function and the unit
step function in ‘gradef’ statements.

   To convert Pochhammer symbols into quotients of gamma functions, use
‘makegamma’.

     (%i1) makegamma (pochhammer (x, n));
                               gamma(x + n)
     (%o1)                     ------------
                                 gamma(x)
     (%i2) makegamma (pochhammer (1/2, 1/2));
                                     1
     (%o2)                       ---------
                                 sqrt(%pi)

   Derivatives of the Pochhammer symbol are given in terms of the ‘psi’
function.

     (%i1) diff (pochhammer (x, n), x);
     (%o1)             (x)  (psi (x + n) - psi (x))
                          n     0             0
     (%i2) diff (pochhammer (x, n), n);
     (%o2)                   (x)  psi (x + n)
                                n    0

   You need to be careful with the expression in (%o1); the difference
of the ‘psi’ functions has polynomials when ‘<x> = -1, -2, .., -<n>’.
These polynomials cancel with factors in ‘pochhammer (<x>, <n>)’ making
the derivative a degree ‘<n> - 1’ polynomial when <n> is a positive
integer.

   The Pochhammer symbol is defined for negative orders through its
representation as a quotient of gamma functions.  Consider

     (%i1) q : makegamma (pochhammer (x, n));
                               gamma(x + n)
     (%o1)                     ------------
                                 gamma(x)
     (%i2) sublis ([x=11/3, n= -6], q);
                                    729
     (%o2)                        - ----
                                    2240

   Alternatively, we can get this result directly.

     (%i1) pochhammer (11/3, -6);
                                    729
     (%o1)                        - ----
                                    2240

   The unit step function is left-continuous; thus

     (%i1) [unit_step (-1/10), unit_step (0), unit_step (1/10)];
     (%o1)                       [0, 0, 1]

   If you need a unit step function that is neither left or right
continuous at zero, define your own using ‘signum’; for example,

     (%i1) xunit_step (x) := (1 + signum (x))/2$

     (%i2) [xunit_step (-1/10), xunit_step (0), xunit_step (1/10)];
                                     1
     (%o2)                       [0, -, 1]
                                     2

   Do not redefine ‘unit_step’ itself; some code in ‘orthopoly’ requires
that the unit step function be left-continuous.

64.1.6 Algorithms
-----------------

Generally, ‘orthopoly’ does symbolic evaluation by using a hypergeometic
representation of the orthogonal polynomials.  The hypergeometic
functions are evaluated using the (undocumented) functions ‘hypergeo11’
and ‘hypergeo21’.  The exceptions are the half-integer Bessel functions
and the associated Legendre function of the second kind.  The
half-integer Bessel functions are evaluated using an explicit
representation, and the associated Legendre function of the second kind
is evaluated using recursion.

   For floating point evaluation, we again convert most functions into a
hypergeometic form; we evaluate the hypergeometic functions using
forward recursion.  Again, the exceptions are the half-integer Bessel
functions and the associated Legendre function of the second kind.
Numerically, the half-integer Bessel functions are evaluated using the
SLATEC code.

