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

Численные методы и программирование с Maxima

Ключевые слова: обмен данными

4.1 Программирование на встроенном макроязыке

4.1.1 Условные операторы

Основная форма условного оператора: if cond_1 then expr_1 else expr_0. Если условие cond_1 истинно, то выполняется выражение expr_1, иначе — выполняется выражение expr_2. Пакет Maxima позволяет использовать различные формы оператора if, например: if cond_1 then expr_1 elseif cond_2 then expr_2 elseif ...else expr_0

Если выполняется условие cond_1, то выполняется выражение expr_1, иначе — проверяется условие cond_2, и если оно истинно — выполняется выражение expr_2, и т.д. Если ни одно из условий не является истинным — выполняется выражение expr_0.

Альтернативные выражения expr_1,exp_r2,... ,expr_k — произвольные выражения Maxima (в т.ч. вложенные операторы if). Условия — действительно или потенциально логические выражения, сводимые к значениям true или false. Способ интерпретации условий зависит от значения флага prederror. Если prederror = true, выдаётся ошибка, если значения какого-либо из выражений cond_1,... ,cond_n отличается от true или false. Если prederror = false и значения какого-либо из выражений cond_1,... ,cond_n отличается от true или false, результат вычисления if — условное выражение.

4.1.2 Операторы цикла

Для выполнения итераций используется оператор textttdo. Могут использоваться три варианта его вызова, отличающиеся условием окончания цикла:

for variable: init_value step increment thru limit do body

for variable: init_value step increment while condition do body

for variable: init_value step increment unless condition do body

Здесь variable — переменная цикла; init_value — начальное значение; increment — шаг (по умолчанию равен 1); limit — конечное значение переменной цикла; body — операторы тела цикла.

Ключевые слова thru, while, unless указывают на способ завершения цикла:

  • по достижении переменной цикла значения limit;
  • пока выполняется условие condition;
  • пока не будет достигнуто условие condition.

Параметры init_value, increment, limit, и body могут быть произвольными выражениями. Контрольная переменная по завершении цикла предполагается положительной (при этом начальное значение может быть и отрицательным). Выражения limit, increment, условия завершения (condition) вычисляются на каждом шаге цикла, поэтому их сложность влияет на время выполнения цикла.

При нормальном завершении цикла возвращаемая величина — атом done. Принудительный выход из цикла осуществляется при помощи оператора return, который может возвращать произвольное значение.

Контрольная переменная цикла — локальная внутри цикла, поэтому её изменение в цикле не влияет на контекст (даже при наличии вне цикла переменной с тем же именем).

Примеры:

(%i1)	for a:-3 thru 26 step 7 do display(a)$
a=-3\\  a=4\\  a=11\\  a=18\\  a=25
(%i2)	s: 0$ for i: 1 while i <= 10 do s: s+i;
done\leqno{(\%o3) }
(%i4)	s;
55\leqno{(\%o4) }
(%i5)	series: 1$ term: exp (sin (x))$
(%i7)	for p:1 unless p > 7 do
	(term: diff (term, x)/p, series: series + subst
	(x=0, term)*x^p)$
(%i8)	series;
\frac{{x}^{7}}{90}-\frac{{x}^{6}}{240}-\frac{{x}^{5}}{15}-\frac{{x}^{4}}{8}
+\frac{{x}^{2}}{2}+x+1\leqno{(\%o8) }
(%i9)	for count: 2 next 3*count thru 20 do display (count)$
count=2\\
count=6\\
count=18

Условия инициализации и завершения цикла можно опускать. Пример (цикл без явного указания переменной цикла):

(%i10)	x:1000;
1000\leqno{(\%o10) }
(%i11)	thru 20 do x: 0.5*(x + 5.0/x)$(%i12) x;
2.23606797749979\leqno{(\%o12) }
(%i12)	float(sqrt(5));
2.23606797749979\leqno{(\%o12) }

За 20 итераций достигается точное значение \sqrt 5.

Несколько более изощрённый пример — реализация метода Ньютона для уравнения с одной неизвестной (вычисляется та же величина — корень из пяти):

(%i1)	newton (f, x):= ([y, df, dfx], df: diff (f ('x), 'x),
	do (y: ev(df), x: x - f(x)/y,
	if abs (f (x)) < 5e-6 then return (x)))
$(%i2)	f(x):=x^2-5;
f\left( x\right) :={x}^{2}-5\leqno{(\%o2) }
(%i3)	float(newton(f,1000));
2.236068027062195\leqno{(\%o3) }

Ещё одна форма оператора цикла характеризуется выбором значений переменной цикла из заданного списка. Синтаксис вызова: for variable in list end_tests do body

Проверка условия завершения end_tests до исчерпания списка list может отсутствовать.

Пример:

(%i1)	a:[];
[\  ]\leqno{(\%o1) }
(%i2)	for f in [1,4,9,16] do a:cons(sqrt(f),a)$
(%i3)	a;
[4,3,2,1]\leqno{(\%o3) }