Смекни!
smekni.com

Программирование и разработка приложений в Maple (стр. 23 из 135)

[W + 2 G + 3 S, 4 W + 5 G + 6 S, 7 W + 8 G + 10 S]

Для обеспечения работы с матричными и векторными выражениями Maple-язык располагает довольно развитым набором функциональных средств, поддерживаемых, в первую очередь, пакетными модулями linalg и LinearAlgebra. Данные модули содержат определения 114 и 118 процедур соответственно (в зависимости от релиза пакета; пример приведен для Maple 10), обеспечивающих расширенные средства линейной алгебры по работе с матричными и векторными выражениями. Учитывая обилие указанных средств и направленность данной книги, мы не будем акцентировать на них внимания, отсылая к нашей книге [12] либо к ее авторскому оригинал-макету, который можно загрузить с университетского Web-сайта www.grsu.by/cgi-bin/lib/lib.cgi?menu=links&path=sites. В них рассмотрены средства пакета, составляющие определенную базу для обеспечения работы с матрично/векторными выражениями в рамках классической линейной алгебры. Лишь кратко определим способы доступа к таким модульным средствам пакета.

Ряд средств линейной алгебры имеют классический формат вызова вида Id(<аргументы>), тогда как основная масса таких средств определяется пакетным модулем linalg. Поэтому первый вызов любого из них должен предваряться предложением одного из следующих трех форматов, а именно: with(linalg), with(linalg, <Процедура_1>, <Процедура_2>, <Процедура_3>, ...) или linalg[<Процедура>](<аргументы>). Исходя из обстоятельств, пользователь будет производить вызов процедур linalg-модуля необходимым ему способом. Первый формат обеспечивает доступ сразу ко всем процедурам модуля, но их загрузка требует дополнительной памяти в рабочей области пакета, второй формат активирует определения конкретных процедур, используемых в текущем сеансе, и третий формат определяет разовый вызов конкретной процедуры на конкретных фактических аргументах. Последний формат часто используется в пользовательских процедурах. Вызов процедуры packages() возвращает список пакетных модулей, загруженных в текущий сеанс. Вышесказанное иллюстрирует следующий простой пример:

> restart; packages(), map(type, [col, det], 'procedure'); ⇒ [], [false, false] > with(linalg, col, det), packages(), map(type, [col, det], 'procedure');

[col, det], [linalg], [true, true]

Из приведенного примера следует, что загрузка даже отдельных процедур модуля идентифицируется процедурой packages как загрузка модуля в целом.

С учетом сказанного, средства модуля linalg не представляют каких-либо затруднений при использовании их знакомым с основами линейной алгебры читателем, а приведенные здесь и в прилож. 1 [12] примеры и дополнительные замечания вполне достаточно иллюстрируют средства матричной алгебры, поддерживаемые Maple-языком. Наряду с наиболее общими linalg-модуль располагает целым рядом других, более специальных, матричных средств, включая средства создания специального типа матриц (Вандермонда, Теплица, Сильвестра и др.), в полном же объеме со средствами матричной алгебры, обеспечиваемыми Maple-языком, рекомендуется ознакомиться по книгам [10-14,59,80,86,90].

Базовые структуры данных модуля LinearAlgebra. Одну из самых больших особенностей Maple составляет его модуль LinearAlgebra, определяющий новые стандарты эффективности, надежности, полезных свойств и точности для вычислительной линейной алгебры. Данная задача была решена путем интегрирования в пакет современных программ линейной алгебры фирмы NAG (Numerical Algorithm Group) через внешний механизм вызовов [13,14,39]. Это позволяет использовать мощные вычислительные алгоритмы NAG для решения задач линейной алгебры с высокими точностью и производительностью. Однако, прежде, чем переходить к характеристике средств LinearAlgebraмодуля, кратко остановимся на различиях между ним и рассмотренным выше linalg-модулем линейной алгебры.

Если в основе векторно-матричных объектов, с которыми оперирует модуль linalg, лежит структура данных array-типа, то основу объектов, обрабатываемых средствами модуля LinearAlgebra, составляет так называемая rtable-структура данных, генерируемая одноименной встроенной функцией. Данная функция и генерируемые ею rtable-объекты детально были нами рассмотрены в [13,14,39]; ряд новых средств по работе с такого типа объектами как отдельно, так и в совокупности с array-объектами представлен нами в книгах [39,41,42,45,46,103], а также в нашей Библиотеке [103,109].

Визуализация rtable-объекта (Array, Matrix, Vector) определяется его размером. Если размер его меньше или равен значению, определенному предопределенной rtablesize-переменной процедуры interface (по умолчанию rtablesize=10), то объект визуализируется полностью. В противном случае он заменяется специальным шаблоном. Установка опции rtablesize=0 определяет вывод любого rtable-объекта в виде шаблона, тогда как установка rtablesize=infinity определяет вывод rtable-объекта полностью безотносительно его размера, как иллюстрирует следующий фрагмент:

