Компания ALT Linux
Опубликован: 24.03.2015 | Доступ: свободный | Студентов: 550 / 136 | Длительность: 19:00:00
Лекция 2:

Основы Maxima

2.7 Типы данных, переменные и функции

Для хранения результатов промежуточных расчётов применяются переменные. Заметим, что при вводе названий переменных, функций и констант важен регистр букв, так переменные x и X — две разные переменные. Присваивание значения переменной осуществляется с использованием символа : (двоеточие), например x:5. Если необходимо удалить значение переменной (очистить её), то применяется метод kill:

kill(x) — удалить значение переменной x;

kill(all) — удалить значения всех используемых ранее переменных.

Зарезервированные слова, использование которых в качестве имён переменных вызывает синтаксическую ошибку: integrate,\ next,\ from, diff,\ in,\ at,\ limit,\ sum,\ for,\ and,\ elseif,\ then,\ else,\ do,\ or,\ if,\ unless,\ product,\ while,\ thru,\ step.

2.7.1 Списки

Списки — базовые строительные блоки для Maxima и Lisp. Все прочие типы данных (массивы, хэш-таблицы, числа) представляются как списки. Чтобы задать список, достаточно записать его элементы через запятую и ограничить запись квадратными скобками. Список может быть пустым или состоять из одного элемента.

(%i1)	list1:[1,2,3,x,x+y];
[1,2,3,x,y+x]\leqno{(\%o1) }
(%i2)	list2:[];
[]\leqno{(\%o2) }
(%i3)	list3:[3];
[3]\leqno{(\%o3) }

Элементом списка может и другой список

(%i4)	list4:[1,2,[3,4],[5,6,7]];
1,2,[3,4],[5,6,7]]\leqno{(\%o4) }

Ссылка на элемент списка производится по номеру элемента списка:

(%i4)	list4:[1,2,[3,4],[5,6,7]];
[1,2,[3,4],[5,6,7]]\leqno{(\%o4) }
(%i5)	list4[1];
1\leqno{(\%o5) }
(%i6)	list4[3];
[3,4]\leqno{(\%o6) }
(%i7)	list4[3][2];
4\leqno{(\%o7) }
2.7.1.1 Функции для элементарных операций со списками

Функция length возвращает число элементов списка (при этом элементы списка сами могут быть достаточно сложными конструкциями):

(%i8)	length(list4);
4\leqno{(\%o8) }
(%i9)	length(list3);
1\leqno{(\%o9) }

Функция copylist(expr) возвращает копию списка expr:

(%i1)	list1:[1,2,3,x,x+y];
[1,2,3,x,y+x]\leqno{(\%o1) }
(%i2)	list2:copylist(list1);
[1,2,3,x,y+x]\leqno{(\%o2) }

Функция makelist создаёт список, каждый элемент которого генерируется из некоторого выражения. Возможны два варианта вызова этой функции:

  • makelist(expr,i,i_0,i_1) — возвращает список, j-й элемент которого равен ev(expr,i = j), при этом индекс j меняется от i_0 до i_1
  • makelist(expr,x,list) — возвращает список, j-й элемент которого равен ev(expr,x = list[j]), при этом индекс j меняется от 1 до length(list).

Примеры:

(%i1)	makelist(concat(x,i),i,1,6);
[x1,x2,x3,x4,x5,x6]\leqno{(\%o1) }
(%i2)	list:[1,2,3,4,5,6,7];
[1,2,3,4,5,6,7]\leqno{(\%o2) }
(%i3)	makelist(exp(i),i,list);
[e,{e}^{2},{e}^{3},{e}^{4},{e}^{5},{e}^{6},{e}^{7}]\leqno{(\%o3) }

Во многом аналогичные действия выполняет функция

create_list(form,x_1,list_1,... ,x_n,list_n).

Эта функция строит список путём вычисления выражения form, зависящего от x_1, к каждому элементу списка list_1 (аналогично form, зависящая и от x_2, применяется к list_2 и т.д.).

Пример:

(%i1)	create_list(x^i,i,[1,3,7]);
[x,{x}^{3},{x}^{7}]\leqno{(\%o1) }
(%i2)	create_list([i,j],i,[a,b],j,[e,f,h]);
[[a,e],[a,f],[a,h],[b,e],[b,f],[b,h]]\leqno{(\%o2) }

Функция append позволяет склеивать списки. При вызове

append (list_1, \dots, list_n)

возвращается один список, в котором за элементами list_1 следуют элементы list_2 и т.д. вплоть до list_n.

Пример:

(%i1)	append([1],[2,3],[4,5,6,7]);
[1,2,3,4,5,6,7]\leqno{(\%o1) }

Создать новый список, компонуя элементы двух списков поочерёдно в порядке следования, позволяет функция join(l,m). Новый список содержит l_1, затем m_1, затем l_2, m_2 и т.д.

Пример:

(%i1)	join([1,2,3],[10,20,30]);
[1,10,2,20,3,30]\leqno{(\%o1) }

