Uploaded by alex2002m

kondratyev sistemy programirovania - maple

advertisement
Министерство РФ по связи и информатизации
ГОУ ВПО ”Сибирский Государственный университет телекоммуникаций и
информатики”
Уральский технический институт связи и информатики (филиал)
В.П. Кондратьев
ЯЗЫКИ
ПРОГРАММИРОВАНИЯ
Система Maple
Часть III. Язык программирования системы
Учебное пособие
Рекомендовано УМО по образованию в области телекоммуникаций
в качестве учебного пособия для студентов,
обучающихся по специальностям
200900 "Сети связи и системы коммутации"
201000 "Многоканальные телекоммуникационные системы"
Екатеринбург, 2006
УДК 621.396.218
ББК 32.884.1
В.П. Кондратьев
ЯЗЫКИ ПРОГРАММИРОВАНИЯ. Система Maple (Часть III. Язык программирования системы). Учебное пособие для студентов заочной и очной форм обучения
специальностей 200900 — Сети связи и системы коммутации, 201000 — Многоканальные телекоммуникационные системы. — Екатеринбург: УрТИСИ ГОУ ВПО "СибГУТИ 2006. — 77 c.
Рецензент: зав. кафедрой прикладной математики Уральского государственного
технического университета - УПИ д.ф.-м.н., профессор А.Н. Сесекин
В первой части пособия были описаны основные конструкции и графические возможности системы Maple. Во второй части эти возможности применялись для решения задач высшей математики внутренними процедурами системы без применения
конструкций языка программирования системы. В настоящей третьей части пособия
описаны основные конструкции языка программирования системы Maple и приводятся процедуры и программы, в которых эти конструкции используются при решении
задач высшей математики. В качестве приложения приведены процедуры решения
задач цифровой обработки сигналов. Кроме того, приведены примеры взаимодействия средств системы Maple с возможностями пакета Excel.
Пособие рекомендуется студентам для самостоятельного изучения системы Maple
с целью применения ее возможностей в процессе обучения.
Библиогр. 9 назв.
Кафедра физики, прикладной
математики и информатики
c Кондратьев В.П., 2006
Часть III
Язык программирования системы
1
1.1
Основные операторы
Описание основных операторов
Основным элементом языков программирования высокого уровня (ПАСКАЛЬ, ФОРТРАН и др.) является оператор. В частности, для языка ПАСКАЛЬ наиболее употребительными являются оператор присваивания, оператор ветвлений (if, case), оператор цикла, оператор процедуры. Результатом выполнения операторов является
изменение данных (переменные, массивы и др.), которые при необходимости можно
отобразить операторами обмена на устройства вывода или сохранить в том или ином
виде в файлах.
Отличительная особенность системы Maple состоит в том, что основным элементом её работы является аналитическое выражение (в силу чего система и является
системой символьной математики). В выражении объекты Maple (числа, переменные, выражения, списки, массивы, множества, последовательности и др.) связываются допустимыми операциями или являются параметрами процедур. Результатом
выполнения команды - выражения является новое выражение, частным случаем которого является численное значение. Поясним команды, приведенные в следующем
пункте параграфа. Введенное выражение a ∗ x + b (строка 1) заканчивается точкой
с запятой, поэтому система после выполнения введенной команды выдает откликрезультат, являющийся тем же самым выражением. В строке 2 переменной b оператором присваивания, о котором скажем чуть ниже, придается значение 2 и снова
вводится прежнее выражение, результат выполнения которого уже учитывает численное значение переменной b. В следующей строке выражение представляет собой
процедуру subs (от англ. substitute) подстановки значения x = 2 в прежнее выражение. Здесь переменная x не меняет (в отличие от b) своего неопределенного
значения, а просто в выражение подставляется указанное значение. В общем случае подстановка выполняет замену одного подвыражения на другое. Напомним, что
выражение-результат может участвовать в дальнейших вычислениях в качестве операнда как ditto− оператор (см. ч. I, п. 1.4.1, [1]), который, к сожалению, учитывает
только результаты выполнения трех предыдущих команд.
Оператор присваивания. Для запоминания результатов вычислений и использования выражений и их значений по именам применяется оператор присваивания,
левая часть которого есть идентификатор, а правая представляет собой выражение:
name := Expression.
Здесь, в отличие от языков программирования, не требуется заранее объявлять типы
данных для их совместимости в операторе присваивания. Переменная левой части
хранит результат-выражение, которое можно использовать указанием имени переменной в других выражениях. Тип результата-выражения можно определить процедурой whattype (строки 4 – 5).
Условный оператор. Разветвляющиеся вычисления реализуются условным оператором и условным выражением. Условный оператор начинается служебным словом
3
if и заканчивается служебными словами end if (или просто end ). В ранних версиях системы оператор завершался служебным словом fi — слово - перевертыш от if.
Краткая форма оператора имеет вид:
if B then E end if,
где B — логическое выражение, E — последовательность операторов и выражений.
Полный условный оператор записывается в виде:
if B then E else F end if,
где F также последовательность операторов и выражений. Если F является, в свою
очередь, условным оператором, то совокупность служебных слов else if заменяется
сокращенной формой elif без завершающего (для F ) служебного слова end if. Логическое выражение строится из арифметических конструкций со знаками сравнения:
<
- меньше;
<= - меньше и равно;
>
- больше;
>= - больше и равно;
=
- равно;
<> - не равно,
связанных логическими операциями not, and, or, возвращающими булевские значения true и false.
Условное выражение начинается со служебного слова if, заключенного в обратные апострофы и имеет вид:
‘if ‘(B, E1, E2),
где E1 и E2 выражения (но не операторы), а B, как и выше — логическое выражение.
Примеры условных операторов и выражений приведены в строках 6 – 10 рабочего
листа сеанса. Особо отметим возможность поименования условного выражения идентификатором в операторе присваивания (строка 7) и использования его значения (но
не самой логической конструкции) в дальнейших вычислениях, чего нельзя сделать
с условным оператором (строка 10). В строке 11 приведен пример применения булевской переменной t, которая имеет значение false и использование этой переменной в
кратком условном операторе приводит к пустому отклику.
Операторы цикла. В языках программирования выполнение многократно повторяющихся вычислений реализуется операторами цикла. В Maple имеется несколько видов операторов цикла, общими для которых является заголовок цикла, определяющий возможные значения параметра цикла, и тело цикла, состоящее из последовательности команд (операторов и выражений). Тело цикла заключается между
служебными словами do и end do (в ранних версиях системы синоним — перевертыш
слова do — od). Оператор цикла общего вида охватывает большинство форм операторов, имеющихся в языках программирования, и записывается в виде конструкции:
[f or V AR ] [f rom IN I ] [to F IN ] [by H ] [while B] do BODY end do,
где строчными буквами набраны служебные слова, а конструкциям, набранным заглавными буквами, соответствуют:
4
— параметр цикла, принимающий числовые значения;
— выражения, задающие начальное и, соответственно,
конечное, значение параметра цикла;
H
— выражение, определяющее шаг изменения параметра;
B
— булевское выражение со значениями true и f alse;
BODY
— тело цикла (операторы и выражения).
Квадратными скобками [ ] выделены необязательные элементы. В частности, допустимой является упрощенная форма цикла типа "пока":
V AR
IN I, F IN
while B do BODY end do.
Специальные формы этих операторов можно посмотреть в примерах справки системы Maple. Команды break и next осуществляют немедленный выход из цикла и
переход к следующему шагу цикла, соответственно.
Специфической формой цикла в Maple-языке является конструкция:
[f or N AM E ] [in SEQ ] [while B] do BODY end do,
где SEQ — последовательность аналитических выражений, значения которых принимает параметр цикла N AM E. Последовательность можно задавать явно в виде
множества или списка.
Поясним примеры операторов цикла, приведенные в строках 12 – 22 рабочего
листа сеанса. Команда restart отменяет все назначения, выполненные в первой части сеанса. Примеры в строках 12 – 15 содержат цикл, наиболее близкий циклу
языка БЕЙСИК. Значения выражений, определяющие начало и конец арифметической прогрессии, а также разность прогрессии (шаг цикла) вычисляются при входе
в цикл и не перевычисляются даже при изменении переменных, входящих в выражения IN I, F IN, H. В то же время (строка 16), значение параметра цикла в теле
цикла можно переопределять. Если цикл завершается точкой с запятой (после служебного слова end), то отклики всех команд тела цикла выводятся на рабочий лист
вне зависимости от того, завершаются они сами двоеточием или точкой с запятой,
поэтому целесообразно завершать цикл двоеточием (как в приведенных примерах).
Для вывода промежуточных результатов в теле цикла использован оператор печати,
описанный ниже. Поскольку параметр цикла представляется в виде аналитического
выражения (в данных примерах в виде обыкновенной дроби), а не в виде величины с ограниченным числом разрядов, то цикл выполняется правильно, в отличие от
аналогичного цикла в БЕЙСИКЕ, где конечное значение 15 оказывается вне цикла
в результате вычисления параметра в машинном представлении при округлении последнего разряда:
F OR x = 10 T O 15 ST EP 5/3
P RIN T x
N EXT
Результат выполнения цикла:
10
11.66667
13.33333.
Пример цикла "пока"приведен в строке 17, где вычисляется первое четырехзначное
простое число с помощью функции isprime, генерирующей значение true, если параметр — простое число. Явно не указанный шаг цикла (как и в строке 19) считается
5
равным единице, в чем можно убедиться, включив промежуточный вывод параметра
оператором print, который в примере подавлен с помощью символа клавиатуры #,
являющимся признаком комментария следующей за ним части строки. Специфическая конструкция цикла, где параметр может принимать значения аналитических
выражений, приведена в строках 20 – 21. Пример выхода из цикла по команде break
(строка 22):
— вычисляется наибольшее трехзначное простое число.
Операторы ввода-вывода. Подавление двоеточием откликов команд приводит
к необходимости выводить промежуточные результаты циклов и процедур, а также окончательные результаты вычислений специальными конструкциями. Наиболее
простой возможностью для этого является использование бесформатного оператора
print(L), где L — есть список выражений, в частности — текстовых строк, заключенных в двойные кавычки (строки 13, 17, 19, 21). Вывод результатов с помощью спецификаций формата, взятых из языка C, осуществляет оператор printf (F, L), где L —
список выводимых значений, а F — список спецификаций формата, представляющий
собой текстовую строку. Спецификация формата начинается со знака процента %, за
которым следует указание типа значения (в частности, a — аналитическая форма,
f — фиксированная форма десятичного числа). Друг от друга спецификации отделяются пробелами. Символы, не относящиеся к спецификациям, выводятся "как
есть"(см. примеры в строках 15, 16, 21, 22). При выполнении строки 22 следует обратить внимание на попытку подавить двоеточием вывод оператора printf, который
все равно выполняется. Более подробные сведения о спецификациях формата можно
получить в справке системы.
Работа с файлами. При необходимости использовать информацию, полученную с помощью других пакетов или языков программирования, а также для обратной
передачи данных, используются файлы. Полное описание команд и специфических
возможностей работы с файлами следует брать в справочной системе Maple. Кратко
опишем только наиболее простые и употребительные команды. Чтение информации
из файла реализуется оператором присваивания
R := readdata(N F [, F ] [, C ]).
Параметр N F представляет собой полное имя файла, заданное текстовой строкой с
двойными обратными наклонными чертами, указывающими вложенность каталогов
(см. пример в строке 24). Если файл существует, то он открывается на чтение и закрывается после выполнения команды, в противном случае выдается сообщение об
ошибке. Необязательный (что отражено в синтаксисе команды квадратными скобками) параметр F является списком форматов читаемых столбцов, а каждый формат
может принимать значения integer, f loat, или string, в соответствии с данными в
столбце. Значением формата по умолчанию является f loat. В этом случае читаются
данные только одного первого столбца файла. При чтении нескольких столбцов однотипных данных список состоит только из одного формата, но параметром C следует
указать число столбцов. Результирующая переменная R представляет конструкцию
типа listlist — список списков, каждый подсписок которого содержит данные одной
строки файла. Арифметические значения преобразуются в соответствии с указанным форматом чтения и установленным значением системной переменной Digits и
могут использоваться как элементы двумерного массива с натуральными индексами
(см. строки 23 – 26). Данные для чтения из файла подготовлены нижеследующей
6
программой на языке БЕЙСИК:
OP EN ”c : \temp\tab1.txt” F OR OU T P U T AS #7
P RIN T #7, ”x = ”;
F OR x = 1 T O 2 ST EP 1/2
P RIN T #7, x,
N EXT
P RIN T #7,
P RIN T #7, ”y = ”;
F OR x = 1 T O 2 ST EP 1/2
P RIN T #7, SQR(x),
N EXT
CLOSE #7.
В результате работы программы содержимое файла имеет вид:
x= 1 1.5
2
y= 1 1.224745 1.414214.
Результат выполнения команды readdata представлен на рабочем листе сеанса (строки 23 – 26).
Команда writedata(N F, L [, F ]) записывает данные L (множество, список, вектор, матрица, список списков) в файл, определенный параметром N F в соответствии
со списком форматов F , причем эти параметры имеют тот же смысл, что и одноименные параметры в команде readdata. Если файл с одноименным полным именем
уже существует, то он предварительно очищается (в противном случае файл создается заново), затем открывается на запись. По завершении команды файл автоматически закрывается. Одномерные конструкции записываются в один столбец файла
(каждый элемент с новой строки), двумерным (матрица или список списков) соответствуют строки файла с элементами (строка матрицы или подсписок, соответственно),
разделенными пробелом. Примеры оператора writedata приведены в строках 27 – 30
рабочего листа сеанса, а содержимое файлов имеет следующий вид.
Файл t2.txt :
2
1.2.
Файл t3.txt :
x= 1 1 2
y= 1 1 1.
Файл t4.txt :
1 1.225 2
1 1.2 1.
Таким образом, результаты вычислений, выполненные средствами пакета Maple,
можно прочитать из текстовых файлов (символы в кодировке ASCII) с помощью
соответствующих операторов чтения данных в языках программирования.
1.1.1
>
Примеры основных операторов
restart;with(linalg):
Warning, the protected names norm and trace have been redefined
and unprotected
>
1:a*x+b;
ax + b
7
>
2:b:=7;a*x+b;
b := 7
ax + 7
>
>
>
3:subs(x=2,a*x+b);%%%;x;
2a + 7
ax + 7
x
4:z:=sin(2*alpha);subs(alpha=Pi/3,z);whattype(z);eval(%%);
z := sin(2 α)
2
sin( π)
3
function
1√
3
2
5:R:=seq(x^k,k=1..5);whattype(R);R[3];
R := x, x2 , x3 , x4 , x5
exprseq
x3
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
restart;
6: a := 3; b := 5;
if (a < b) then a;b else x:=b end if;%;x;
a := 3
b := 5
3
5
5
x
7:Z:=‘if‘(a > b,a,b);5*(Pi +Z );
Z := 5
5 π + 25
8:if a>b then
if a<0 then
a:=99
else
x;
end if
else
b:
end if;%;
5
5
9:a:=b;if a<>b then x:=-1 elif (a<0) or
(x=b) then a:=99 else x
end if:%;
a := 5
8
x
>
10:U:=if a=b then a;
Error, reserved word ‘if‘ unexpected
>
11:t:=a>b;evalb(t);if t then Z end if;
t := 5 < 5
false
>
>
>
>
>
restart;
12: A:=10;B:=15;
13:for x from A
B:=2*B; print(x);
end:
A := 10
B := 15
to B+1 by (B-A)/3 do
10
35
3
40
3
15
>
>
>
>
14:B;
240
15: h:=1/3:for x from 1 by h to 2 do
h:=h/2; printf(" h= %a x= %a
\n",h,x):
end:
h= 1/6
x= 1
h= 1/12
x= 4/3
h= 1/24
x= 5/3
h= 1/48
x= 2
>
>
>
16: h:=1/3:for x from 1 by h to 2 do
y:=x; x:=x+1/10; printf(" y= %a x= %a
end:
y= 1
x= 11/10
y= 43/30
x= 23/15
y= 28/15
x= 59/30
>
17:for p from 1000 while not isprime(p) do
#print(p);
end;
>
18:p;isprime(p);
>
>
1009
9
\n",y,x):
>
>
19:from 3 to 5 do print(q);
end:;
true
q
q
q
>
>
>
20:S:={1,z^2,sqrt(2)};
√
S := {1, z 2 , 2}
21:Q:=0;for R in S do Q:=Q+R; print(R);
end:Q;printf("Q=%a",Q):
Q := 0
1
z2
√
2
√
2
1+z + 2
Q=1+z^2+2^(1/2)
>
>
>
>
>
22: for p from 999 by -2 do if isprime(p)
then
printf("наибольшее трехзначное простое число %6.0f",p);
break; end;
end;
наибольшее трехзначное простое число
>
>
>
>
>
>
>
>
>
>
>
997
23: restart;with(linalg):Digits:=2;
Digits := 2
24: T:=readdata("c:\\TEMP\\tab1.txt",
[string,float,float,integer]);
T := [[“x=”, 1., 1.5, 2], [“y=”, 1., 1.2, 1]]
25: T[2,4];T[1,1];
1
“x=”
26: M:=convert(T,matrix);
“x=” 1. 1.5 2
M :=
“y=” 1. 1.2 1
27: writedata("C:\\TEMP\\t2.txt",[M[1,4],M[2,3]]);
28:Digits:=4:namef:="C:\\TEMP\\t3.txt":
writedata(namef,M,[string,integer,integer,float]);
29: M1:=delcols(M,1..1):
M1[1,2]:=sqrt(M1[1,2]):evalm(M1);
1. 1.225 2
1. 1.2 1
30:writedata("C:\\TEMP\\t4.txt",M1);
10
1.2
1.2.1
Процедуры и функции
Функции пользователя
В пакете имеется большое количество встроенных функций, как элементарных, так
и специальных математических, о которых можно узнать командой вызова справки
?inif unction.
Для построения функций пользователя имеется несколько возможностей. Самым
простым вариантом задания функции является ее определение посредством оператора присваивания, где в левой части записано название функции, а в правой —
выражение, задающее способ вычисления значения функции (строка 1 следующего
пункта параграфа). Напомним, что в целях экономии места многие команды примеров работы в системе (в частности, команды построения графиков) завершаются
двоеточием, подавляющим вывод результата на рабочий лист. При самостоятельном
выполнении команд необходимо заменить двоеточие на точку с запятой. Выражение
- отклик на оператор присваивания можно использовать с помощью контекстного
меню, указав правой кнопкой мыши на это выражение. Этой возможностью удобнее всего строить график функции (P lots I 2D − P lot), который выводится на
диапазоне изменения аргумента (−10 .. 10).
Применение такого варианта определения функции для вычислений неудобно, так
как значение аргумента (в нашем случае z = 5 ) необходимо задавать отдельными
командами и нельзя написать математическое выражение f (5). Вызов переменной f
приводит к выводу выражения с формальной подстановкой в него значения переменной z. Для получения численного значения или упрощения полученного результата
можно применить команды evalf и simplif y, соответственно. Если снова
указать
√
правой кнопкой мыши на результат ( в нашем случае это выражение x cos (x)), то
можно видеть, что возможностей преобразования результата уже намного больше.
Выбор варианта отображения графика (как и выше) приводит к построению графика без учета области определения функции x ≥ 0. Здесь эффективнее использовать
команду явного построения графика plot (строка 1.1), которая доступна без подключения библиотеки графических процедур (команда with(plots)).
Способ определения функции оператором присваивания можно применять для
задания неявных функций (строка 2). Имя переменной можно использовать в логических выражениях(строка 2.1). Построение на плоскости множества точек (линия),
удовлетворяющих равенству, реализует процедура implicitplot, библиотеки plots. Команда в такой форме (строка 2.2) загружает в память только вызываемую процедуру,
в отличие от команды with(plots), где в память загружаются все процедуры библиотеки. Отметим, что переменные x, y должны быть освобождены от сделанных
назначений и иметь тип symbol (строка 2.2). Здесь, как и в первом варианте задания
функции, формальное указание аргумента в определении функции (g(t), строка 3) не
приводит к желаемому результату: команда g(2) не вычисляет значение функции в
точке 2, следовательно, такая конструкция не может использоваться как процедурафункция.
Простой вариант процедурного определения функции представляется функциональным оператором, который может быть записан ( в простейшем случае одного
отображения, а не списка отображений) в одной из двух форм: либо (строка 4):
(последовательность переменных) -> ( выражение),
либо с помощью команды:
11
unapply( выражение, список переменных).
Функциональный оператор задает отображение совокупности значений переменных
на множество значений, определяемых выражением. В обоих случаях отображения
должны быть поименованы, поскольку в противном случае их невозможно использовать. При наборе первой формы стрелку следует набирать как последовательность
символов − > (минус больше). Так, отображение x − > x3 + a, поименованное как F
(строка 4), используется далее для вычисления значения F (2), причем переменная a
играет роль параметра, а значение аргумента 2 подставляется в выражение, но сама
переменная x не теряет сделанного назначения x := 5, то есть является формальным
параметром процедуры-функции, никак не связанным с переменной x. Во втором
случае переменные списка должны быть свободными, поэтому попытка задать отображение при x = 5 заканчивается неудачей (строка 5). В строке 6 то же самое отображение задается под именем W и используется, как и F , в полном соответствии
с математическим смыслом определения функции. Выполненное затем назначение
переменной x = 5 уже не влияет на значение функции, вычисляемое при значении
фактического параметра 2. При построении графика функции командой plot после
имени функции параметр можно не указывать. С помощью функционального оператора можно также определять функции нескольких переменных. Определенные такими способами функции являются объектами системы Maple. Эти функции могут
использоваться при решении уравнений и систем уравнений. К ним можно применять
операции интегрирования, дифференцирования (команды int, dif f, соответственно).
Для построения сложных функций (суперпозиция или, что то же самое, композиция
функций) используются оператор композиции "@"и повторный (кратный оператор
композиции ) "@@"(см. соответствующие справки ?@, ?@@ ).
В случаях, когда значение функции не может быть вычислено единым выражением, в частности, когда требуется проверять некоторые условия (истинность логических выражений), используется специальная конструкция языка Maple — процедура
- функция. Объявление процедуры - функции в этом случае может быть выполнено
в простой форме следующим образом:
N := proc (список формальных параметров)
BODY
end proc,
где последний из операторов тела процедуры (BODY ) генерирует возвращаемое процедурой значение. Вызов процедуры осуществляется оператором:
N (S),
где S — список фактических параметров. Подробнее о процедурах скажем в нижеследующем пункте (1.2.3) параграфа, а здесь приведем пример определения кусочной
функции с помощью процедуры - функции и условного оператора (строка 7). Завершение объявления процедуры точкой с запятой (после служебного слова end proc)
приводит к выводу текста процедуры на внутреннем языке системы. Использование
идентификатора процедуры с подстановкой фактических параметров взамен формальных по синтаксису вполне согласуется с математическим смыслом функции.
Попытка вычислить значение функции при неопределенном аргументе p завершается сообщением о невозможности выполнить логическую операцию (p < 0). Выход из
данной ситуации достигается путем заключения имени процедуры в апострофы (см.
ниже пример построения кусочной функции, п. 9.3.2, строка 7). Кроме того, построение графика функции на заданном диапазоне может быть выполнено без указания
12
имени фактического параметра (команда plot строки 7.1 рабочего листа сеанса, вывод которой подавлен двоеточием). Отметим, что для задания кусочных функций в
Maple имеется встроенная функция piecewise, более эффективно реализующая многоуровневый оператор if (строка 8).
1.2.2
>
>
>
Примеры функций
1: restart;
f:=z*cos(z^2);z:=5;f;evalf(f);z:=sqrt(x):f;
1.1: plot(f,x=0..10):
f := z cos(z 2 )
z := 5
5 cos(25)
4.956014060
√
x cos(x)
>
>
>
>
>
>
>
2: G:=x^2+3*y^2-2*x*y=4;
G := x2 + 3 y 2 − 2 x y = 4
2.1:whattype(G);x:=2;y:=1;whattype(x);
if not G then print(‘точка вне линии‘)end;
=
x := 2
y := 1
integer
2.2:x:=’x’:y:=’y’:
plots[implicitplot](G,x=-3..3,y=-2..2,color=black):
x;whattype(x);
x
symbol
3: g(t):=t/(1-t);g(2);t:=2;g(t);subs(t=2,g(t));
t
g(t) :=
1−t
g(2)
t := 2
g(2)
g(2)
>
4: x:=5;F:=(x)->(x^3+a);F(2);F(u);F(x);F(y);
x := 5
F := x → x3 + a
8+a
u3 + a
125 + a
y3 + a
>
5: W:=unapply(x^3+a,x);
Error, (in unapply) variables must be unique and of type name
13
>
>
>
>
6: x:=’x’:W:=unapply(x^3+a,x);
W := x → x3 + a
6.1: W(2);x:=5;W(2);a:=-1;plot(W):
8+a
x := 5
8+a
a := −1
7: w:=proc(x) if x<0 then -x elif (x>0)
and (x<4) then x else -x+8 fi end;
w := proc(x) if x < 0 then − x elif 0 < x and x < 4 then x
else − x + 8 end if end proc
>
7.1: w(1);x;t:=6;w(t);w(p);t:=’t’;plot(w, -2..5):
1
5
t := 6
2
Error, (in w) cannot evaluate boolean: p < 0
>
t := t
8: y:=proc(t) z:=piecewise(t<0,-t,t<4,t,-t+8);end proc:
Warning, ‘z‘ is implicitly declared local to procedure ‘y‘
>
1.2.3
8.1: diff(y(t),t):plot(y(t),t=-2..5):
Процедуры
Процедуры играют особую роль в языках программирования. Алгоритм, реализующий решение некоторой задачи и запрограммированный в виде процедуры, может
многократно использоваться в других программах. Основная роль при взаимодействии процедуры и вызывающего её оператора программы принадлежит механизму
взаимодействия формальных и фактических параметров.
Определение процедуры в Maple имеет следующий синтаксис:
N := proc([список формальных параметров])
[local список локальных переменных;]
[global список глобальных переменных;]
[options список режимов;]
[description строка описания;]
BODY
end proc,
где N — имя процедуры. Необязательные конструкции заключены в квадратные
скобки и даже список формальных параметров может быть пустым, но круглые скобки в заголовке процедуры должны присутствовать. Тело процедуры BODY представляет собой последовательность операторов, последний выполненный из которых
14
генерирует значение - результат, который может быть любым объектом Maple - системы. Этот оператор лексикографически не обязан быть последним в теле процедуры. Вычисления можно прервать и выполнить выход из процедуры оператором
RET U RN (S), где S —последовательность возвращаемых значений. Таким образом, в Maple нет четкого разграничения процедур на процедуры - функции и просто
процедуры. Процедуры пользователя на Maple - языке по способу реализации представляют собой процедуры - функции, возвращающие значение - результат. Вызов
процедуры осуществляется конструкцией
N (список фактических параметров),
генерирующей значение - результат, который может затем использоваться в соответствии с типом возвращаемого значения.
В списках имена переменных разделяются запятой. Переменную V списка формальных параметров можно специфицировать указанием типа V ::< тип>. При вызове процедуры проверяются на совпадение типа вычисленные значения фактических параметров, соответствующих специфицированным формальным параметрам.
Это позволяет избежать ошибок и неверных результатов в период выполнения процедуры. Если тип не указан, то фактический параметр может иметь при разных
вызовах процедуры различный тип, который можно проверить булевской функцией type(V, t), (где t — имя типа) и по результату организовать разветвление алгоритма. В отличие от языка программирования ПАСКАЛЬ, где копия фактического параметра может модифицироваться не влияя на значение оригинала, в Maple
формальному параметру, имеющему значение (то есть не имеющему тип symbol),
нельзя присвоить новое значение (строка 1 рабочего листа, след. пункт). При вызове процедуры выдается сообщение об ошибке. Следовательно, такие параметры
схожи с параметрами - константами языка ПАСКАЛЬ. Так, при первом вызове процедуры (строка 1) фактический параметр x является свободной переменной, то есть
его значением в процедуре будет имя переменной. Процедура возвращает результат
выполнения последнего оператора — число 5, а фактический параметр x получает
это значение. Очередной вызов процедуры завершается ошибкой, поскольку оригинал, соответствующий формальному параметру, имеет значение. Это ограничение
вызвано спецификой символьных вычислений. Так, например, переменную x можно
переопределять операторами присваивания, но если переменная уже имеет значение
(то есть не является переменной типа symbol), то ее имя нельзя использовать как аргумент при определении функции. Предварительно следует освободить переменную
от назначения, заключив ее имя в апострофы.
Если входной параметр используется для передачи данных из процедуры (аналог параметра, вызываемого по адресу — спецификация var в заголовке процедуры
языка ПАСКАЛЬ), то формальный параметр в Maple необходимо специфицировать
описанием <:: evaln > (строка 2), а соответствующий ему фактический параметр
должен быть переменной, в противном случае выдается сообщение об ошибке (строка 3, оператор B(1, 2). Опишем подробнее действия, выполняемые системой в этом
примере. Формальный параметр a вызывается "по адресу но его изменение a := −1
никак не отображается оператором print, поскольку такой параметр вычисляется
до первого уровня, которым является имя фактического параметра x. В то же время, параметр b вызывается значением 2, которое подставляется вместо формального
параметра. Значение фактического параметра a (первоначального или модифицированного) становится доступным при обращении к функции eval (оператор print и
15
оператор z := eval(a + b).
Локальные переменные создаются на время выполнения процедуры и доступны
только внутри процедуры. Если переменная не объявлена локальной или глобальной, то система сама определяет ее статус как локальной переменной по правилам:
– переменная появляется в левой части оператора присваивания;
– переменная является параметром цикла или индексной переменной
в операторах работы с последовательностями (типа seq).
Если ни одно из этих правил не применимо к переменной, то она считается глобальной. Имена формальных параметров не должны совпадать с именами локальных и
глобальных переменных. Изменение глобальных переменных (несмотря на нежелательный в языках программирования побочный эффект) является еще одним механизмом передачи данных из процедуры. Для глобальных переменных действует правило полного вычисления значения, а локальные переменные вычисляются только до
первого уровня, то есть до имен переменных, входящих в выражения. Поясним это на
примере, приведенном в строке 2. Оператор y := a + z присваивает локальной переменной y значение суммы формального параметра a (его значение на первом уровне
— имя переменной x) и локальной переменной z, которой не присвоено пока никакого
значения, следовательно, ее значение — тоже ее имя z, что и видно по возвращаемому оператором RET U RN значению x + z переменной y. В то же время, глобальная
переменная G вычисляется до окончательного значения G = y = a + z = 0, то есть
учитывает присваивание переменной z значения eval(a + b) = 1, выполненного даже
позже оператора присваивания G := y (заметим, что эта специфика языка Maple в
некоторой степени противоречит принципам программирования).
Приведем примеры процедур, иллюстрирующих некоторые возможности аналитических вычислений в Maple с применением графики.
Строка 4.1 содержит объявление процедуры, которая соответствует тригонометрическому полиному степени n:
n
X
ktπ
1
ktπ
(ak cos(
) + bk sin(
)),
Tn (t) = a0 +
2
L
L
k=1
имеющему период 2L. Если для произвольной функции, заданной на отрезке [−L,
построить коэффициенты Фурье
Z
1 L
f(t) dt,
a0 =
L −L
Z
1 L
ktπ
f(t) cos(
) dt,
ak =
L −L
L
Z
1 L
ktπ
bk =
f(t) sin(
) dt,
L −L
L
(1)
L],
(2)
(3)
(4)
то полином Tn (t) как конечная сумма ряда Фурье будет приближенно представлять
(аппроксимировать) функцию на заданном отрезке. Параметрами процедуры являются:
n
— степень полинома;
t
— аргумент, который может быть числом или переменной;
L
— величина полупериода;
a, b — массивы коэффициентов полинома.
16
Объявление локальными переменных z, k предупреждает вывод сообщения о том,
что система сама объявит их локальными. Встроенная функция sum суммирует выражения в диапазоне изменения индексов k = 1, . . . , n. Возвращаемым значением
является значение локальной переменной z, в которой вычислена сумма по формуле
(1). Вывод в конце процедуры подавлен двоеточием и текст процедуры на внутреннем
языке не выводится. Формальные параметры a, b не специфицируются как массивы
(:: array), поэтому контроля соответствия формальных и фактических параметров
для них при вызове процедуры не производится. Для полного понимания этих пояснений рекомендуется поэкспериментировать с набором текста процедуры: заменить
двоеточие за служебным словом end proc на точку с запятой; удалить объявление локальных переменных; добавить спецификации массивов (:: array) и выполнять при
этом каждый раз оператор строки 4.2. В нашем случае вызов процедуры (строка
4.2) с единственным определенным фактическим параметром π = 3.14 . . . приводит
к выводу аналитического выражения, где все переменные не имеют значений и являются просто символами. Тем не менее, полученное выражение можно использовать
для дальнейших преобразований с помощью ditto− оператора, или присвоить значение выражения переменной, или воспользоваться контекстным меню (правая кнопка
мыши на формуле - результате).
Зададим конкретные значения коэффициентов полинома, определив массивы p и
q с нулевыми начальными значениями (строка 4.3) как элементами последовательности S0. Оператором присваивания зададим величины коэффициентов первой и десятой гармоник (строка 4.4). Теперь при вызове процедуры T rig с соответствующими
параметрами откликом на введенную команду является аналитическое выражение полином cos(t) + 0.2 sin(10 t). Если вызвать процедуру при фиксированном значении
аргумента t, то вычислится значение полинома в этой точке, что и показывает оператор построения графика полинома на отрезке длины периода (строка 4.6). Процедура
T rig, являясь первым параметром команды построения графика, представляет собой в этом виде процедуру - функцию вычисления полинома в точках диапазона
изменения аргумента t, который остается свободным после выполнения процедуры.
Режимы построения графика полинома, заданные опциями процедуры plot, рекомендуется модифицировать, обратившись к соответствующим разделам справки системы. Следующий пример (строки 4.7 – 4.8) определяет тригонометрический полином
степени 2 периода 2 (L = 1 — полупериод) со свободными коэффициентами (массивы
r и s, элементы которых можно задать операторами присваивания).
Приведем пример процедуры (строка 5), вычисляющей коэффициенты Фурье для
функции f (t) по формулам (2 – 4). Параметрами процедуры F ourier являются величина полупериода L и имя процедуры - функции f , соответственно. В системе имеются команды, которые называются командами отложенного действия (в частности,
Sum, Int, Limit). Их имена начинаются с заглавной буквы и при вызове такой команды она выполняется, но возвращает не конечный результат, а соответствующую
математическую запись действия. Конечный результат можно получить операцией
вызова значения value(%), которое также не обязано быть численным значением, а
может представлять собой аналитическое выражение. Интегралы в формулах (2 – 4)
вычисляются командой отложенного действия Int и их значения назначаются глобальным переменным A и B, а значение коэффициента a0 , назначенное локальной
переменной a0, является возвращаемым значением процедуры. В строке 5.1 задана
кусочная функция ψ(x), которую будем рассматривать как периодическую с пери17
одом 2 (L = 1 — полупериод), заданную на отрезке [-1, 1] и продолженную периодически на всю вещественную ось. Отметим, что переменную z система определяет
сама как локальную (строка – отклик на введенную команду). Построение графика функции выполняет команда plot (строка 5.2), результат выполнения которой
присваивается графической структуре Ris1, а вывод команды подавлен двоеточием. Если команду завершить точкой с запятой, то результат выполнения команды
будет выведен в виде оператора на языке Open GL, где будут участвовать списки координат отображаемых точек, режимы отображения и опции команды plot. В
строке 5.2 вызывается процедура F ourier, которая генерирует коэффициент a0 (2)
тригонометрического полинома (1) и вычисляет глобальные переменные A и B как
аналитические выражения коэффициентов Фурье (3) – (4). Эти выражения можно
использовать по имени переменных в дальнейших вычислениях. Некоторые другие
графические возможности системы и примеры применения процедуры построения
коэффициентов Фурье для целей цифровой обработки периодических сигналов, в
частности, построения спектральных характеристик таких сигналов, приведены в
приложении.
1.2.4
>
>
>
>
Примеры процедур
restart;
1: A:=proc(t) t:=5;
end proc;
A := proc(t) t := 5 end proc
A(x);x;A(x);
5
5
Error, (in A) illegal use of a formal parameter
>
>
>
>
>
>
2: B:=proc(a::evaln,b) local y,z; global
G; a:=-1; print(a,b,eval(a));
y:=a+z;
G:=y; z:=eval(a+b); RETURN(y,z);
end:
3: x:=1;B(x,2);x;G;B(1,2);
x := 1
x, 2, −1
x + z, 1
−1
0
Error, illegal use of an object as a name
>
>
>
>
>
>
restart;with(plots):
4.1: Trig:=proc(n,t,L,a,b) local z,k;
z:=sum(a[k]*cos(k*t*Pi/L)+b[k]*sin(k*t*Pi/L),k=1..n);
z:=a[0]/2+z;
end proc:
4.2: Trig(m,x,Pi,A,B);
18
m
X
1
A0 + (
(Ak cos(k x) + Bk sin(k x)))
2
k=1
>
>
>
>
>
>
>
>
>
4.3:
n:=10;S0:=seq(0,j=1..n+1):p:=array(0..n,[S0]):
q:=array(0..n,[S0]):
n := 10
4.4: p[1]:=1;q[10]:=0.2;
p1 := 1
q10 := .2
4.5: Trig(n,t,Pi,p,q);
cos(t) + .2 sin(10 t)
4.6:
plot(Trig(n,t,Pi,p,q),t=0..2*Pi,color=black,
labels=[x,T],labeldirections=[HORIZONTAL,VERTICAL],
xtickmarks=[0,1,3,6]);
T
1
0.5
0
1
3
x
6
–0.5
–1
>
>
4.7: m:=2;r:=array(0..m):s:=array(0..m);
m := 2
s := array(0..2, [])
4.8: Trig(m,x,1,r,s);
1
r0 + r1 cos(x π) + s1 sin(x π) + r2 cos(2 x π) + s2 sin(2 x π)
2
19
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1.3
1.3.1
5: Fourier:=proc(L,f) local a0,ak,bk;
global A,B;
a0:=1/L*Int(f(t),t=-L..L):
ak:=1/L*Int(f(t)*cos(Pi*k*t/L),t=-L..L);
bk:=1/L*Int(f(t)*sin(Pi*k*t/L),t=-L..L);
A:=value(ak);
B:=value(bk);
value(a0);
end proc:
5.1: psi:=proc(t)
z:=piecewise(t<0,0,t);
end proc;
φ := proc(t) local z; z := piecewise(t < 0, 0, t) end proc
5.2: Ris1:=plot(phi(x),x=-1..1,thickness=2,color=blue):
5.3: a0:=Fourier(1,phi);A;B;
1
a0 :=
2
cos(π k) − 1 + π k sin(π k)
π2 k2
−sin(π k) + cos(π k) π k
−
π2 k2
Кусочные функции
Построение кусочных функций
При исследовании характеристик электрических цепей используются кусочные функции, имеющие вид прямоугольных, пилообразных, треугольных и др. импульсов.
Приведем примеры процедур, позволяющих строить периодические функции таких
видов. Импульс будем задавать нормированной финитной (заданной на конечном
отрезке) функцией f (t) на отрезке единичной длины с единичной максимальной амплитудой. Преобразованиями масштаба временной оси, сдвигом начальной точки и
умножением на коэффициент масштабирования и сдвигом по оси амплитуды можно
получить из такой функции большое разнообразие функций.
Зададим прямоугольный единичный импульс условным оператором (строка 1).
Процедура, реализующая вычисление с помощью условного оператора, обладает недостатком, обусловленным спецификой символьных вычислений. Так, если вызвать
процедуру с заданным численным значением фактического параметра (например, командой f 1(0.5)), то процедура возвращает вычисленное значение. Если же обратиться к процедуре с параметром типа symbol, например, командой f 1(a)), то выводится
сообщение об ошибке невыполнимости операции сравнения: cannot evaluate boolean :
a < 0. Аналогичная ошибка будет выдаваться и при попытке построения графика
такой функции. Выходом из такой ситуации является отложенный вызов процедуры, то есть заключение ее имени в апострофы (строка 7). (Рекомендуется выполнить
оператор строки 7 с указанием имени функции f 1(t) без апострофов).
При реализации многоуровневого условия удобнее пользоваться встроенной процедурой piecewise, начальные параметры которой задаются последовательностью
пар B, E, где B — первичное логическое выражение, заданное в виде неравенства, а
20
E — выражение для вычисления значения функции при истинности B (строка 4 —
отклик на введенную команду f 2(x)). Интервалы следует задавать последовательно
в соответствии с их расположением на оси абсцисс (слева направо или справа налево).
Истинность условий проверяется также последовательно в порядке вхождения пар
параметров (то есть слева направо) и при истинности очередного условия остальные
условия не проверяются. Последний параметр является выражением для вычисления функции в случае, если ни одно из условий не выполнилось. Математическая
форма определения такой функции, как правило, записывается с условиями в виде
двойных неравенств, определяющих интервалы звеньев функции, и, следовательно,
могут задаваться без упорядоченного расположения на оси:

0
∞<x<0



2 x
0 ≤ x < 0.5
f (x) =

2 − 2 x 0.5 ≤ x ≤ 1



0
1<x<∞
В строках 3, 5, 6 определены процедуры, задающие треугольные и пилообразные
финитные функции. Графики этих импульсов строятся командами в строках 7 – 10.
При этом, для построения функции f 1(t) ее имя следует заключить в апострофы.
В строке 11 строится процедура, выполняющая периодическое продолжение на
всю ось импульса f длительностью τ со сдвигом начала импульса в точку t0 , и периодом T . Вызов процедуры P eriod(t, t0, τ, T, f ) в случае функции f 1, заданной условным оператором, выполняется как и в случае условного оператора, то есть заключением в апострофы имени процедуры P eriod. В строках 12 – 17 строятся графики
периодических функций с помощью процедуры P eriod, демонстрирующие разные
способы задания параметров, определяющих длительность, начальный сдвиг и уровень амплитуды сигналов. Построение графиков на рабочем листе не приводится.
Рекомендуется выполнить эти команды самостоятельно и разобраться со смыслом
параметров.
1.3.2
>
>
>
>
Примеры процедур кусочных функций
restart;with(plots):
1: f1:=proc(t) if t<0 then 0 elif t<=1 then 1
else 0 end if;end:
2: f1(0.5);f1(a);
1
Error, (in f1) cannot evaluate boolean: a < 0
3: f2:= proc(t) local z ;
z:=piecewise(t<0,0,t<1/2,2*t,t<=1,2-2*t,0); evalf(z);end:
>
4: f2(x);
>

0.



2. x
f (x) =

2. − 2. x



0.
21
x < 0.
x < .5
x ≤ 1.
otherwise
>
>
>
>
>
>
>
>
5: f3:= proc(t) local z ;
z:=piecewise(t<0,0,t<1/4,4*t,t<=3/4,2-4*t,t<1,-4+4*t,0);
evalf(z);end:
6: f4:=proc(t) local z
;z:=piecewise(t<0,0,t<=1,2*t-1,0);
evalf(z);end:
7: plot(’f1’(x/(1/2),Pi),x=-Pi..Pi,thickness=3,
color=brown);
1
0.8
0.6
0.4
0.2
–3
>
–2
–1
0
1
x
2
3
8: plot(f2(x/2),x=-1..3,thickness=3,color=brown);
1
0.8
0.6
0.4
0.2
–1
0
1
x
22
2
3
>
9: plot(f3(x),x=-1..2,thickness=3,color=brown);
1
0.5
–1
–0.5
0.5
1
x
1.5
2
–0.5
–1
>
10: plot(f4(x),x=-1..2,thickness=3,color=brown);
1
0.5
–1
–0.5
0.5
1
x
–0.5
–1
>
>
>
>
11: Period:=proc(t,t0,tau,T,f) local x,z;
x:=evalf(t-t0-floor((t-t0)/T)*T);
z:=f(x/tau);evalf(z);
end:
23
1.5
2
>
>
>
>
>
>
>
12: plot(’Period’(x,0,3,5,f1),x=-5..10);
13: plot(’Period’(x,1,3,5,f1),x=-5..10);
14: plot(Period(x,-1,2,4,f2),x=-6..10);
15: plot(’Period’(x,-1,2,3,f3),x=-6..10);
16: plot(’Period’(x,-1,2,3,f4)*3,x=-6..10);
17: plot(’Period’(x,-1,2,3,f1)*2-1,x=-3.5..6,
color=blue,thickness=2);
1
0.5
–2
2
–0.5
–1
24
x
4
6
2
2.1
Системы линейных уравнений
Постановка задачи. Определения
Рассмотрим систему общего вида, состоящую
вестных:

a11 x1 + a12 x2 + . . .



a21 x1 + a22 x2 + . . .

...


am1 x1 + am2 x2 + . . .
из m уравнений относительно n неиз+ a1n xn = b1 ,
+ a2n xn = b2 ,
(5)
+ amn xn = bm .
Система уравнений называется совместной, если можно найти такие значения x1 =
α1 , x2 = α2 , . . . , xn = αn для неизвестных, которые удовлетворяют всем уравнениям
системы. Совокупность этих значений обозначим как упорядоченный набор
x∗ = (α1 , α2 , . . . , αn ).
(6)
Совокупность X ∗ всевозможных наборов этих значений называется решением системы. При отсутствии решения система называется противоречивой или несовместной. В случае единственного набора система называется определенной.
Легко показать, что если решение не единственно, то решений бесконечное множество. Так, например, для любого числа t ∈ R, и для любых двух решений x∗1 , x∗2
их комбинация вида x∗3 = tx∗1 + (1 − t)x∗2 , также является решением (здесь верхние
индексы играют роль номеров). В этом случае система называется неопределенной.
Если коэффициенты правой части системы (свободные члены) всех уравнений
равны нулю b1 = 0, b2 = 0, . . . , bm = 0, то система называется однородной и она
всегда имеет решение x1 = 0, x2 = 0, . . . , xn = 0, которое называется нулевым или
тривиальным.
Используемые на практике методы решения систем линейных алгебраических
уравнений разделяют на точные методы и методы последовательных приближений
(итерационные). Известное правило Крамера для решения определенных (имеющих
единственное решение) систем практически невыгодно, так как требует слишком
большого количества арифметических операций (при m = n > 3). Традиционные
для курса линейной алгебры системы трех уравнений с тремя неизвестными, для
решения которых (вручную) применяется правило Крамера, здесь отдельно не рассматриваются, поскольку их компьютерное решение вполне укладывается в рамки
рассматриваемого ниже метода Гаусса - Жордана. Более того, связанные с такими
системами методы вычисления определителей третьего порядка (в частности, правило Саррюса) неэффективны и при ручных вычислениях приводят к многочисленным
ошибкам даже на модельных примерах с целочисленными коэффициентами.
2.2
Метод полного исключения
Одним из наиболее универсальных и изучаемых в курсе линейной алгебры методов
решения систем линейных уравнений считается метод последовательного исключения неизвестных, называемый методом Гаусса. Этот метод имеет несколько разновидностей. Одна из реализаций метода называется методом Гаусса с обратным ходом
(см., например, [5] и [1, § 3.8, п. 3.8.3]). Применение метода приводит к равносильной
25
системе с треугольной (ступенчатой) матрицей, что в случае бесчисленного множества решений требует значительных затрат на проведение аналитических выкладок обратного хода при построении решения в параметрической форме. Вследствие
этого, целесообразность применения данного варианта метода весьма сомнительна.
Большего внимания заслуживает метод полного исключения, называемый методом
Гаусса-Жордана, суть которого заключается в последовательном исключении неизвестных из уравнений системы и приведении основной матрицы системы к единичной
матрице, в результате чего, на месте столбца свободных коэффициентов расширенной матрицы получается вектор решения. Реализация метода достаточно проста.
Строим таблицу, соответствующую системе (5), в которой свободные коэффициенты остаются в правой части уравнений и записываются в таблицу с исходными
знаками.
x1
a11
...
am1
...
...
...
...
xn
a1n
...
amn
1
b1
...
bm
(7)
На первом шаге выбираем в первом столбце ненулевой элемент. Пусть это элемент a1,1 (в противном случае переставляем строки таблицы), который называется
главным. Делим все элементы строки на этот коэффициент, при этом новый элемент
a∗1,1 станет равным единице. Затем вычитаем последовательно все элементы полученной первой строки, умноженные на величину ai,1 из каждой очередной строки
с номером i. Тем самым, элементы первого столбца (кроме главного элемента) становятся равными нулю. Остальные элементы таблицы, включая столбец свободных
коэффициентов перевычисляются по формуле:
(8)
a∗k,j = ak,j − a∗1,j · ai,1 ,
где элементы, помеченные символом ∗ —это новые элементы таблицы.
На втором шаге выполняем аналогичные действия со вторым столбцом и, выбрав
ненулевой главный элемент в оставшихся строках (снова, пусть это элемент a2,2 ), делим на него все элементы второй (главной) строки. Исключаем с помощью главной
строки элементы второго столбца в остальных строках, включая и первую (превращая их в нулевые) и т.д.. Если столбец, соответствующий исключаемой переменной,
содержит после предыдущих шагов только нулевые элементы, то переставляем его
на место последнего столбца с перенумерацией соответствующих переменных. Не
вдаваясь в подробное рассмотрение последующих вычислений, отметим, что после
числа шагов, равного рангу r исходной матрицы системы, получим таблицу вида:
x1
1
...
0
0
...
0
...
...
...
...
...
...
...
xr
0
...
1
0
...
0
xr+1
c1,r+1
...
cr,r+1
0
...
0
26
...
...
...
...
...
...
...
xn
c1n
...
crn
0
...
0
1
c1
...
cr
cr+1
...
cm
(9)
Анализ полученной таблицы проводим следующим образом. Если среди элементов
столбца свободных коэффициентов cr+1 , cr+2 , . . . , cm есть хоть один элемент, отличный от нуля, система несовместна, поскольку строка с ненулевым свободным
коэффициентом соответствует уравнению вида 0 · x = b.
При совместности системы, в случае r = n, получаем в столбце свободных коэффициентов единственное решение системы:
x1 = c1 , . . . , xn = cn .
В случае r < n записываем уравнения системы, соответствующие полученной таблице:
x1 + c1,r+1 xr+1 + . . . + c1n xn = c1 ,
...
...
...
...
...
xr + cr,r+1 xr+1 + . . . + crn xn = cr ,
(10)
Если разрешить каждое из этих уравнений относительно соответствующих неизвестных x1 , . . . , xr , полагая остальные переменные в правой части уравнений параметрами, можно получить решение системы в параметрической форме.
2.3
Процедура метода Гаусса-Жордана
Приведем процедуру Gauss_Jordan, реализующую метод Гаусса - Жордана и текст
рабочего листа с решением системы (31, ч. II,§ 5.3) с помощью этой процедуры.
Решим систему

x1 − x2 + x3 + x4 + x5 = −1,



 −x1 − x2 + 2x3 + x4
= −4,
− 2x3 − 2x4 − x5 =
2,



 −3x + x
− x4 − 2x5 = −2,
1
2
которой соответствует матрица


1 −1
1
1
1
 −1 −1
2
1
0 

A=
 0
0 −2 −2 −1 
−3
1
0 −1 −2
и вектор правых частей
b = (−1, −4, 2, −2).
Для определенности приведем текст рабочего листа полностью, опуская только
несущественные промежуточные результаты вычислений.
>
>
>
>
>
restart;with(linalg):
m:=4:n:=5:
A:=matrix(m,n,[[1, -1, 1, 1, 1], [-1, -1,
2, 1, 0], [0, 0, -2, -2, -1],
[-3, 1, 0, -1, -2]]);
27


1 −1
1
1
1
 −1 −1
2
1
0 

A := 
 0
0 −2 −2 −1 
−3
1
0 −1 −2
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
b:= vector([-1, -4, 2, -2]);
b := [−1, −4, 2, −2]
Ae:=concat(A,b):
Hstr:=vector(n+2):
for i from 1 to n do
Hstr[i+1]:=x[i];
end do:
Hstr[1]:=‘ ‘:
Hstr[n+2]:=1:
Lcol:=vector(m): for k from 1 to m do
Lcol[k]:=‘ ‘:
end do:
Maketab:=proc() local At;
global Ae,Lcol,Hstr;
At:=Ae; At:=concat(Lcol,At):
At:=stackmatrix(Hstr,At);
print(At);
end proc:
Maketab();


x1 x2 x3 x4 x5
1

1 −1 1
1
1 −1 


 −1 −1 2
1
0 −4 



0
0 −2 −2 −1
2 
−3 1
0 −1 −2 −2
Gauss_Jordan:=proc(A::evaln,k,r)
local i,j,z,zag;
global m,n,Lcol,Hstr;
z:=A[k,r]:
for j to n+1 do
A[k,j]:=A[k,j]/z;
end do;
for i from 1 to m do
if i <> k then
z:=A[i,r];
for j from 1 to n+1 do
A[i,j]:=A[i,j]-A[k,j]*z;
end do;
end if;
end do:
A[k,r]:=1:
print(k,r);
end:
28
SYS_solve:=proc(m,n)
local k,r,i,zag,p,fin,num;
>
global Lcol,Hstr,Ae;
>
k:=1; r:=1; fin:=true;
>
while fin do
>
p:=Ae[k,r];num:=k;
>
for i from k+1 to m do
>
if abs(abs(Ae[i,r]-1))<abs(abs(p)-1) then
>
p:=Ae[i,r]; num:=i;
>
end if;
>
end do;
>
if abs(p)>1e-7 then
>
if num<>k then
>
swaprow(Ae,num,k);
>
end if;
>
Gauss_Jordan(Ae,k,r);
>
Maketab();
>
k:=k+1; r:=r+1;
>
else
>
r:=r+1;
>
end if;
>
if (k>m) or (r>n) then
>
fin:=false;
>
end if;
>
end do;
>
end proc:
>
SYS_solve(m,n):


x1 x2 x3 x4 x5
1



 1 0 0 1 3
1


2 4




1
1

 0 1 0
1


2
4




 0 0 1 1 1 −1 


2


0 0 0 0 0
0
Напомним, что свободные коэффициенты записываются в таблицу с исходными
знаками. Обрабатываемая матрица передается в процедуру Gauss_Jordan и возвращается как результат, поэтому соответствующий формальный параметр A специфицируется как передаваемый по адресу (см. выше описание процедур). Следующая
процедура SY S_solve, как и в предыдущем параграфе, поочередно исключает переменные из уравнений системы, выбирая по столбцу элемент, ближайший к единице.
При вызове процедуры SY S_solve выполняются три шага исключения (равные рангу основной матрицы системы), в результате чего получаем окончательную таблицу.
Система совместна, поскольку свободный коэффициент в оставшейся строке c46 = 0.
Выписав уравнения системы, соответствующие таблице, получим следующие равен>
>
29
ства
1
3
x4 +
x5 = 1,
2
4
1
1
x2 +
x4 +
x5 = 1,
2
4
1
x4 +
x5 = −1,
x3 +
2
которые легко разрешить относительно переменных x1 , x2 , x3 и получить решение
системы в параметрическом виде со свободными переменнными x4 , x5 (сравни решение (32, ч. II, $ 8.3)).
x1 +
3
3.1
Электронные таблицы
Электронные таблицы в Maple
Электронные таблицы, создаваемые и обрабатываемые многими пакетами, имеют
общие свойства и отличаются друг от друга уровнем сервиса (комфортабельностью
работы) и функциональными возможностями, то есть наличием встроенных процедур обработки данных (сравни Excel, QuattroPro и множество других вариантов
электронных таблиц, включая пакеты обработки статистических данных). Главным
свойством электронных таблиц, являющихся двумерными объектами, служит свойство адресации элементов прямоугольной таблицы (матрицы), которое определяется
координатным способом, то есть указанием адреса клетки номерами столбца и строки. Аналогичный подход применяется в электронной таблице пакета Maple. Элементами клетки cell таблицы могут быть любые команды системы Maple, поэтому возможности собственных электронных таблиц Maple гораздо шире аналогичных
возможностей таблиц других пакетов. Уровень сервиса в таблицах Maple уступает
развитым средствам других пакетов.
На рабочий лист таблицу можно вставить двумя способами: с помощью опции меню Insert I Spreadsheet, либо командой пакета Spread — CreateSpreadsheet(name).
В первом случае создается безымянная таблица, имя которой можно затем назначить
опцией P roperties меню Spreadsheet, которое становится доступным при активизации поля таблицы. Таблица имеет 100 строк с номерами 1, . . . , 100 и 52 столбца,
обозначенных буквами A, . . . , Z, AA, . . . , AZ. При добавлении ряда в таблице
(ряд — это строка или столбец) размеры таблицы не меняются, а если последний ряд
заполнен, то он удаляется из таблицы. При удалении ряда удаляется информация
из него, а остальные ряды сдвигаются, меняя адреса. При этом меняются и ссылки на относительные адреса. Команды, соответствующие этим операциям находятся
в меню Spreadsheet, где кроме операций вставки и удаления есть опция изменения
ширины столбца (для Column — W idth) и высоты строки (для Row — Height). Однако, последние манипуляции легче проводить непосредственным применением приема
Drag & Drop.
Ячейки таблицы могут содержать объекты Maple такие как выражения, списки,
множества и некоторые команды системы (но не операторы), которые не обязательно должны заканчиваться в стиле команд Maple, то есть двоеточием или точкой
с запятой. Вводимые выражения отображаются в формульной строке контекстной
панели и там же могут корректироваться. В момент ввода информации активная
ячейка заполняется диагональной штриховкой, а после окончания редактирования
30
(нажатие клавиши Enter, или установка фокуса на другую ячейку) выводится результат выполнения команды в установленном стиле вывода (по умолчанию — в
стиле математической нотации) с автоматическим изменением размера ряда по высоте результата в ячейке. Для численных значений можно установить количество
значащих цифр с помощью опции меню Spreadsheet I P roperties (либо обращением к контекстному меню — правая кнопка мыши на области ячейки). Таким образом, ячейка таблицы, как и в Excel, ассоциируется с выражением (формулой в
стиле Maple) и значением выражения. Если выражение содержит ссылки на переменные, определенные в сеансе до заполнения ячейки, то переменные подставляются своими значениями. Если же выражение содержит неопределенную переменную,
которая впоследствии (в сеансе Maple вне таблицы) задается выражением (или конкретным значением), то для модификации содержимого ячейки с учетом изменений
следует выделить ячейку (или диапазон модифицируемых ячеек) и с помощью опции Spreadsheet I Evaluate Selection перевычислить ее значение. При этом ячейки,
содержащие ссылки на модифицируемую клетку, заштриховываются диагональной
штриховкой. Эти ячейки, в свою очередь, можно так же перевычислить.
Внутри таблицы ссылки на ячейки записываются в виде абсолютных и относительных адресов в стиле Excel, а перед адресом ставится знак тильда ~, например
˜A1, ~$B$2, ~R$77. За пределами таблицы к ее ячейкам можно обращаться с помощью функций пакета Spread (см. ниже список команд, выведенных при подключении пакета), указывая адрес ячейки без знака тильды. Приведем примеры создания
электронных таблиц и поясним некоторые приемы работы с ними.
Подключим пакет Spread (строка 1 рабочего листа) без подавления двоеточием
вывода команды. Выводится список процедур пакета, назначение которых отражено
в названиях, а справка о их синтаксисе выдается единой статьей. В конце статьи приводятся гиперссылки на немногочисленные примеры работы с электронными таблицами, в частности, с правилами ссылок на внутренние относительные и абсолютные
адреса клеток, а также на приемы перевычисления клеток, содержащих ссылки на
внешние переменные сеанса, изменившие свои значения.
> 1: restart;with(Spread);
[CopySelection, CreateSpreadsheet, EvaluateCurrentSelection,
EvaluateSpreadsheet, GetCellFormula, GetCellValue,
GetFormulaeMatrix , GetMaxCols, GetMaxRows,
GetSelection, GetValuesMatrix , InsertMatrixIntoSelection, IsStale,
SetCellFormula, SetMatrix , SetSelection]
>
2: CreateSpreadsheet(sampltab);
Создадим таблицу (строка 2) и ограничим ее размеры четырьмя столбцами и тремя
строками (приемом буксировки правого нижнего угла таблицы). Заполним клетки
таблицы выражениями в соответствии со следующей таблицей и порядком заполнения, описанным ниже:
31
A
B
C
D
1
sin(y)
xˆ2
˜A1ˆ2
dif f (˜$A$1, y)
2
sin(P i/3)
P
b
b
3
[a, 2, r, T ]
{p, q, 5}
sqrt(˜A3[2])
Int(phi(t), t)
Выражения в клетках C1 и D1 содержат, соответственно, ссылки на относительный
и абсолютный адреса ячейки A1. Ячейка A3 заполнена списком, на элемент которого ссылается выражение в ячейке C3. В ячейке B3 задано множество конструкцией
Maple: {p, q, 5}. Ячейка D3 содержит команду интегрирования не заданной функции φ. В сеансе установлен режим ввода в стиле нотации Maple, а режим вывода —
в математической нотации. Однако для электронной таблицы действуют свои режимы, которые (как уже было сказано в начале параграфа) задаются опциями меню
P roperties (см. значения, установленные по умолчанию, а также пояснения к вводу
второй и третьей строк таблицы). Вводимые символы отображаются в формульной
строке контекстной панели инструментов.
При нажати клавиши Enter или активизации другой ячейки результат ввода
отображается в соответствии с правилами обработки и вычисления выражений, описанными в первой части пособия [1,?]. Изменение содержимого клетки приводит к
появлению диагональной штриховки клеток, содержащих ссылки на нее.
Будем заполнять ячейки таблицы в следующей последовательности. Сначала вводим выражения в ячейки B1, C1 и D1, а затем выражение в ячейку A1. В результате
клетки со ссылками на эту ячейку заштриховываются. Статус ячейки в сеансе Maple
(за пределами таблицы) определяется булевской функцией IsStale (см. ниже команду строки 3, которую рекомендуется выполнить для ячеек первой строки и вернуть
курсор в пределы таблицы для заполнения оставшейся ее части).
>
3: IsStale(sampltab,D1);
Перевычисление заштрихованных ячеек выполняется активизацией ячейки (или
выделением диапазона перевычисляемых ячеек) с помощью опции меню Evaluate
Selection. Введем выражения во вторую и третью строки таблицы (последовательно, слева направо). Если значением выражения является число, то форму его вывода
можно определить опцией (контекстного или главного) меню P roperties, установив
режим плавающей запятой или символьный режим. Здесь же можно установить способ выравнивания результата в ячейке (Alignment), цвет поля ячейки, количество
значащих цифр при выводе и число знаков, участвующих в вычислениях (аналог системной константы Digits). Установка режимов производится для выделенной ячейки или выделенного диапазона ячеек. Рекомендуется изучить эти возможности самостоятельно.
Итоговая таблица имеет следующий вид:
32
A
B
C
D
1
sin(y)
x2
sin(y)2
cos(y)
2
1√
3
2
P
b
[a, 2, r, T ]
{5, q, p}
3
√
2
b
Z
φ(t) dt
Ширина столбца и высота строки автоматически подстраиваются под размеры максимального из содержащихся в них элементов. В случае принудительного изменения
размеров (с помощью буксировки разделителей строк или столбцов, или с помощью
опций меню Row I Height, Column I W idth, соответственно) цвет границы ячейки
изменяется с черного на красный, если данные не умещаются в размерах ячейки.
Приведем примеры команд взаимодействия элементов таблицы и объектов сеанса, на которые ссылаются выражения в ячейках таблицы. Значение выражения и
формула, ассоциированные с ячейкой, выводятся соответствующими командами пакета Spread (строки 4 – 5). Изменение выражения в ячейке реализуется процедурой
SetCellF ormula, третьим параметром которой задается явное или поименованное
идентификатором выражение (строка 6). Второй параметр является адресом ячейки
(без знака тильды перед адресом, в отличие от упоминания адреса в выражении P ).
Таким образом, одноименные с адресами ячеек переменные в выражениях и командах сеанса записываются без знака тильды и не конфликтуют с адресами. А запись
адреса без тильды внутри команд пакета Spread также не приводит к конфликту
имен, поскольку здесь имя является ссылкой на ячейку таблицы, а не на одноименную переменную (см. также строку 8 рабочего листа сеанса).
Команда GetSelection (строка 7) выдает координаты ячеек левого верхнего и правого нижнего угла выделенного диапазона таблицы. С диапазоном можно выполнять
обмен информацией с помощью матриц (см. соответствующие справки по командам
пакета Spread).
>
4: GetCellValue(sampltab,C1);
sin(y)2
>
5: GetCellFormula(sampltab,C1);
“~A1^2”
>
6: P:=~A2+ln(x); SetCellFormula(sampltab,B2,P);
P := ˜A2 + ln(x)
>
7: GetSelection(sampltab);
1, 2, 1, 2
Если переопределить значения переменных (строка 8), на которые ссылаются
формулы в ячейках таблицы, то изменить отображаемые значения ячеек можно пересчетом выделенного диапазона ячеек, или всей таблицы (опцией Evaluate Selection,
или Evaluete Spreadsheet, соответственно). Тем не менее, если даже не применять
эту процедуру изменения отображаемых значений в ячейках, эти изменения учитываются при ссылках на ячейки (строки 9 – 13).
33
>
>
8: A1:=x^2;x:=5;b:=-77;
A1 := 25
x := 5
b := −77
9: value(GetCellValue(sampltab,D3));
Z
φ(t) dt
>
10: value(GetCellFormula(sampltab,D3));
“Int(phi(t),t)”
11: phi:=proc(x) x^2*exp(-x);end;
>
φ := proc(x) x2 ∗ exp(−x) end proc
12: value(GetCellValue(sampltab,D3));
>
−t2 e(−t) − 2 t e(−t) − 2 e(−t)
>
13: value(GetCellFormula(sampltab,D3));
“Int(phi(t),t)”
Несомненным достоинством электронных таблиц является автоматический пересчет относительных адресов ячеек в формулах при добавлении или удалении рядов.
Это свойство также присуще и таблицам Spreadsheets в Maple. Однако, механизм
копирования здесь проще. Продемонстрируем это на примере следующей таблицы.
После команды restart вставим на поле рабочего листа таблицу опцией меню
Insert I Spreadsheet, затем заполним первый столбец таблицы выражениями в стиле Maple–нотации (в частности, в ячейке A4 формула имеет вид: xˆalpha). Ячейка
A14 содержит выражение C, играющее роль произвольной постоянной в первообразных от функций первого столбца. В ячейку B2 введем выражение dif f (˜A2, x),
имеющее ссылку на соседнюю ячейку с относительной адресацией. Выделим диапазон B2 : B13, начиная с ячейки B2 и выполним опцию меню F ill I Down. Ячейки ряда заполнятся формулой с модифицированным адресом, имеющем ссылку на
соседнюю ячейку столбца A, а в ячейках отобразятся выражения соответствующих
производных. Аналогично этому, введем в ячейку C2 команду отложенного действия
Int(˜A2, x) и выделив диапазон C2 : C13, заполним ячейки с помощью кнопки F ill
контекстной панели. В ячейках отобразятся выражения неопределенных интегралов
от соответсвующих функций первого столбца. Ячейку D2 заполним выражением
value(˜C2) + ˜$C$14, где ссылку на абсолютный адрес ˜$C$14 при копировании
распространим только на диапазон D2 : D9, в результате получим следующую таблицу:
34
Таблица производных и интегралов основных функций.
A
B
f(x)
∂
∂x
√
x
1 1
√
2 x
xα
xα α
x
a
x
ln(x)
sin(x)
cos(x)
tan(x)
cot(x)
arcsin(x)
arccos(x)
arctan(x)
arccot(x)
f(x)
C
D
Integral
Z
√
x dx
Z
xα dx
Value
Z
x
a ln(a)
ax dx
2 (3/2)
+C
x
3
x(α+1)
+C
α+1
ax
+C
ln(a)
Z
ln(x) dx
x ln(x) − x + C
cos(x)
Z
sin(x) dx
−cos(x) + C
−sin(x)
Z
cos(x) dx
sin(x) + C
Z
tan(x) dx
−ln(cos(x)) + C
Z
cot(x) dx
ln(sin(x)) + C
1
x
2
1 + tan(x)
2
−1 − cot(x)
1
√
1 − x2
1
−√
1 − x2
1
1 + x2
1
−
1 + x2
Z
arcsin(x) dx
x arcsin(x) +
Z
arccos(x) dx
x arccos(x) −
Z
arctan(x) dx
Z
arccot(x) dx
√
1 − x2
√
1 − x2
1
ln(x2 + 1)
2
1
arccot(x) x + ln(x2 + 1)
2
x arctan(x) −
C
3.2
Maple в Excel
Электронную таблицу пакета Excel можно внедрить на поле рабочего листа Maple
как объект, однако эта таблица будет обрабатываться средствами Excel, что не представляет самостоятельного интереса в сеансе Maple. Гораздо больше возможностей
дает использование средств аналитических вычислений внутри электронной таблицы
Excel. Это достигается подключением библиотеки процедур Maple в качестве надстройки в Excel (Maple Excel Add-in), что возможно для версий пакета Microsoft
Office 2000 и выше.
После подключения надстройки появляется новая панель инструментов с соответствующим названием "Maple". Кнопка панели с изображением вопросительного
35
знака вызывает краткую справку по использованию возможностей Maple и по ключевым словам и командам системы Maple. При обращении к Maple начинается сеанс
работы, аналогичный сеансу на рабочем листе Worksheet, то есть переменные, которым назначаются значения, запоминаются и могут использоваться в процессе вычислений по именам. Имена переменных сеанса не конфликтуют с адресами ячеек
и с названиями поименованных ячеек таблицы, поскольку они участвуют в разных
конструкциях. Обращение к Maple осуществляется с помощью вызова функции в
виде Excel-формулы и записывается в двух форматах:
=Maple("LE"),
либо
=Maple("Expr",LR),
где параметры функции LE и Expr обязательно должены заключаться в двойные кавычки. В первом варианте параметром является последовательность команд Maple,
разделенных двоеточием или точкой с запятой (в соответствии с их предназначением подавления или отображения области вывода). Во втором — параметр Expr есть
Maple-команда, ссылающаяся на ячейки листов Excel метками (placeholder) в виде
"&n где после амперсанда указан порядковый номер адреса ячеек (или диапазонов
ячеек) из списка LR.
При наборе команды вводимый текст отображается в строке формул панели инструментов, где при необходимости текст можно отредактировать. Результат выполнения команд Maple отображается в клетке, где была введена формула. В сеансе Maple на рабочем листе область вывода нескольких команд, введенных в одной
строке, является многострочной (результат выполнения каждой команды выводится с новой строки). В Excel в этом случае клетка заполняется текстом из результатов выполнения команд, разделенных видимым символом — квадратом. Для получения многострочного вывода клетку следует отформатировать "с переносом по
словам"(режим "Формат ячейки I выравнивание I переносить по словам").
Заполним клетки листа Excel выражениями и формулами в порядке ввода, описанном ниже, в соответствии со следующей таблицей.
A
B
1
x
sin(x)/x
2
= M aple(”M := [a, x + 2, 7, a2 ]; ; ”)
= M aple(”M [2]; ”)
3
= M aple(”dif f (&1, &2)”; B1; A1; )
= M aple(”S[4]2 /M [1]; ”)
4
= M aple(”simplif y(&1)”; A3)
= M aple(”int(&1, x)”; B3)
5
= M aple(”whattype(&1)”; A4)
= M aple(”int(&1, x)”; B4)
36
Введем выражения в клетки A1 и B1. С точки зрения Excel эти выражения представляют собой строки текста, который и отображается в клетках (формат столбцов
– с выравнием по центру). В сеансе Excel выключен режим отображения формул —
Сервис I Параметры I Вид (на вкладке "Вид"отсутствует флажок в переключателе отображения формул). Введем далее в клетку A2 формулу Excel, полный текст
которой следующий:
=Maple("M:=[a,x+2,7,a^2]; S:={a,x+2,7,a^2};")
При этом подключается сеанс Maple и все выполненные действия с участием Maple
запоминаются и обрабатываются как и в обычном сеансе. В частности, создаются
список M и множество S, которые отображаются в клетке A2 (для нее включена
опция переноса по словам), и к элементам которых можно обращаться в командах
Maple по именам переменных как это показано в командах клеток B2 и B3. Введем
формулы в эти ячейки, обращая внимание на индекс элемента множества S, который должен соответствовать выражению x + 2 (напомним, что элементы множества
система Maple упорядочивает по некоторым внутренним правилам так, что даже
при неоднократном выполнении конструктора множества порядок элементов может
различаться). Затем в клетку A3 вводим формулу, которая обращается к команде
дифференцирования Maple. Параметрами команды указаны выражения в клетках
B1 и A1, ссылки на которые передаются метками (placeholder — см. выше). В клетку A4 вводим выражение = M aple(”simplif y(&1)”; A3), упрощающее вычисленную
в A3 производную. Как и в обычном сеансе Maple, в командах можно использовать
ditto-оператор — вводим команду в ячейку A5 сразу после выполнения предыдущей
команды. Далее, вводим в ячейку B4 формулу = M aple(”int(&1, x)”; B3), вычисляющую неопределенный интеграл от выражения, вычисленного в ячейке B3. После
выполнения команды методом копирования формулы в ячейке (выделить и отбуксировать за угловой маркер на нужное место) заполняем ячейку B5, копией ячейки B4.
При этом автоматически модифицируются ссылки на относительные адреса ячеек,
поскольку они находятся в зоне действия среды Excel, а не в поле команды Maple.
Вид листа Excel после выполнения описанных действий:
37
Достаточно просто выполняется построение графиков средствами Maple на листе
Excel. Для построения диаграммы (графика) в Excel необходимо создать таблицу,
клетки которой содержат данные для графика. Построим график функции f (x) =
sin(x)/x средствами Excel и командой Maple. Приведем вид листа Excel, заполнение
которого опишем ниже.
38
Зададим в первой строке названия столбцов: x и sin(x)/x, соответственно. Заполним столбец A методом автозаполнения сеткой узлов из диапазона −5 . . . 5 с
шагом 0, 5 (напомним, что в русскоязычной версии Excel разделителем между целой
и дробной частями числа является запятая). Далее введем в ячейку B2 формулу
= SIN (A2)/A2, указывая на ячейку A2 там, где нужен ее адрес (отметим, что адреса ячеек при наборе на клавиатуре следует задавать в латинском регистре, поэтому
удобнее показывать на клетку щелчком, а адрес этой клетки Excel записывает в
формулу в требуемом формате). Методом Drag & Drop скопируем формулу в нижние ячейки столбца B, затем построим по вычисленным данным график полученной
табличной функции.
Очевидный недостаток графика — неопределенное значение операции деления на
ноль, которое в таблице отмечено как ошибка вычисления "ДЕЛ/0!". Отметим, что
эта же "ущербность"численной арифметики присуща и системе MathCad, график
функции sin(x)/x в которой выглядит аналогично.
Для построения графика с помощью системы Maple зададим в ячейке C1 формулу
=Maple("plot(&1,x=-5..5,color=blue,thickness=3)";B1),
которая на листе отображается в клетке C1 текстом M aple plot. График функции
выводится на поле листа как объект-рисунок, не обладающий свойствами диаграмм
Excel, и, к сожалению, не являющийся "живым"рисунком Maple, который можно модифицировать. Тем не менее, график функции строится системой Maple корректно,
поскольку адаптивный графический алгоритм учитывает точки разрыва функции и
точки неопределенности, вычисляя сеточные значения функции в точках быстрого
изменения с более мелким шагом, а в точках неопределенности с помощью пределов
слева и справа.
Заполнение параметров команды Maple можно выполнять с помощью удобного
механизма системы Excel — мастера функций, кнопка вызова которого расположена
на панели инструментов Maple (слева от кнопки вызова справки). Построим этим
способом график поверхности z = arctg(x2 y). При вызове мастера функций появляется окно, аналогичное окну справки Maple. Последовательный выбор разделов
Graphics I 3D I plot3d и нажатие кнопки N ext приводит к выводу формы,
поля которой заполним в соответствии с приведенным ниже рисунком. Поскольку
на форме присутствуют не все опции процедуры plot3D, то рисунок, построенный
явной командой
plot3d(arctan(x^2*y),x=-2..2,y=-5..5,
orientation=[-130,45],style=PATCHCONTOUR);
выглядит эффектнее. Рекомендуется эту команду выполнить на листе Excel самостоятельно.
39
Значения полей формы должны заполняться в соответствии с синтаксисом команды Maple. Так, при заполнении полей вместо явного набора значений с клавиатуры
можно указывать на клетки таблицы, но при этом возникают проблемы несоответствия в форме представления вещественных чисел. Целая часть отделяется в Maple,
как и во всех языках программирования, точкой, а в русифицированной версии Excel
— запятой, что будет вызывать сообщение об ошибке при ссылке на ячейку с вещественным значением.
4
4.1
Приложение
Резонансные LCR-контуры
Многие физические процессы, такие как колебание маятника, груз на пружине, поведение тока в электрической цепи с простейшими элементами: катушка индуктивности, сопротивление и конденсатор, а также многие другие физические явления,
моделируются математическим дифференциальным уравнением второго порядка с
постоянными коэффициентами
y 00 + py 0 + qy = f (x),
где коэффициент q соответствует силе, сохраняющей систему в положении равновесия (коэффициент упругости восстанавливающей силы), а коэффициент p соот40
ветствует силе сопротивления среды (коэффициент трения). Функция f (x) в правой
части дифференциального уравнения называется внешним воздействием (возмущающая сила). Независимая переменная x обычно интерпретируется как время.
Как известно, семейство функций, являющихся решениями однородного дифференциального уравнения, определяется корнями соответствующего характеристического уравнения
λ2 + pλ + q = 0,
являющихся, в общем случае, комплексными:
λ = α ± ıβ.
В зависимости от значения величины p, определяющей так называемую степень
демпфирования системы, и значения величины q, определяющей резонансную частоту системы, корни характеристического многочлена могут быть как чисто вещественными, комплексными (пара комплексно сопряженных корней), так и чисто
мнимыми. Нас интересует случай гармонических колебаний (при p = 0 — отсутствует сила сопротивления внешней среды), когда общее решение однородного уравнения
определяется двупараметрическим семейством тригонометрических функций и имеет вид
(11)
Y (x) = C1 cos β x + C2 sin β x,
которое в радиотехнике обычно записывают в виде
Y (x) = A sin(β x + φ0 ).
(12)
Колебания системы в этом случае называются гармоническими, а интегральные кривые представляют собойqсинусоиды с величиной наибольшего отклонения от поло-
жения равновесия A = C12 + C22 , называемой амплитудой колебаний, и начальной
фазой φ0 , определяемой через C1 и C2 как
φ0 = arctan
C1
.
C2
При отсутствии внешнего воздействия (f (x) = 0) единственная интегральная кривая
определяется начальными условиями прохождения кривой через заданную точку с
заданным в ней наклоном касательной (задача Коши), которые обычно задаются в
начальный момент времени x0 = 0:
y(0) = y0 ; y 0 (0) = y1 .
(13)
Если возмущающая внешняя сила является периодической и изменяется по закону a sin ω x причем ее частота ω = β, то есть совпадает с частотой собственных
колебаний системы, то в решении уравнения
y(x) = Y (x) + y ∗ (x)
частное решение y ∗ следует искать в виде
y ∗ (x) = x(M cos β x + N sin β x).
41
Подстановка этого выражения в дифференциальное уравнение
y 00 + β 2 y = a sin β x
дает частное решение синусоидальной формы
a
y ∗ (x) = − x cos β x,
2β
а общее решение y(x) можно записать как
y(x) = Y (x) + y ∗ (x) = A sin(β x + φ0 ) −
a
x cos β x, .
2β
(14)
При возрастании времени x второе слагаемое становится преобладающим и представляет собой колебательный процесс с возрастающей амплитудой колебания и фазой,
π
π
отстающей от фазы возмущающей силы на − (из − cos α = sin(α− )). Это явление,
2
2
имеющее место при совпадении частоты собственных колебаний системы с частотой
колебаний внешней силы, носит название резонанс. Построение решения, удовлетворяющего начальным условиям (13) удобнее (при ручных вычислениях) выполнять в
представлении общего решения в форме (11), поскольку представление (14) требует
решения нелинейной задачи.
Приведем пример сеанса, демонстрирующего явление резонансного решения. В
строках 1 – 2 определяется дифференциальное уравнение и начальные условия в параметрическом виде без конкретизации значений p, q, y0 , y1 , которые впоследствии
можно переопределять и заново решать уравнение. В строках 4 – 5 задаются параметры, соответствующие резонансному решения уравнения (корни характеристического
уравнения чисто мнимые и частота внешней силы совпадает с собственной частотой
колебаний системы).
>
>
restart;with(plots):
1: DifUr:=diff(y(t),t,t)+p*diff(y(t),t)+q*y(t);
2
>
>
∂
∂
DifUr := ( ∂t
2 y(t)) + p ( ∂t y(t)) + q y(t)
2: uslov:=y(0)=y0,D(y)(0)=y1;
uslov := y(0) = y0 , D(y)(0) = y1
3: char:=lambda^2+p*lambda+q=0;
char := λ2 + p λ + q = 0
>
4: p:=0;q:=16;
p := 0
q := 16
>
solve(char,lambda);
4 I, −4 I
>
5: f(t):=3*sin(4*t);
f(t) := 3 sin(4 t)
>
6: y0:=1;y1:=2;
y0 := 1
y1 := 2
42
Общее решение однородного уравнения имеет вид:
>
7: dsolve(DifUr,y(t));
y(t) = _C1 sin(4 t) + _C2 cos(4 t)
Частное решение однородного уравнения, удовлетворяющее начальным
условиям:
>
8: Y:=dsolve({DifUr,uslov},y(t));
1
Y := y(t) = sin(4 t) + cos(4 t)
2
Решение неоднородного уравнения, удовлетворяющее начальным
условиям:
>
9: r:=rhs(dsolve({DifUr=f(t),uslov},y(t)));
19
3
sin(4 t) + cos(4 t) − cos(4 t) t
r :=
32
8
Отметим здесь, что для выделения решения можно применить функцию
$rhs$, либо воспользоваться приемом буксировки результата вычислений в командную строку. Построим график решения и совместные
графики решения и возмущающей силы.
>
10: plot(r,t=0..20,color=blue,thickness=2);
6
4
2
0
–2
2
4
6
8
10
t
12
14
16
18
20
–4
–6
>
11: plot([Y,r,f(t)],t=0..15,thickness=2,color=[black,blue]);
43
4
2
0
2
4
6
t
8
10
12
14
–2
–4
Рекомендуется изменить значения параметров p и q и построить решения дифференциального уравнения, меняя также начальные условия и возмущающую силу.
Например, зададим близкое к нулю значение коэффициента p, которому будет соответствовать малое значения параметра затухания колебаний, и построим график
этого решения, демонстрирующего эффект "биения". Рекомендуется выполнить вычисления этого сеанса для разных вариантов корней характеристического уравнения.
>
12: p:=0.1;
p := .1
>
13: r:=rhs(dsolve({DifUr=f(t),uslov},y(t)));
√
9 √
17 (−1/20 t)
9 √
97 (−1/20 t)
sin(
79 t) 79 +
cos(
e
e
79 t)
1422
20
2
20
15
− cos(4 t)
2
14: plot(r,t=0..50,color=blue,thickness=2);
r :=
>
44
6
4
2
0
10
20
–2
t
30
40
50
–4
–6
>
>
4.2
4.2.1
15: plot([Y,r,f(t)],t=0..10,thickness=2,
color=[black,blue]);
Гармонический анализ дискретных сигналов
Конечные ряды Фурье
Представление функции, заданной на отрезке [−L, L] тригонометрическим полиномом, требует вычисления коэффициентов с помощью определенных интегралов (см.
формулы (1 – 4) §1.2.3)). Для табличной функции, заданной на равномерной сетке
(дискретный сигнал), имеют место аналогичные формулы для вычисления коэффициентов аппроксимирующего тригонометрического полинома вида (1).
Пусть периодический сигнал задан отсчетами y0 , y1 , . . . , yN , снятыми в моменты
T
— шаг дискретизации, а T — период,
времени tj = j ∗ h, j = 0, . . . , N где h =
N
2π
причем y0 = yN . При замене переменной x = t
можно рассматривать сигнал как
T
2π
периодический, заданный на равномерной сетке xj = j , j = 0, . . . , N отрезка
N
[0, 2π], на которой имеет место ортогональность системы функций:
1, cos x, sin x, cos 2x, sin 2x, . . . , cos nx, sin nx.
Будем предполагать, что N ≥ 2n + 1. В этом случае коэффициенты тригонометрического полинома Tn (x) (1) вычисляются по формулам Бесселя (см., например [7]):
2X
a0 =
yj ,
N j=1
N
45
(15)
2X
ak =
yj cos(kxj ),
N j=1
(16)
2X
bk =
yj sin(kxj ),
N j=1
(17)
N
N
Заметим, что по существу замену переменной можно было и не делать, вычисляя
коэффициенты суммированием с синусами и косинусами кратных углов, заданными
2π
в точках j . Коэффициенты в данном случае зависят только от отсчетов сигнаN
ла. В целях экономии времени счета вместо непосредственного вычисления матрицы значений синусов и косинусов, применяют так называемый метод удвоения (см.,
например, [8, §6.4]). В задачах цифровой обработки сигналов применяют алгоритм
быстрого дискретного преобразования Фурье [9].
Тригонометрический полином при N > 2n + 1
n
X
k t 2π
1
k t 2π
) + bk sin(
)),
(ak cos(
Tn (t) = a0 +
2
T
T
k=1
(18)
является полиномом наилучшего среднеквадратического приближения для сеточной
функции, заданной на [0, T ], и имеющим период T . Коэффициенты полинома не
зависят от интервала, на котором определена функция и не зависят (в силу ортогональности базисной системы функций) друг от друга, поэтому их можно вычислить
сразу по максимальной степени (2n+1 = N ), что возможно при нечетном числе узлов
дискретизации, и соответствует (в силу равенства числа условий числу неизвестных)
интерполяционному полиному. Следуя Хеммингу [8], в случае четного числа узлов
(N = 2n) положим bn = 0. Построим процедуру вычисления коэффициентов Фурье
сеточной функции (строка 2 рабочего листа, следующий пункт параграфа). Параметрами процедуры F _Discret являются:
Y
— массив значений отсчетов сигнала y0 , . . . , yN ;
N
— наибольший номер узла сетки;
a, b
— коэффициенты Фурье, являющиеся результатом работы
процедуры, поэтому передающиеся в процедуру со
спецификацией evaln.
Следующая процедура (строка 2) T rig(t, n, T, a, b) служит для вычисления в точке t вещественной оси значения периодического с периодом T тригонометрического
полинома степени n.
Процедура ARR(n, c) (строка 4) предназначена для построения амплитудно - частотной характеристики аппроксимируемого дискретного сигнала. В отличие от аналогичной задачи (§ 3.3.2, ч. II), вместо функции arrow пакета plots используется
функция arrow пакета plottools, имеющая больше возможностей, но имеющая ошибку при выводе командой display стрелки нулевой длины в начале или конце массива
стрелок. Процедура исправляет недостатки этой функции и корректно отображает
46
даже все нулевые значения амплитуд. Параметрами √
процедуры являются — число
элементов n и значения модулей коэффициентов c = a2 + b2 .
В строке 5 процедура Setka(N t, T, F, Y ) вычисляет значения функции F (t) на
сетке узлов tj , j = 0, . . . , N t и формирует массив Y . При этом для разрывных
функций следует дополнительно учитывать условие периодичности сеточной функции, полагая, например, (как в строке 5.1, yN t = y0 ) R[N t] := [x, eval(Y [0])], либо
yN t = (y0 + yN t )/2 — R[N t] := [x, eval(Y [0] + Y [N t])/2].
Процедура Spectr строки 6 подготавливает значения модулей амплитуд и создает
графический объект с графиком фазо - частотной характеристики. В строке 7 задается прямоугольный сигнал единичной амплитуды, длительности 1/2. Далее, в строке
8 задаются число точек дискретизации, степень полинома и величина периода. При
переопределении числа точек следует также перевычислять число коэффициентов,
поскольку эти параметры служат для определения границ массивов коэффициентов
и сеточных значений функции (строка 9).
Для построения коэффициентов Фурье сеточной функции f 3(t) вызывается процедура построения массива дискретных отсчетов (строка 10) и затем процедурой
F _Discret вычисляются коэффициенты (максимально возможное количество, соответствующее интерполяционному полиному). Совместные графики сеточной функции и интерполяционного полинома строятся командами строки 13, где графическая
структура, соответствующая сеточной функции, подготовлена как глобальная переменная процедурой Setka. В строке 15 строится последовательность графиков полиномов степеней кратных восьми, которые затем отображаются командой строки
16 с цветом линий, заданных последовательностью (строка 14). В строках 17 – 19
строятся амплитудно - частотная и фазо - частотная (ее график на рабочем листе не
приводится) характеристики.
При аппроксимации функции, имеющей конечный спектр (строки 20 – 28), замена
нулями коэффициентов при некоторых гармониках представляет собой частотную
фильтрацию (как график полинома степени меньшей 15 — строка 25).
В строках 29 – 37 приведены примеры сигналов нечетного и четного продолжений с использованием уже применявшейся ранее процедуры P eriod (их графики на
рабочем листе не приведены). Команды строк 38 – 43 выполняют вычисление коэффициентов и построение спектральных характеристик сигнала f 4(t), продолженного четным образом, причем аппроксимация проводится стандартным способом на
полном периоде [0, T ], T = 2, без учета свойства bk = 0. Строки 44 – 49 решают
аналогичную задачу для нечетного сигнала. Нечетный сигнал периода T = 1 аппроксимируется командами строк 50 – 56. Приведены только графики некоторых
сигналов и их спектральных характеристик. При самостоятельном выполнении команд рабочего листа эти графики будут выводиться, если их вывод не подавлять
двоеточием в конце команды.
Время вычисления спектральных характеристик при большом числе отсчетов может оказаться также достаточно большим, поэтому в таких случаях целесообразно использовать встроенную процедуру быстрого преобразования Фурье F F T (f ast
F ourier T ransf orm), пример применения которой приведен в строках 57 – 62 рабочего листа сеанса. Параметрами процедуры являются — степень двойки, соответствующая числу отсчетов m, массивы вещественной и мнимой составляющей сигнала.
47
4.2.2
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
Процедуры гармонического анализа
1: restart;with(plots):with(plottools):
2: F_Discret:=proc (Y,N,a,b::evaln)
local n,k,j,p,q,h;
n:=trunc(N/2);
h:=2*Pi/N; for k from 0 to n do
p:=0;q:=0;
for j from 1 to N do
p:=p+evalf(Y[j]*cos(k*j*h));
q:=q+evalf(Y[j]*sin(k*j*h));
end;
a[k]:=2/N*p;b[k]:=2/N*q;
#print(k,a[k],b[k]);
end:
if 2*n=N then b[n]:=0; end;
RETURN(n);
end:;
3: Trig:=proc(t,n,T,a,b) local z,k;
z:=a[0]/2+sum(a[k]*cos(k*t*2*Pi/T)+b[k]*sin(k*t*2*Pi/T),
k=1..n);
end:
4: ARR:=proc(n::integer,c) local
L,H,ma,mi,k::integer,
Sim::array(0..n);
ma:=c[0];mi:=c[0];
L:=line([0,c[0]],[n,c[n]],thickness=2,color=red);
for k from 1 to n do
if c[k]>ma then ma:=c[k];end if;
if c[k]<mi then mi:=c[k];end if;
end do;
H:=ma-mi;
if H=0 then RETURN(L) end;
for k from 0 to n do
if abs(c[k])<H/1000 then
Sim[k]:=ellipse([k,c[k]],0.2,0.01*H,color=blue);
else
Sim[k]:=arrow([k,0],[k,c[k]],0.2,0.2,0,color=black);
end if;
end do;
convert(Sim,list);
end:
5: Setka:=proc(Nt,T,F,Y::array) local
h,j,x,R,RL;
global GrafF;
h:=T/Nt;
for j from 0 to Nt do
x:= evalf(j*h);
Y[j]:= F(x);
R[j]:=[x,eval(Y[j])];
end:
5.1: R[Nt]:=[x,eval(Y[0])];
GrafF:=plot(convert(R,list),0..T,color=brown,
style=point,symbol=circle):
end:
48
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
6:
Spectr:=proc(n,a,b,c::evaln,Risphi::evaln)
local k,R,phi;
for k from 0 to n do
c[k]:=evalf(abs(a[k]+I*b[k])):
phi:=evalf(argument(a[k]+I*b[k]));
R[k]:=[eval(k),eval(phi)];
end:
Risphi:=plot(convert(R,list)):
end:
7: f3:= proc(t) local z ;
z:=piecewise(t<0,0,t<1/2,1,0);
evalf(z);end:
8: Nt:=100:n:=trunc(Nt/2):T:=2;
T := 2
9: a:=array(0..n):b:=array(0..n):
Y:=array(0..Nt):
10: Setka(Nt,T,f3,Y):
11: F_Discret(Y,Nt,a,b):
12:
RT:=plot(Trig(t,n,T,a,b),t=-T..T,numpoints=500,
color=blue):
13: display(RT,GrafF):
14: Cl:=blue,red,brown;
Cl := blue, red , brown
15:
RT:=seq(plot(Trig(t,8*k,T,a,b),t=-0.1..T+0.1,
numpoints=500,color=Cl[k]),k=1..3):
16: display(RT,GrafF);
1
0.8
0.6
0.4
0.2
0
0.5
1
t
1.5
49
2
>
>
17: Spectr(n,a,b,GrafC,Grafphi):
18: display(ARR(n,GrafC));
0.4
0.3
0.2
0.1
0
>
>
>
>
>
>
>
>
>
>
>
10
20
30
40
50
19: display(Grafphi):
20: ysin:=proc(x) local
z;z:=3*sin(x*2*Pi/Tau)+0.2*cos(15*x*2*Pi/Tau);end;
21: Tau:=2;
T := 2
22: Nt:=40;n:=trunc(Nt/2);
Nt := 40
n := 20
23: Setka(Nt,T,ysin,Y):
24: F_Discret(Y,Nt,a,b):
25:
RT:=seq(plot(Trig(t,8*k,T,a,b),t=-0.1..T+0.1,
numpoints=500,color=Cl[k]),k=1..2):
26: display(RT,GrafF);
50
3
2
1
0.5
–1
1
t
1.5
2
–2
–3
>
>
27: Spectr(n,a,b,GrafC,Grafphi):
28: display(ARR(n,GrafC));
3
2.5
2
1.5
1
0.5
0
5
10
15
20
29: f1:=proc(t) 2/Pi*arcsin(sin(t*Pi/2));end;
30: f2:= proc(t) local z ;
z:=piecewise(t<0,0,t<1/2,2*t,t<=1,2-2*t,0); evalf(z);end:
>
>
51
31: Period:=proc(t,t0,tau,T,f) local x,z;
x:=evalf(t-t0-floor((t-t0)/T)*T);
z:=f(x/tau);evalf(z);
end:
>
32: f4:=proc(x) Period(x,-1/2,2,2,f3);end;
>
33: plot([f1,f2,f4],-2..2,thickness=2,color=[Cl]);
>
34: f5:=proc(x) Period(x,0,2,2,2*f3-1);end;
>
35: plot(f5,-2..2,thickness=2);
>
36: Setka(Nt,T,f4,Y):
>
37: F_Discret(Y,Nt,a,b):
>
38:
RT:=seq(plot(Trig(t,6*k,T,a,b),t=-T-0.1..T+0.1,
numpoints=500,color=Cl[k]),k=1..2):
>
39: display(RT,GrafF);
40: Spectr(n,a,b,GrafC,Grafphi):
>
41: display(ARR(n,GrafC));
>
1
0.8
0.6
0.4
0.2
–2
–1
1
t
52
2
1
0.8
0.6
0.4
0.2
0
5
10
15
42: Nt:=80;n:=40;Setka(Nt,T,f5,Y):
>
43: F_Discret(Y,Nt,a,b):
>
44:
RT:=seq(plot(Trig(t,8*k,T,a,b),t=-T-0.1..T+0.1,
numpoints=500,color=Cl[k]),k=1..2):
>
45: display(RT,GrafF);
>
46: Spectr(n,a,b,GrafC,Grafphi):
>
47: display(ARR(n,GrafC));
>
48: f6:=proc(t)
piecewise(t<0,0,t<1/4,1,t<3/4,0,t<=1,-1,0) end:
>
49: plot(Period(t,0,1,1,f6),t=-2..4);
>
50: T:=1;Setka(Nt,T,f6,Y):
>
51: F_Discret(Y,Nt,a,b):
>
52:
>
RT:=seq(plot(Trig(t,6*k,T,a,b),t=-T-0.1..T+0.1,
>
numpoints=500,color=Cl[k]),k=1..2):
>
53: display(RT,GrafF);
>
54: Spectr(n,a,b,GrafC,Grafphi):
>
55: display(ARR(n,GrafC));
>
53
20
1
0.5
–1
–0.5
0
0.5
t
1
–0.5
–1
>
57: f7:=proc(t) local z;
z:=f5(t);z1:=0.5*arcsin(sin(Pi*t*8));evalf(z+z1);
end;
>
58: plot(f7(x),x=-1..10,numpoints=1024);
1.5
1
0.5
0
–0.5
2
4
6
x
8
–1
–1.5
>
>
>
59: m:=1024:r:=array(1..m):s:=array(1..m):
60: for j to m do r[j]:=f7(50*j/m);s[j]:=0;end:
61: FFT(10,r,s):
54
10
>
62: Sp:=seq([j/m*2,abs(r[j]+I*s[j])],j=1..m/2):plot([Sp]);
600
500
400
300
200
100
0
4.3
4.3.1
0.2
0.4
0.6
0.8
1
Проектирование цифровых фильтров
Сглаживающие фильтры
В настоящем параграфе приведем примеры программ, моделирующих нерекурсивные линейные фильтры цифровых сигналов, отсылая читателя за основными понятиями и терминологией к книге [9].
Наиболее просто фильтр низких частот (сглаживающий фильтр) строится по методу усреднения отсчетов:
yk = hk yk + hk+1 yk+1 + . . . + hk+M yk+M ,
где M — число последующих используемых отсчетов, которое называется порядком фильтра, а весовые коэффициенты hj представляют собой отсчеты импульсной
характеристики фильтра. Заметим, что в практических задачах применяется сглаживающий фильтр, использующий одинаковое количество отсчетов слева и справа
от текущего отсчета (метод скользящего среднего).
Зададим (строка 1) порядок фильтра M = 2 и частоту Найквиста (называемую
также частотой среза или граничной частотой полосы пропускания). Частота дискретизации (в согласии с теоремой Котельникова) должна быть по крайней мере в
два раза выше частоты среза. В строке 3 зададим шаг дискретизации, называемый
иначе периодом дискретизации. В строках 5 – 7 определяется массив значений отсчетов импульсной характеристики и строится ее график. Напомним, что большинство
выводов команд и построений графиков на рабочем листе не приводятся. Рекомендуется при самостоятельном выполнении расчетов заменять двоеточие в конце команды
на точку с запятой.
55
В строках 8 – 11 вычисляются (по формулам 19-20) амплитудно - частотная и
фазочастотная характеристики сглаживающего фильтра и строятся их графики (на
рабочем листе приведен только график АЧХ). Команды строк 12 и 12.1 строят графики логарифма квадрата спектра в зависимости от частоты и от круговой частоты,
показывающие уровень подавляемого шума.
>
restart;with(plots):
>
1: Fc:=8;M:=2;#частота среза и порядок фильтра
>
2: Fd:=5*Fc;# частота дискретизации
>
3: T:=1/Fd;# шаг дискретизации
>
4: omega[d]:=2*Pi*Fd;# круговая частота дискретизации
>
5: h:=array(0..M):
Средние арифметические весовые коэффициенты:
>
6: h[0]:=1/3:h[1]:=1/3:h[2]:=1/3:
>
7: n:=’n’:plot(h[n],n=0..M,numpoints=M+1):
АЧХ и ФЧХ, вычисляются по формулам:
v
u
M
M
u
X
X
hk cos(k wT )))2 + (
hk sin(k wT ))2
A := t(h0 + (
k=1
φ := −arctan
(19)
k=1
PM
hk sin(k wT )
!
k=1
P
h0 + ( M
k=1 hk cos(k wT ))
8: A:=proc(wT) local z,k;global h,M,Fd;
z:=sqrt((h[0]+sum(h[k]*cos(k*wT/Fd),k=1..M))^2+
sum((h[k]*sin(k*wT/Fd),k=1..M))^2); evalf(z);
end:
>
9: plot(A(wT),wT=0..omega[d]/2,numpoints=500);
>
56
(20)
1
0.8
0.6
0.4
0.2
0
20
40
60
wT
80
100
120
>
10: phi:=proc(wT) local z,k;global
h,M,Fd; z:=-arctan(sum(evalf(h[k]*sin(k*wT/Fd)),k=1..M)/
(h[0]+sum(evalf(h[k]*cos(k*wT/Fd)),k=1..M))); evalf(z);
end:
>
11: plot(phi(wT),wT=0..omega[d]/2);
>
12: plot(ln(A(wT)),wT=0..omega[d]/2,numpoints=500,
thickness=3):;
>
12.1: plot(ln(A(w*Fd*Pi*2)),w=0..1/2,numpoints=500,
thickness=3);
0.1
0.2
w
0.3
0
–2
–4
–6
–8
–10
57
0.4
0.5
Проверка работоспособности фильтра. Зададим рабочую частоту сигнала и построим синусоидальный сигнал с наложением на него высокочастотной составляющей, которую будем сглаживать фильтром как шум.
>
13: X:=array(0..50*M):Y:=array(0..50*M):
>
omega_r:=25: F_r:=evalf(omega_r/2/Pi):
>
14: omega_H:=20*omega_r:F_H:=evalf(omega_H/2/Pi):
>
15: for j from 0 to 50*M do
>
X[j]:=sin(omega_r*T/Pi*j/2)+1/5*sin(omega_H*T/Pi*j);
>
end:;
>
16: j:=’j’:plot(X[j],j=0..50*M,style=point,symbol=cross):
>
17: j:=’j’:for j from 0 to 50*M do
>
s:=0;
>
for k from 0 to M do
>
if j-k>=0 then
s:=s+X[j-k]*h[k];
>
end;
>
end;
>
Y[j]:=s;
>
end:
>
18: j:=’j’:plot(Y[j],j=0..50*M):
>
19: j:=’j’:Gra1:=plot(X[j],j=0..50*M,style=point,
>
symbol=cross):
>
20: j:=’j’:Gra2:=plot(Y[j],j=0..50*M,color=blue):
>
21: display(Gra1,Gra2);
1
0.5
0
20
40
60
80
100
j
–0.5
–1
Повышение порядка фильтра (в целях улучшения качества сглаживания) приводит к уменьшению полосы пропускания и увеличению боковых лепестков АЧХ. Это
58
демонстрирует расчет, который следует выполнить, заменив в тексте рабочего листа
сеанса строки 1 и 6 на сответствующие строки 100 и 106:
101: Fc:=20;M:=10;
106: for n from 0 to M do h[n]:=1/(M+1);end:
Однако, даже простое перераспределение значений коэффициентов импульсной характеристики уже улучшает качество сглаживания (строки 201 и 206, заменяющие
соответствующие строки 1 и 6).
201: Fc:=8;M:=6;
206: h[0]:=1/12;h[1]:=1/6;h[2]:=1/4;
h[5]:=1/12;h[4]:=1/6;h[3]:=1/4;
Зададим очередной вариант расчета в строках 301 и 306:
301: Fc:=20;M:=10;
306: h[0]:=0.02;h[M]:=0.02;H:=2*h[0];
for n from 1 to M-1 do
h[n]:=evalf(sin(n*Pi/M));H:=H+h[n];
end:
for n from 0 to M do
h[n]:=h[n]/H;
end:
Увеличим порядок фильтра, перераспределив отсчеты импульсной характеристики
как в предыдущем расчете (то есть не меняем строку 306).
301: Fc:=100;M:=50;
Таким образом, очевидна задача — подобрать коэффициенты импульсной характеристики так, чтобы форма АЧХ была близка к прямоугольной и имела требуемую
полосу пропускания. Эта задача решается с применением весовых функций, называемых также оконными.
4.3.2
Весовые функции
Аналогично командам предыдущего сеанса, зададим порядок фильтра и сопутствующие величины, повторяя команды строк 1 – 4.
>
restart;with(plots):
>
1: Fc:=10;M:=100;#частота среза и порядок фильтра
>
2: Fd:=4*Fc;# частота дискретизации
>
3: T:=1/Fd;# шаг дискретизации
>
4: omega[d]:=2*Pi*Fd;# круговая частота дискретизации
Зададим весовые функции, соответствующие часто использующимся окнам: функция окон Хенна (при α = 0.5) и Хемминга (при α = 0.54), и построим их графики.
> restart;with(plots):
> ThetaH:=proc(n) local z,alpha;alpha:=0.54;
z:=piecewise(abs(n)>M/2,0,alpha+(1-alpha)*cos(2*Pi*n/M));
evalf(z);end;
plot(ThetaH(n),n=-M..M);
59
Окна Блэкмана и Кайзера задаются следующими процедурами:
>
>
ThetaB:=proc(n) local z;
z:=piecewise(abs(n)>M/2,0,0.42+0.5*cos(2*Pi*n/M)+
0.08*cos(4*Pi*n/M));
> evalf(z);end:plot(ThetaB(n),n=-M..M);
> plot(ThetaB(n),n=-M..M);
> ThetaK:=proc(n) local z,beta,J0;beta:=1;
>
J0:=proc(x) local y;y:=1+sum((1/k!*(1/2)^2)^k,k=1..5);
evalf(y);end;
>
z:=piecewise(abs(n)>M/2,0,J0(beta*sqrt(1-(2*n/M)^2))/
\ J0(beta));
>
evalf(z);end:
> plot(ThetaK(n),n=-M..M);
Далее, определим массивы, соответствующие весовым коэффициентам и отсчетам
импульсной характеристики, вычислим их и построим график импульсной характеристики. Если потребуются значения отсчетов импульсной характеристики, то следует убрать символ # перед операторами print. Для подстановки требуемой функции
окна следует изменить последнюю букву в названии оконной процедуры (строка 333)
на соответствующую окну букву.
>
>
>
>
>
>
>
>
>
>
>
c:=array(0..M);h:=array(0..M);
c[0]:=omega_n*T/Pi;h[M/2]:=c[0];
K:=M/2;
for n from 1 to M/2 do
333: c[n]:=evalf(2*sin(omega_n*T*n)/(Pi*n)*ThetaH(n));
end:
#printf("
n
c[n]
h[n]
h[M-n] \n");
for n from 0 to M/2-1 do
h[n]:=c[K-n]/2;h[M-n]:=h[n];
#printf(" % 4.0f % 8.4f % 8.4f % 8.4f \n",n,c[n],h[n],h[M-n]);
end:
>
n:=’n’:plot(h[n],n=0..M,numpoints=M+1,color=black,
thickness=2);
60
0.4
0.3
0.2
0.1
0
20
40
n
60
80
100
Повторяя команды строк 8 – 11, строим графики АЧХ и ФЧХ фильтра и график
квадрата логарифма спектра:
>
>
>
>
>
A:=proc(wT) local z,k;global h,M;
z:=sqrt((h[0]+sum(h[k]*cos(k*wT),k=1..M))^2+
sum((h[k]*sin(k*wT),k=1..M))^2); evalf(z);
end:
plot(A(wT),wT=0..omega[d]/2,numpoints=500);
1
0.8
0.6
0.4
0.2
0
10000 20000 30000 40000 50000 60000 70000
wT
61
>
>
>
>
phi:=proc(wT) local z,k;global h,M,Fd;
z:=-arctan(sum(evalf(h[k]*sin(k*wT/Fd)),k=1..M)/
(h[0]+sum(evalf(h[k]*cos(k*wT/Fd)),k=1..M))); evalf(z);
end; plot(phi(wT),wT=0..omega[d]/2);
62
Литература
1. Кондратьев В.П. Элементы линейной алгебры. Часть I. (Системы линейных
уравнений. Теория). Часть II. (Системы линейных уравнений. Практика вычислений). Учебное пособие. Екатеринбург: УрТИСИ ГОУ ВПО СибГУТИ, 2005.
2. Дьяконов В.П. Математическая система Maple V R3/R4/R5. М.: Солон, 1998.
3. Дьяконов В.П. Maple 8 в математике, физике и образовании. М.: Солон, 2003.
4. Дьяконов В.П. MATLAB 6/6.1/6.5 + Simulink 4/5. Основы применения. М.:
СОЛОН-Пресс, 2004.
5. Mathcad 6.0 PLUS. Финансовые, инженерные и научные расчеты в среде Windows
95. Пер. с англ. — М.: "Филинъ 1996.
6. Говорухин В.Н., Цибулин В.Г. Компьютер в математическом исследовании.
Учебный курс. — СПб.: Питер, 2001.
7. Березин И.С., Жидков Н.П. Методы вычислений. т. I. М.: Физматгиз, 1962.
8. Хемминг Р.В. Численные методы для научных работников и инженеров. М.:
Наука, 1968.
9. Основы цифровой обработки сигналов: Курс лекций. СПб.: БХВ-Петербург,
2003.
63
Содержание
III
Язык программирования системы
1 Основные операторы
1.1 Описание основных операторов . . . . . . . .
1.1.1 Примеры основных операторов . . . .
1.2 Процедуры и функции . . . . . . . . . . . . .
1.2.1 Функции пользователя . . . . . . . . .
1.2.2 Примеры функций . . . . . . . . . . . .
1.2.3 Процедуры . . . . . . . . . . . . . . . .
1.2.4 Примеры процедур . . . . . . . . . . .
1.3 Кусочные функции . . . . . . . . . . . . . . .
1.3.1 Построение кусочных функций . . . .
1.3.2 Примеры процедур кусочных функций
3
.
.
.
.
.
.
.
.
.
.
3
3
7
11
11
13
14
18
20
20
21
2 Системы линейных уравнений
2.1 Постановка задачи. Определения . . . . . . . . . . . . . . . . . . . . . .
2.2 Метод полного исключения . . . . . . . . . . . . . . . . . . . . . . . . . .
2.3 Процедура метода Гаусса-Жордана . . . . . . . . . . . . . . . . . . . . .
25
25
25
27
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3 Электронные таблицы
30
3.1 Электронные таблицы в Maple . . . . . . . . . . . . . . . . . . . . . . . . 30
3.2 Maple в Excel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
4 Приложение
4.1 Резонансные LCR-контуры . . . . . . . . . .
4.2 Гармонический анализ дискретных сигналов
4.2.1 Конечные ряды Фурье . . . . . . . .
4.2.2 Процедуры гармонического анализа .
4.3 Проектирование цифровых фильтров . . . .
4.3.1 Сглаживающие фильтры . . . . . . .
4.3.2 Весовые функции . . . . . . . . . . .
Литература . . . . . . . . . . . . . . . . . . . . . .
64
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
40
40
45
45
48
55
55
59
63
Download