4 @c OriginalRevision=1.33
5 @c TranslatedBy: (c) 2007-06 Vadim V. Zhytnikov <vvzhyt@gmail.com>
8 * Введение в программирование на Maxima::
9 * Функции и переменные для программирования на Maxima::
12 @node Введение в программирование на Maxima, Функции и переменные для программирования на Maxima, Программы Maxima, Программы Maxima
13 @section Введение в программирование на Maxima
15 Maxima предоставляет цикл @code{do}, для итерации, а также более простые управляющие
16 конструкции, такие как @code{go}.
18 @c end concepts Program Flow
19 @node Функции и переменные для программирования на Maxima, , Введение в программирование на Maxima, Программы Maxima
20 @section Функции и переменные для программирования на Maxima
22 @deffn {Функция} backtrace ()
23 @deffnx {Функция} backtrace (@var{n})
24 Печатает стек вызовов, т.е. список функций, которые
25 вызывают текущую активную функцию.
27 Вызов @code{backtrace()} печатает весь стек вызовов.
29 Вызов @code{backtrace (@var{n})} печатает @var{n} последних
30 функций, включая текущую.
32 @c IS THIS STATMENT REALLY NEEDED ??
33 @c (WHY WOULD ANYONE BELIEVE backtrace CANNOT BE CALLED OUTSIDE A DEBUGGING CONTEXT??)
34 Функция @code{backtrace} может вызываться внутри программы, функции или из интерактивного
35 приглашение а не только из контекста отладки.
41 Вызов @code{backtrace()} печатает весь стек вызовов.
45 (%i2) g(x) := f(x-11)$
47 (%i4) e(x) := (backtrace(), 2*x + 13)$
61 Вызов @code{backtrace (@var{n})} печатает @var{n} последних
62 функций, включая текущую.
65 (%i1) h(x) := (backtrace(1), g(x/7))$
66 (%i2) g(x) := (backtrace(1), f(x-11))$
67 (%i3) f(x) := (backtrace(1), e(x^2))$
68 (%i4) e(x) := (backtrace(1), 2*x + 13)$
80 @opencatbox{Категории:}
85 @deffn {Специальный оператор} do
86 Команда @code{do} используется для выполнения итераций. Т.к. команда @code{do}
87 довольно обща, то она будет описана в двух частях.
88 Сначала будет описана обычная форма, аналогична используемым
89 в нескольких других языках программирования (Fortran, Algol, PL/I и т.д.).
90 Далее будут описаны другие возможности.
92 Существует три формы команды, отличающиеся только условием
97 @code{for @var{variable}: @var{initial_value} step @var{increment}
98 thru @var{limit} do @var{body}}
100 @code{for @var{variable}: @var{initial_value} step @var{increment}
101 while @var{condition} do @var{body}}
103 @code{for @var{variable}: @var{initial_value} step @var{increment}
104 unless @var{condition} do @var{body}}
107 @c UGH. DO WE REALLY NEED TO MENTION THIS??
108 (Как альтернатива, команда @code{step} может быть задана после условия завершения или
111 Параметры @var{initial_value}, @var{increment}, @var{limit} и @var{body}
112 могут быть произвольными выражениями. Если приращение равно 1, то команда
113 "@code{step 1}" может быть опущена.
115 Перед выполнение команды @code{do}, переменной @var{variable}
116 (далее называемой управляющей переменной) присваивается начальное значение @var{initial_value}.
117 Далее: (1) если значение управляющей переменной превышает верхнюю границу,
118 задаваемую @code{thru}, или если условие @code{unless} равно @code{true},
119 или условие @code{while} равно @code{false}, то @code{do} завершается.
120 (2) Вычисляется @var{body}. (3) Приращение добавляется к управляющей переменой.
121 Шаги (1) -- (3) повторяются до выполнения условия завершения.
122 Можно задавать несколько условий завершения. В этом случае команда @code{do}
123 завершается при удовлетворении любого из них.
125 Обычно тест @code{thru} выполняется, когда управляющая переменная становится больше
126 @var{limit}, когда приращение @var{increment} неотрицательно, или, если переменная становится меньше
127 @var{limit}, когда приращение @var{increment} отрицательно.
128 Параметры @var{increment} и @var{limit} могут быть нечисловыми выражениями, если
129 может быть определено их неравенство. Однако, если @var{increment} не является
130 синтаксически отрицательным (например, отрицательным числом) в момент начала выполнения команды @code{do},
131 то Maxima предполагает положительность @var{increment} во время выполнения @code{do}.
132 Если на самом деле @var{increment} окажется неположительным, то @code{do}
133 может не завершиться надлежащим образом.
135 Отметим, что @var{limit}, @var{increment} и условие завершения вычисляются
136 заново для каждой итерации. Таким образом, если какое-либо из этих выражений требует
137 длительного вычисления, но не меняется от итерации к итерации при вычислении
138 @var{body}, то будет более эффективным присвоить их
139 значение переменной до выполнения @code{do} и использовать эту переменную.
141 Значение, обычно возвращаемое командой @code{do}, есть атом @code{done}.
142 Однако, функция @code{return} может быть использована внутри @var{body}
143 для завершения @code{do} и задания возвращаемого значения.
144 Отметим, что вызов @code{return} внутри цикла @code{do}, расположенного в блоке
145 @code{block}, завершает @code{do} а не блок @code{block}.
146 Функция @code{go} не может быть использована для выхода из команды @code{do}
147 в объемлющий блок @code{block}.
149 Управляющая переменная всегда локальна в рамках @code{do}, т.е.
150 эту переменную можно использовать внутри цикла и это не
151 окажет влияния на переменную с тем же именем вне @code{do}.
152 После завершения @code{do}, управляющая переменная остается несвязанной.
155 (%i1) for a:-3 thru 26 step 7 do display(a)$
169 (%i2) for i: 1 while i <= 10 do s: s+i;
175 Отметим, что условие @code{while i <= 10} эквивалентно условию
176 @code{unless i > 10} или условию @code{thru 10}.
180 (%i2) term: exp (sin (x))$
181 (%i3) for p: 1 unless p > 7 do
182 (term: diff (term, x)/p,
183 series: series + subst (x=0, term)*x^p)$
187 (%o4) -- - --- - -- - -- + -- + x + 1
191 что дает 8 членов ряда Тейлора для @code{e^sin(x)}.
195 (%i2) for i: 1 thru 5 do
196 for j: i step -1 thru 1 do
200 (%o3) 5 x + 9 x + 12 x + 14 x + 15 x
202 (%i5) for i: 1 thru 10 do
203 (guess: subst (guess, x, 0.5*(x + 10/x)),
204 if abs (guess^2 - 10) < 0.00005 then return (guess));
205 (%o5) - 3.162280701754386
208 В этом примере вычисляется отрицательный квадратный корень числа 10
209 с использованием метода Ньютона-Рафсона с максимальным числом итераций 10.
210 Если условие сходимости не будет выполнено, то возвращается значение
213 Вместо добавления значения к управляющей переменной возможен
214 другой способ ее изменения на каждом цикле итерации.
215 В этом случае можно использовать @code{next @var{expression}} вместо @code{step @var{increment}}.
216 Что вызывает присваивание управляющей переменной значения @var{expression}
220 (%i6) for count: 2 next 3*count thru 20 do display (count)$
228 @c UGH. DO WE REALLY NEED TO MENTION THIS??
229 Синтаксис @code{for @var{variable} from @var{value} ...do...} может
230 быть использован как альтернатива @code{for @var{variable}: @var{value} ...do...}.
231 Что позволяет располагать @code{from @var{value}} после значений @code{step} или @code{next},
232 или после условия завершения. Если @code{from @var{value}} опущено, то в качестве начального
233 значения предполагается 1.
235 Иногда требуется выполнить итерации без использования управляющей переменной.
236 В этом случае можно задать только условие завершения без команд
237 инициализации и изменения управляющей переменной, как сделано в
238 следующем примере, вычисляющем квадратный корень числа 5 при
239 неточном затравочном значении.
243 (%i2) thru 20 do x: 0.5*(x + 5.0/x)$
245 (%o3) 2.23606797749979
246 (%i4) sqrt(5), numer;
247 (%o4) 2.23606797749979
250 Если необходимо, то можно полностью опустить условия завершения
251 и использовать только @code{do @var{body}}, что вызывает бесконечное
252 вычисление @var{body}. В этом случае для завершения @code{do} следует
253 использовать @code{return}.
256 (%i1) newton (f, x):= ([y, df, dfx], df: diff (f ('x), 'x),
257 do (y: ev(df), x: x - f(x)/y,
258 if abs (f (x)) < 5e-6 then return (x)))$
259 (%i2) sqr (x) := x^2 - 5.0$
260 (%i3) newton (sqr, 1000);
261 (%o3) 2.236068027062195
264 @c DUNNO IF WE NEED THIS LEVEL OF DETAIL; THIS ARTICLE IS GETTING PRETTY LONG
265 (Заметим, что @code{return} вызывает возвращение текущего значения @code{x}
266 в качестве значения @code{do}. Блок @code{block} завершается, и значение @code{do}
267 возвращается в качестве значения блока, т.к. @code{do} является последней командой @code{block}.)
269 В Maxima доступна еще одна форма команды @code{do}. Ее синтаксис:
272 for @var{variable} in @var{list} @var{end_tests} do @var{body}
275 Элементы списка @var{list} (произвольные выражения)
276 последовательно присваиваются переменной @var{variable}
277 Для каждой итерации вычисления @var{body}.
278 Необязательное условие @var{end_tests} может использоваться для завершения @code{do},
279 иначе цикл завершится при исчерпании @var{list} или при выполнении @code{return}
280 внутри @var{body}. (На самом деле, @var{list} может быть любым
281 неатомарным выражением, последовательные части которого будут использованы в итерации.)
284 (%i1) for f in [log, rho, atan] do ldisp(f(1))$
294 @opencatbox{Категории:}
295 @category{Программирование}
299 @deffn {Функция} errcatch (@var{expr_1}, ..., @var{expr_n})
300 Вычисляет одно за другим выражения @var{expr_1}, ..., @var{expr_n}
301 и, если не возникает ошибок, возвращает @code{[@var{expr_n}]} (список).
302 Если при вычислении одного из аргументов возникает ошибка, то
303 @code{errcatch} предотвращает дальнейшее распространение ошибки и возвращает
304 пустой список @code{[]} без дальнейшего вычисления аргументов.
306 Функция @code{errcatch} полезна в пакетных @code{batch} файлах,
307 если ожидается возможное возникновение ошибки, что без
308 перехвата ошибки приводит к завершению @code{batch}.
310 @opencatbox{Категории:}
311 @category{Программирование}
315 @deffn {Функция} error (@var{expr_1}, ..., @var{expr_n})
316 @deffnx {Системная переменная} error
317 Вычисляет и печатает @var{expr_1}, ..., @var{expr_n}, и
318 затем вызывает ошибку, что возвращает управление на верхний
319 уровень Maxima или ближайшему объемлющему @code{errcatch}.
321 Значением переменной @code{error} является список, описывающий ошибку.
322 Первый элемент @code{error} -- строка форматирования,
323 которая объединяет все строки из параметров @var{expr_1}, ..., @var{expr_n},
324 остальные элементы -- есть значения нестроковых аргументов.
326 Функция @code{errormsg()} форматирует и печатает @code{error},
327 что повторяет печать самой последней ошибки.
329 @opencatbox{Категории:}
330 @category{Программирование}
334 @deffn {Функция} errormsg ()
335 Повторяет печать самой последней ошибки.
336 Информация об ошибке содержится в переменной @code{error}, и @code{errormsg}
337 форматирует и печатает ее.
339 @opencatbox{Категории:}
340 @category{Программирование}
345 @c AT LEAST SHOULD LIST VARIANTS HERE
346 @deffn {Специальный оператор} for
347 Используется в циклах. См. @code{do} для описания средств Maxima для
348 организации итераций.
350 @opencatbox{Категории:}
351 @category{Программирование}
355 @deffn {Функция} go (@var{tag})
356 Используется внутри блока @code{block} для передачи управления на команду,
357 помеченную параметром @code{go}. Для пометки команды в блоке, перед ней помещают
358 другую команду в виде атома (метки). Например:
361 block ([x], x:1, loop, x+1, ..., go(loop), ...)
364 Аргументом @code{go} должна быть метка, определенная в том же блоке @code{block}.
365 Нельзя использовать @code{go} для передачи управления на метку в блоке отличном от
366 того, где находится сама команда @code{go}.
368 @opencatbox{Категории:}
369 @category{Программирование}
373 @c NEEDS CLARIFICATION, EXPANSION, EXAMPLES
374 @c THIS ITEM IS IMPORTANT
375 @deffn {Специальный оператор} if
376 Условное вычисление. Существуют различные формы условного выражения @code{if}.
378 @code{if @var{cond_1} then @var{expr_1} else @var{expr_0}}
379 вычисляет и возвращает значение @var{expr_1}, если значение @var{cond_1} равно @code{true},
380 иначе вычисляет и возвращает значение @code{expr_0}.
382 @code{if @var{cond_1} then @var{expr_1} elseif @var{cond_2} then @var{expr_2} elseif ... else @var{expr_0}}
383 вычисляет и возвращает значение @var{expr_k}, если @var{cond_k} равно @code{true}
384 а все предыдущие условия равны @code{false}.
385 Если не одно из условий не равно @code{true}, то вычисляется и возвращается значение @var{expr_0}.
387 Если завершающее @code{else} отсутствует, то в конце подразумевается @code{else false}.
388 Т.е. @code{if @var{cond_1} then @var{expr_1}} эквивалентно
389 @code{if @var{cond_1} then @var{expr_1} else false},
390 а @code{if @var{cond_1} then @var{expr_1} elseif ... elseif @var{cond_n} then @var{expr_n}}
392 @code{if @var{cond_1} then @var{expr_1} elseif ... elseif @var{cond_n} then @var{expr_n} else false}.
394 Альтернативы @var{expr_0}, ..., @var{expr_n} могут быть произвольными выражениями Maxima,
395 включая вложенные @code{if} выражения.
396 Альтернативы не упрощаются и не вычисляются до тех пор пока соответствующее условие
397 не равно @code{true}.
399 Условия @var{cond_1}, ..., @var{cond_n} являются выражениями, которые потенциально или фактически
400 вычисляются в @code{true} или @code{false}.
401 Если значение условия не равно ни @code{true}, ни @code{false}, то
402 поведение @code{if} управляется глобальной переменной @code{prederror}.
403 Если @code{prederror} равна @code{true}, то любое значение условия, отличное от @code{true} или @code{false},
404 считается ошибкой. Иначе, условия, которые не вычисляются в @code{true} или @code{false},
405 считаются допустимыми и результатом вычисления является условное выражение.
407 Вместе с другими элементами, условия могут включать следующие логические операторы
408 и операторы отношения.
410 @c - SEEMS LIKE THIS TABLE WANTS TO BE IN A DISCUSSION OF PREDICATE FUNCTIONS; PRESENT LOCATION IS OK I GUESS
411 @c - REFORMAT THIS TABLE USING TEXINFO MARKUP (MAYBE)
415 меньше < отношение, инфиксный
416 меньше или равно <= отношение, инфиксный
417 равенство (синтаксическое) = отношение, инфиксный
418 отрицание = # отношение, инфиксный
419 равенство (значение) equal отношение, функция
420 отрицане equal notequal отношение, функция
421 больше или равно >= отношение, инфиксный
422 больше > отношение, инфиксный
423 и and логический, инфиксный
424 или or логический, инфиксный
425 нет not логический, префиксный
428 @opencatbox{Категории:}
429 @category{Программирование}
430 @category{Функции предикаты}
434 @c NEEDS CLARIFICATION
435 @c THIS ITEM IS IMPORTANT
436 @deffn {Функция} map (@var{f}, @var{expr_1}, ..., @var{expr_n})
437 Возвращает выражение, с оператором верхнего уровня таким же как у выражений
438 @var{expr_1}, ..., @var{expr_n} но аргументы которого являются результатами
439 применения @var{f} к соответствующим аргументам выражений @var{expr_i}.
440 Здесь, @var{f} -- либо функция @math{n} аргументов, либо @code{lambda}
441 выражение с @math{n} аргументами.
443 Если переменная @code{maperror} равна @code{false}, то @code{map}:
444 (1) остановится на самом коротком выражении @var{expr_i}, если не все @var{expr_i}
445 имеют одинаковую длину; (2) применит @var{f} к [@var{expr_1}, @var{expr_2},...],
446 если не все @var{expr_i} имеют одинаковый тип. Если @code{maperror} равна @code{true},
447 то в оба вышеуказанных случая считаются ошибкой.
449 Одним из применений функции @code{map} является применение какой-либо функции
450 (например, @code{partfrac}) к каждому члену большого выражения вместо применения
451 ее к выражению целиком, что может привести к слишком сложным вычислениям и,
452 как следствие, к нехватке памяти.
454 @c IN THESE EXAMPLES, SPELL OUT WHAT IS THE MAIN OPERATOR
455 @c AND SHOW HOW THE RESULT FOLLOWS FROM THE DESCRIPTION STATED IN THE FIRST PARAGRAPH
457 (%i1) map(f,x+a*y+b*z);
458 (%o1) f(b z) + f(a y) + f(x)
459 (%i2) map(lambda([u],partfrac(u,x)),x+1/(x^3+4*x^2+5*x+2));
461 (%o2) ----- - ----- + -------- + x
464 (%i3) map(ratsimp, x/(x^2+x)+(y^2+y)/y);
468 (%i4) map("=",[a,b],[-0.5,3]);
469 (%o4) [a = - 0.5, b = 3]
474 @opencatbox{Категории:}
475 @category{Применение функций}
479 @deffn {Функция} mapatom (@var{expr})
480 Возвращает @code{true} тогда и только тогда, когда выражение @var{expr} рассматривается map-процедурами
481 как атомарное выражение. К таким "mapatoms" относятся атомы, числа (включая рациональные) и
482 переменные с индексом.
483 @c WHAT ARE "THE MAPPING ROUTINES", AND WHY DO THEY HAVE A SPECIALIZED NOTION OF ATOMS ??
485 @opencatbox{Категории:}
486 @category{Функции предикаты}
490 @c NEEDS CLARIFICATION
491 @defvr {Управляющая переменная} maperror
492 Значение по умолчанию: @code{true}
494 Если переменная @code{maperror} равна @code{false}, то все @code{map} функции, например:
497 map (@var{f}, @var{expr_1}, @var{expr_2}, ...)
500 (1) остановится на самом коротком выражении @var{expr_i}, если не все @var{expr_i}
501 имеют одинаковую длину; (2) применит @var{f} к [@var{expr_1}, @var{expr_2},...],
502 если не все @var{expr_i} имеют одинаковый тип.
504 Если @code{maperror} равна @code{true},
505 то в оба вышеуказанных случая считаются ошибками.
507 @opencatbox{Категории:}
508 @category{Применение функций}
513 @defvr {Управляющая переменная} mapprint
514 Значение по умолчанию: @code{true}
516 Если переменная @code{mapprint} равна @code{true}, то функции
517 @code{map}, @code{mapl} и @code{fullmap} в определенных ситуациях
518 выдают различные сообщения. Включая ситуации, когда @code{map} использует
519 @code{apply} или @code{map} обрезает до самого короткого списка.
521 Если @code{mapprint} равна @code{false}, то данные сообщения подавляются.
523 @opencatbox{Категории:}
524 @category{Применение функций}
528 @c NEEDS CLARIFICATION
529 @deffn {Функция} maplist (@var{f}, @var{expr_1}, ..., @var{expr_n})
530 Возвращает список с @var{f}, примененной к частям выражений
531 @var{expr_1}, ..., @var{expr_n}.
532 @var{f} -- есть имя функции или лямбда-выражение.
534 Функция @code{maplist} отличается от @code{map (@var{f}, @var{expr_1}, ..., @var{expr_n})},
535 которая возвращает выражение с главным оператором, одним для всех выражений @var{expr_i}
536 (за исключеним упрощений и случая, когда @code{map} выполняет @code{apply}).
538 @opencatbox{Категории:}
539 @category{Применение функций}
543 @c NEEDS CLARIFICATION
544 @defvr {Управляющая переменная} prederror
545 Значение по умолчанию: @code{false}
547 Если @code{prederror} равна @code{true}, то ошибка случается всякий раз, как только
548 вычисленное значение предиката команды @code{if} или функции @code{is} отлично от
549 @code{true} или @code{false}.
551 Если @code{false}, то в этом случае возвращается @code{unknown}.
552 Работа с @code{prederror: false} не поддерживается транслированном коде.
553 Однако, @code{maybe} поддерживается в транслированном коде.
555 См. также @code{is} и @code{maybe}.
557 @opencatbox{Категории:}
558 @category{Программирование}
559 @category{Функции предикаты}
563 @deffn {Функция} return (@var{value})
564 Используется для явного выхода из блока, делая @var{value} значением этого блока.
565 См. @code{block} для более детального описания.
567 @opencatbox{Категории:}
568 @category{Программирование}
572 @c NEEDS CLARIFICATION
573 @deffn {Функция} scanmap (@var{f}, @var{expr})
574 @deffnx {Функция} scanmap (@var{f}, @var{expr}, bottomup)
575 Применяет функцию @var{f} к @var{expr} рекурсивно начиная с верхнего уровня и глубже.
576 Это может быть полезно, если, например, требуется полная факторизация:
579 (%i1) exp:(a^2+2*a+1)*y + x^2$
580 (%i2) scanmap(factor,exp);
585 Отметим, что то, как @code{scanmap} применяет данную функцию @code{factor} к подвыражениям
586 @var{expr}, зависит от формы этого выражения. И если дана другая форма @var{expr},
587 то результат @code{scanmap} может быть другим. Так, @code{%o2} не получится,
588 если @code{scanmap} применить к раскрытому варианту @code{exp}:
591 (%i3) scanmap(factor,expand(exp));
593 (%o3) a y + 2 a y + y + x
596 Еще один пример рекурсивного применения @code{scanmap} ко всем подвыражениям,
600 (%i4) expr : u*v^(a*x+b) + c$
601 (%i5) scanmap('f, expr);
602 f(f(f(a) f(x)) + f(b))
603 (%o5) f(f(f(u) f(f(v) )) + f(c))
606 @code{scanmap (@var{f}, @var{expr}, bottomup)} применяет @var{f} к @var{expr} с
607 самого глубокого уровня вверх. Например, для неопределенной функции @code{f},
611 f(a*x+b) -> f(f(a*x)+f(b)) -> f(f(f(a)*f(x))+f(b))
612 scanmap(f,a*x+b,bottomup) -> f(a)*f(x)+f(b)
613 -> f(f(a)*f(x))+f(b) ->
617 В данном случае результат одинаков для обоих вариантов вызова.
619 @opencatbox{Категории:}
620 @category{Применение функций}
624 @deffn {Функция} throw (@var{expr})
625 Вычисляет выражение @var{expr} и "бросает" его значение вверх до ближайшего @code{catch}.
626 Функции @code{throw} и @code{catch} реализуют механизм нелокального возврата.
628 @opencatbox{Категории:}
629 @category{Программирование}
634 @c AT LEAST SHOULD LIST ACCEPTABLE VARIANTS
635 @deffn {Специальный оператор} while
636 @deffnx {Специальный оператор} unless
639 @opencatbox{Категории:}
640 @category{Программирование}
644 @deffn {Функция} outermap (@var{f}, @var{a_1}, ..., @var{a_n})
645 Применяет функцию @var{f} к каждому элементу внешнего произведения
646 @var{a_1} x @var{a_2} ... x @var{a_n}.
648 @var{f} -- есть имя функции с @math{n} аргументами или
649 лямбда-выражение с @math{n} аргументами.
650 Каждый элемент @var{a_k} может быть списком, списком списков, матрицей или любым другим выражением.
652 Значение @code{outermap} является вложенной структурой.
653 Пусть @var{x} является возвращаемым значением.
654 Тогда @var{x} имеет ту же структуру, как первый аргумент (список, список списков или матрица),
655 @code{@var{x}[i_1]...[i_m]} имеет ту же структуру, как второй аргумент (список, список списков или матрица),
656 @code{@var{x}[i_1]...[i_m][j_1]...[j_n]} имеет ту же структуру, как третий аргумент (список, список списков или матрица),
657 и т.д., где @var{m}, @var{n}, ... -- есть число индексов, необходимых для для доступа к элементам
658 каждого из аргументов (один для списка, два для матрицы, еще один для вложенного списка).
659 Аргументы, не являющиеся списками и матрицами, не оказывают влияния на возвращаемое значение.
661 Отметим, что результат @code{outermap} отличается от применения @var{f} ко всем
662 элементам внешнего произведения, возвращаемого @code{cartesian_product}.
663 Функция @code{outermap} сохраняет структуру аргументов в возвращаемом значении, а @code{cartesian_product} нет.
665 Функция @code{outermap} вычисляет свои аргументы.
667 См. также @code{map}, @code{maplist} и @code{apply}.
668 @c CROSS REF OTHER FUNCTIONS HERE ??
672 Простые примеры @code{outermap}.
673 Для прояснения комбинации аргументов, @code{F} оставлена неопределенной.
676 @c outermap (F, [a, b, c], [1, 2, 3]);
677 @c outermap (F, matrix ([a, b], [c, d]), matrix ([1, 2], [3, 4]));
678 @c outermap (F, [a, b], x, matrix ([1, 2], [3, 4]));
679 @c outermap (F, [a, b], matrix ([1, 2]), matrix ([x], [y]));
680 @c outermap ("+", [a, b, c], [1, 2, 3]);
683 (%i1) outermap (F, [a, b, c], [1, 2, 3]);
684 (%o1) [[F(a, 1), F(a, 2), F(a, 3)], [F(b, 1), F(b, 2), F(b, 3)],
685 [F(c, 1), F(c, 2), F(c, 3)]]
686 (%i2) outermap (F, matrix ([a, b], [c, d]), matrix ([1, 2], [3, 4]));
687 [ [ F(a, 1) F(a, 2) ] [ F(b, 1) F(b, 2) ] ]
689 [ [ F(a, 3) F(a, 4) ] [ F(b, 3) F(b, 4) ] ]
691 [ [ F(c, 1) F(c, 2) ] [ F(d, 1) F(d, 2) ] ]
693 [ [ F(c, 3) F(c, 4) ] [ F(d, 3) F(d, 4) ] ]
694 (%i3) outermap (F, [a, b], x, matrix ([1, 2], [3, 4]));
695 [ F(a, x, 1) F(a, x, 2) ] [ F(b, x, 1) F(b, x, 2) ]
697 [ F(a, x, 3) F(a, x, 4) ] [ F(b, x, 3) F(b, x, 4) ]
698 (%i4) outermap (F, [a, b], matrix ([1, 2]), matrix ([x], [y]));
699 [ [ F(a, 1, x) ] [ F(a, 2, x) ] ]
701 [ [ F(a, 1, y) ] [ F(a, 2, y) ] ]
702 [ [ F(b, 1, x) ] [ F(b, 2, x) ] ]
704 [ [ F(b, 1, y) ] [ F(b, 2, y) ] ]
705 (%i5) outermap ("+", [a, b, c], [1, 2, 3]);
706 (%o5) [[a + 1, a + 2, a + 3], [b + 1, b + 2, b + 3],
707 [c + 1, c + 2, c + 3]]
710 Более детальное исследование работы @code{outermap}.
711 Первый, второй и третий аргументы являются матрицей, списком и матрицей соответственно.
712 Возвращаемое значение является матрицей.
713 Каждый элемент этой матрицы есть список, и каждый элемент данного списка -- матрица.
716 @c arg_1 : matrix ([a, b], [c, d]);
718 @c arg_3 : matrix ([xx, yy]);
719 @c xx_0 : outermap (lambda ([x, y, z], x / y + z), arg_1,
721 @c xx_1 : xx_0 [1][1];
722 @c xx_2 : xx_0 [1][1] [1];
723 @c xx_3 : xx_0 [1][1] [1] [1][1];
724 @c [op (arg_1), op (arg_2), op (arg_3)];
725 @c [op (xx_0), op (xx_1), op (xx_2)];
728 (%i1) arg_1 : matrix ([a, b], [c, d]);
732 (%i2) arg_2 : [11, 22];
734 (%i3) arg_3 : matrix ([xx, yy]);
736 (%i4) xx_0 : outermap (lambda ([x, y, z], x / y + z), arg_1,
739 [ [[ xx + -- yy + -- ], [ xx + -- yy + -- ]] ]
740 [ [ 11 11 ] [ 22 22 ] ]
743 [ [[ xx + -- yy + -- ], [ xx + -- yy + -- ]] ]
744 [ [ 11 11 ] [ 22 22 ] ]
746 [ [[ xx + -- yy + -- ], [ xx + -- yy + -- ]] ]
747 [ [ 11 11 ] [ 22 22 ] ]
750 [ [[ xx + -- yy + -- ], [ xx + -- yy + -- ]] ]
751 [ [ 11 11 ] [ 22 22 ] ]
752 (%i5) xx_1 : xx_0 [1][1];
754 (%o5) [[ xx + -- yy + -- ], [ xx + -- yy + -- ]]
756 (%i6) xx_2 : xx_0 [1][1] [1];
758 (%o6) [ xx + -- yy + -- ]
760 (%i7) xx_3 : xx_0 [1][1] [1] [1][1];
764 (%i8) [op (arg_1), op (arg_2), op (arg_3)];
765 (%o8) [matrix, [, matrix]
766 (%i9) [op (xx_0), op (xx_1), op (xx_2)];
767 (%o9) [matrix, [, matrix]
770 Функция @code{outermap} сохраняет структуру аргументов в возвращаемом значении, а @code{cartesian_product} нет.
773 @c outermap (F, [a, b, c], [1, 2, 3]);
774 @c setify (flatten (%));
775 @c map (lambda ([L], apply (F, L)),
776 @c cartesian_product ({a, b, c}, {1, 2, 3}));
777 @c is (equal (%, %th (2)));
780 (%i1) outermap (F, [a, b, c], [1, 2, 3]);
781 (%o1) [[F(a, 1), F(a, 2), F(a, 3)], [F(b, 1), F(b, 2), F(b, 3)],
782 [F(c, 1), F(c, 2), F(c, 3)]]
783 (%i2) setify (flatten (%));
784 (%o2) @{F(a, 1), F(a, 2), F(a, 3), F(b, 1), F(b, 2), F(b, 3),
785 F(c, 1), F(c, 2), F(c, 3)@}
786 (%i3) map (lambda ([L], apply (F, L)),
787 @c cartesian_product (@{a, b, c@}, @{1, 2, 3@}));
788 (%o3) @{F(a, 1), F(a, 2), F(a, 3), F(b, 1), F(b, 2), F(b, 3),
789 F(c, 1), F(c, 2), F(c, 3)@}
790 (%i4) is (equal (%, %th (2)));
794 @opencatbox{Категории:}
795 @category{Применение функций}