Next: , Previous: Множества, Up: Множества   [Contents][Index]

36.1 Введение в работу с множествами

Maxima предоставляет функции, такие как пересечение или объединение, для работы с конечными множествами, определяемыми перечислением элементов. Maxima трактует списки и множества как различные объекты. Это позволяет работать с множествами, элементами которых сами могут быть списками или множествами.

В дополнение к функциям для работы конечными множествами Maxima определяет некоторые функции, относящиеся к комбинаторике, что включает: числа Стирлинга первого и второго рода, числа Белла, мультиномиальные коэффициенты, разбиения неотрицательных целых чисел и некоторые другие. Maxima также определяет дельта-функцию Кронекера.

36.1.1 Использование

Для того, чтобы задать множество с элементами a_1, ..., a_n, следует написать set(a_1, ..., a_n) или {a_1, ..., a_n}; для пустого множества надо написать set() или {}. При вводе формы set(...) и { ... } эквивалентны. При выводе множества всегда печатаются с фигурными скобками.

Если элемент множества присутствует более одного раза, то упрощение удалит повторяющиеся элементы.

(%i1) set();
(%o1)                          {}
(%i2) set(a, b, a);
(%o2)                        {a, b}
(%i3) set(a, set(b));
(%o3)                       {a, {b}}
(%i4) set(a, [b]);
(%o4)                       {a, [b]}
(%i5) {};
(%o5)                          {}
(%i6) {a, b, a};
(%o6)                        {a, b}
(%i7) {a, {b}};
(%o7)                       {a, {b}}
(%i8) {a, [b]};
(%o8)                       {a, [b]}

Два элемента x и y являются повторяющимися (т.е. рассматриваются совпадающими с точки зрения включения в множество), тогда и только тогда, когда is(x = y) дает true. Заметим, что is(equal(x, y)) может давать true, тогда как is(x = y) дает false. В этом случае элементы x и y считаются различными.

(%i1) x: a/c + b/c;
                              b   a
(%o1)                         - + -
                              c   c
(%i2) y: a/c + b/c;
                              b   a
(%o2)                         - + -
                              c   c
(%i3) z: (a + b)/c;
                              b + a
(%o3)                         -----
                                c
(%i4) is (x = y);
(%o4)                         true
(%i5) is (y = z);
(%o5)                         false
(%i6) is (equal (y, z));
(%o6)                         true
(%i7) y - z;
                           b + a   b   a
(%o7)                    - ----- + - + -
                             c     c   c
(%i8) ratsimp (%);
(%o8)                           0
(%i9) {x, y, z};
                          b + a  b   a
(%o9)                    {-----, - + -}
                            c    c   c

Для того, чтобы создать множество из элементов списка, используется setify.

(%i1) setify ([b, a]);
(%o1)                        {a, b}

Элементы множества x и y равны если is(x = y) вычисляется в true. Тогда rat(x) и x являются равными элементами множества, и, следовательно

(%i1) {x, rat(x)};
(%o1)                          {x}

Далее, поскольку is((x - 1)*(x + 1) = x^2 - 1) вычисляется в false, то (x - 1)*(x + 1) и x^2 - 1 есть различные элементы, и

(%i1) {(x - 1)*(x + 1), x^2 - 1};
                                       2
(%o1)               {(x - 1) (x + 1), x  - 1}

Для приведения этого множества к одноэлементному следует применить rat к каждому элементу:

(%i1) {(x - 1)*(x + 1), x^2 - 1};
                                       2
(%o1)               {(x - 1) (x + 1), x  - 1}
(%i2) map (rat, %);
                              2
(%o2)/R/                    {x  - 1}

Для удаления повторов из множеств другого вида может потребоваться применение других упрощающих функций. Вот пример, использующий trigsimp:

(%i1) {1, cos(x)^2 + sin(x)^2};
                            2         2
(%o1)                {1, sin (x) + cos (x)}
(%i2) map (trigsimp, %);
(%o2)                          {1}

Множество является упрощенным, если его элементы не повторяются и упорядочены. Текущая реализация Maxima функций для работы с множествами использует функцию orderlessp для упорядочения, однако будущие версии могут использовать другую упорядочивающую функцию.

Некоторые операции над множествами, такие как подстановки, вызывают автоматическое упрощение. Например,

(%i1) s: {a, b, c}$
(%i2) subst (c=a, s);
(%o2)                        {a, b}
(%i3) subst ([a=x, b=x, c=x], s);
(%o3)                          {x}
(%i4) map (lambda ([x], x^2), set (-1, 0, 1));
(%o4)                        {0, 1}

Maxima рассматривает списки и множества как различные объекты; функции, подобные union и intersection, сигнализируют об ошибке если их аргументы не являются множествами. Если необходимо применить функцию для работы с множествами к списку, то надо сначала использовать setify для преобразования списка в множество. Таким образом