(%i2) join([1,2,3],[10,20,30,40]);

[1,10,2,20,3,30]\leqno{(\%o2) }

Длина полученного списка ограничивается минимальной длиной списков l и m.

Функция cons(expr,list) создаёт новый список, первым элементом которого будет expr, а остальные — элементы списка list. Функция endcons(expr,list) также создаёт новый список, первые элементы которого — элементы списка list, а последний — новый элемент expr.

Пример:

(%i1)	cons(x,[1,2,3]);
[x,1,2,3]\leqno{(\%o1) }
(%i2)	endcons(x,[1,2,3]);
[1,2,3,x]\leqno{(\%o2) }

Функция reverse меняет порядок элементов в списке на обратный

(%i5)	list1:[1,2,3,x];
[1,2,3,x]\leqno{(\%o5) }
(%i6)	list2:reverse(list1);
[x,3,2,1]\leqno{(\%o6) }

Функция member(expr_1,expr_2) возвращает true, если expr_1 является элементом списка expr_2, и false в противном случае.

Пример:

(%i1)	member (8, [8, 8.0, 8b0]);
true\leqno{(\%o1) }
(%i2)	member (8, [8.0, 8b0]);
false\leqno{(\%o2) }
(%i3)	member (b, [[a, b], [b, c]]);
false\leqno{(\%o3) }
(%i4)	member ([b, c], [[a, b], [b, c]]);
true\leqno{(\%o4) }

Функция rest(expr) выделяет остаток после удаления первого элемента списка expr. Можно удалить первые n элементов, используя вызов rest(expr,n). Функция last(expr) выделяет последний элемент списка expr (аналогично first — первый элемент списка).

Примеры:

(%i1)	list1:[1,2,3,4,a,b];
[1,2,3,4,a,b]\leqno{(\%o1) }
(%i2)	rest(list1);
[2,3,4,a,b]\leqno{(\%o2) }
(%i3)	rest(%);
[3,4,a,b]\leqno{(\%o3) }
(%i4)	last(list1);
b\leqno{(\%o4) }
(%i5)	rest(list1,3);
[4,a,b]\leqno{(\%o5) }

Суммирование и перемножение списков (как и прочих выражений) осуществляется функциями sum и product. Функция sum(expr,i,in,ik) суммирует значения выражения expr при изменении индекса i от in до ik. Функция product(expr,i,in,ik)перемножает значения выражения expr при изменении индекса i от in до ik.

Пример:

(%i1)	product (x + i*(i+1)/2, i, 1, 4);
\left( x+1\right) \,\left( x+3\right) \,\left( x+6\right) \,\left( x+10\right) \leqno{(\%o1) }
(%i2)	sum (x + i*(i+1)/2, i, 1, 4);
4\,x+20\leqno{(\%o2) }
(%i3)	product (i^2, i, 1, 4);
576\leqno{(\%o3) }
(%i4)	sum (i^2, i, 1, 4);
30\leqno{(\%o4) }
2.7.1.2 Функции, оперирующие с элементами списков

Функция map(f,expr_1,... ,expr_n) позволяет применить функцию (оператор, символ операции) f к частям выражений expr_1, expr_2,... ,expr_n. При использовании со списками применяет f к каждому элементу списка. Следует обратить внимание, что f — именно имя функции (без указания переменных, от которых она зависит).

Примеры:

(%i1)	map(ratsimp, x/(x^2+x)+(y^2+y)/y);
y+\frac{1}{x+1}+1\leqno{(\%o1) }
(%i2)	map("=",[a,b],[-0.5,3]);
[a=-0.5,b=3]\leqno{(\%o2) }
(%i3)	map(exp,[0,1,2,3,4,5]);
[1,e,{e}^{2},{e}^{3},{e}^{4},{e}^{5}]\leqno{(\%o3) }

Функция f может быть и заданной пользователем, например:

(%i5) f(x):=x^2;
f\left( x\right) :={x}^{2}\leqno{(\%o5) }
(%i6)	map(f,[1,2,3,4,5]);
[1,4,9,16,25]\leqno{(\%o6) }

Функция apply применяет заданную функцию ко всему списку (список становится списком аргументов функции; при вызове (F, [x_1,... ,x_n] вычисляется выражение F(arg_1,... ,arg_n)). Следует учитывать, что apply не распознаёт ординарные функции и функции от массива.

Пример:

(%i1)	L : [1, 5, -10.2, 4, 3];
[1,5,-10.2,4,3]\leqno{(\%o1) }
(%i2)	apply(max,L);
5\leqno{(\%o2) }
(%i3)	apply(min,L);
-10.2\leqno{(\%o3) }

Чтобы найти максимальный или минимальный элемент набора чисел, надо вызвать функции max или min. Однако, обе функции в качестве аргумента ожидают несколько чисел, а не список, составленный из чисел. Применять подобные функции к спискам и позволяет функция apply.