> interface(rtablesize=2); Kr:= rtable(1..3, [89, 11, 99]); restart: Kr:=rtable(1..3, [89, 11, 99]);

Kr :=  1..3 1-D Array Data Type: anything Storage: rectangular Order: Fortran_order 

Kr := [89, 11, 99]

> interface(rtablesize = 6); Kr:= rtable(1..3, 1..3, [[42, 47, 67], [64, 59, 39], [44, 10, 17]]);

42 47 67

Kr := 6444 5910 3917 

Из фрагмента нетрудно заметить, что шаблон rtable-объекта представляет собой стандартный описатель объекта (размерность, тип и основные характеристики). В случае больших размеров массивов данное средство оказывается весьма удобным. При этом, следует иметь в виду следующее важное обстоятельство. Если размер rtable-объекта больше определяемого rtablesize-переменной, то выводится его шаблон даже в случае наличия рекурсивности в его определении, в противном случае сразу же идентифицируется аварийная ситуация, требующая перезагрузки пакета. Причиной этого является переполнение системного стэка. Впрочем, работа пакетного стэка и так имеет много нареканий.

Для работы с rtable-объектами пакет располагает рядом полезных функций и процедур, детально рассмотренных в [45,46]. Данные средства применимы к любому rtable-объекту (Array, Matrix, Vector), однако каждый из трех типов объектов располагает и собственными аналогичными средствами, кратко рассматриваемыми ниже. Для вывода rtable-объектов можно использовать и форматирующие функции printf-группы: printf, fprintf, sprintf, nprintf, с опциями которых для этого случая можно ознакомиться по справке пакета. Аналогично этому к любому rtable-объекту применимы и функции scanf-группы (scanf, fscanf, sscanf) для выполнения синтаксического анализа объектов.

Объекты rtable-типа. На основе упомянутой rtable-функции определяются три базовых объекта LinearAlgebra-модуля: Array, Matrix и Vector. Непосредственно посредством rtable-функции в среде пакета можно определять любой из указанных трех объектов. После их создания с ними можно работать в рамках алгебры, определяемой операциями, довольно детально рассмотренными в книгах [39,41,42,45,46,103]. Приведем простой фрагмент, иллюстрирующий использование операций rtable-алгебры пакета.

> A:=rtable(1..4, 1..4, random(4..11, 0.95), subtype=Array, storage=sparse, datatype=integer):

M:= rtable(1..4, 1..4, random(42..99, 0.58), subtype=Matrix, storage=rectangular): C:=rtable(1..4, 1..4): V:= rtable(1..4, random(42..99, 0.64), subtype=Vector[column], storage=rectangular): A, M, V, C;

10869 10655 10756 10856, 6995460 739500 54536885 5549760,  45477284, 0000 0000 0000 0000

> Vr:= rtable(1..4, random(47..99, 0.99), subtype = Vector[row], storage = sparse, datatype = integer); ⇒ Vr := [65, 56, 57, 90]

> Vr.M^(-2) + 6*Vr;

208520698897237 , 7876939551794474 , 1338604372134095006 , 164952480446301172553 

> A^2 + 10*A + 99, M^2 + 17*M + 95, (Vr.M + 17*Vr).(10*M + 17);

299243195270

[3

195

299

174

174 15128

218

174

195

299 80 27,

174

243, 1451710416206155035 114081662550359913 1711324383120175406

299

195

251067 36562329 26471066, , ]

8531

12411,

17632

4123

С учетом сказанного, примеры фрагмента особых пояснений не требуют. В этой связи имеет смысл лишь вкратце пояснить различие между табличной организацией собственно Maple-среды (базируется на table-функции) и NAG-организацией (базируется на функции rtable). В первом случае массивы и таблицы базируются на внутренних хэш-таблицах пакета, тогда как во втором случае используется формат импортированного NAG-модуля линейной алгебры. В этом случае для каждого измерения rtable-объекта используется по одному вектору индексов и отдельный вектор отводится под значения элементов массива. На основе такого представления формируются такие структуры данных как Array, Matrix, Vector[row] и Vector[column]. Более того, следует иметь в виду, что одноименные рассмотренным структуры array, matrix и vector, начинающиеся со строчных букв (исключение составляют пассивные функции), относятся к средствам собственно Maple-языка и их обработка производится иными средствами, детально рассмотренными в цитируемых выше книгах. При этом, следует отметить, что функции на основе rtable-функции принципиально отличаются от одноименных функций array, matrix и vector, как отмечалось выше.