(%i1) union ([1, 2], {a, b});
Function union expects a set, instead found [1,2]
 -- an error.  Quitting.  To debug this try debugmode(true);
(%i2) union (setify ([1, 2]), {a, b});
(%o2)                     {1, 2, a, b}

Для того, чтобы получить все элементы множества s, удовлетворяющие предикату f, используйте subset(s, f) (предикат – функция, дающая логическое значение). Например, чтобы найти в заданном множестве уравнения, которые не зависят от переменной z, используйте

(%i1) subset ({x + y + z, x - y + 4, x + y - 5},
                                    lambda ([e], freeof (z, e)));
(%o1)               {- y + x + 4, y + x - 5}

Раздел Функции и переменные для работы с множествами содержит полный список функций Maxima, предназначенных для работы с множествами.

36.1.2 Итерация по элементам множества

Существует два способа организации цикла по элементам множества. Один способ – использовать map, например:

(%i1) map (f, {a, b, c});
(%o1)                  {f(a), f(b), f(c)}

Другой способ – использовать for x in s do

(%i1) s: {a, b, c};
(%o1)                       {a, b, c}
(%i2) for si in s do print (concat (si, 1));
a1 
b1 
c1 
(%o2)                         done

Maxima функции first и rest правильно работают с множествами. Примененная к множеству, first возвращает первый элемент множества, какой именно – может зависеть от реализации. Если s является множеством, то rest(s) эквивалентно disjoin(first(s), s). В настоящий момент есть другие функции Maxima, корректно работающие с множествами. В будущих версиях функции first и rest могут работать на множествах иначе или не работать вовсе.

36.1.3 Ошибки

Функции для работы с множествами используют Maxima функцию orderlessp для сортировки элементов множества и Lisp функцию like для проверки равенства элементов. Обе эти функции имеют известные ошибки, которые проявляются при попытке использовать множества, элементы которых являются списками или матрицами, включающими выражения в канонической рациональной форме (КРВ). Например

(%i1) {[x], [rat (x)]};
Maxima encountered a Lisp error:

  The value #:X1440 is not of type LIST.

Automatically continuing.
To reenable the Lisp debugger set *debugger-hook* to nil.

Это выражение вызывает ошибку (сообщение об ошибке зависит от версии Lisp и Maxima). Другой пример

(%i1) setify ([[rat(a)], [rat(b)]]);
Maxima encountered a Lisp error:

  The value #:A1440 is not of type LIST.

Automatically continuing.
To reenable the Lisp debugger set *debugger-hook* to nil.

Эти ошибки вызваны ошибками в orderlessp и like, а не ошибками в реализации функций работы с множествами. Для иллюстрации попробуем следующие выражения

(%i1) orderlessp ([rat(a)], [rat(b)]);
Maxima encountered a Lisp error:

  The value #:B1441 is not of type LIST.

Automatically continuing.
To reenable the Lisp debugger set *debugger-hook* to nil.
(%i2) is ([rat(a)] = [rat(a)]);
(%o2)                         false

До тех пор, пока эти ошибки не исправлены, не следует использовать множества с элементами в виде списков и матриц, содержащих выражения в формате КРВ. Множества, просто содержащие выражения КРВ в качестве элементов, не создают проблем.

(%i1) {x, rat (x)};
(%o1)                          {x}

Maxima функция orderlessp имеет еще одну ошибку, которая может создать проблемы при работе с множествами. А именно, упорядочивающий предикат orderlessp не является транзитивным. Простейший известный пример, демонстрирующий это

(%i1) q: x^2$
(%i2) r: (x + 1)^2$
(%i3) s: x*(x + 2)$
(%i4) orderlessp (q, r);
(%o4)                         true
(%i5) orderlessp (r, s);
(%o5)                         true
(%i6) orderlessp (q, s);
(%o6)                         false

Эта ошибка вызывает проблемы со всеми функциями для работы с множествами и даже с другими функциями Maxima. Возможно, но точно не известно, что эту ошибку можно обойти, если все элементы множества или являются КРВ, или упрощены с помощью ratsimp.

Механизмы Maxima orderless и ordergreat не совместимы с функциями для работы с множествами. Если требуется использовать либо orderless, либо ordergreat, то следует вызывать эти функции до формирования множеств, и не следует использовать unorder.

Если вы встретите что-то, что может быть ошибкой в функциях работы с множествами, пожалуйста, сообщите об этом в базу данных ошибок Maxima. См. bug_report.

36.1.4 Авторы

Функции для работы с множествами Maxima и документация к ним написаны Ставросом Макракисом (Stavros Macrakis of Cambridge, Massachusetts) и Бартоном Уиллисом (Barton Willis of the University of Nebraska at Kearney (UNK)).


Next: , Previous: Множества, Up: Множества   [Contents][Index]