Remkomplekty.ru

IT Новости из мира ПК
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Возведение матрицы в степень паскаль

Возведение матрицы в степень паскаль

Решение практических задач на Паскале. Выпуск 6

Возведение матрицы в целочисленную степень

Преамбула

На нашем форуме (http://www.yourpascal.com/viewforum.php?f=6) был задан вопрос о возведении матрицы в степень в неподходящем для этого месте «нужно напечатать период дроби (на паскале)«. Отвечу в рассылке, в которой давно уже ничего не писал. Увы! Времени очень мало

В этом выпуске я представлю способ решения задачи с использованием рекурсии, так как давно искал повод для этого :)). Вот и пришло время .

Сейчас будет предложен вариант решения, в котором ранг матрицы фиксирован. Он задается константой max в модуле uMatrics . Если Вам захочется изменить ранг матрицы, то нужно изменить значение константы и заново откомпилировать программу. Это не очень удобно и в Delphi для решения такой проблемы существуют динамические массивы (которых в Паскале нет :(( ).

Но если нельзя, но хочется, то добрый старый Паскаль позволяет сделать все . Правда, для этого матрицу следует расположить в динамической памяти компьютера и работать с ней с помощью указателя. Чтобы было легче понять более сложный вариант, я и в этот раз буду размещать матрицу в динамической памяти. Это вовсе не обязательно. Можно обойтись «традиционными» двумерными массивами, объявленными в разделе VAR программы. Но используя указатели на массивы, размещенные в динамической памяти, позволяет использовать функции, а не процедуры. А это тоже плюс

Если описанный здесь способ покажется сложным, то напишите мне — я опишу и тот, более простой, способ решения с «обычными» массивами-матрицами.

Краткое описание

Метод рекурсий заключается в том, что в программе вызывается подпрограмма. А она вызывает саму себя до тех пор, пока не будет выполнена какая-то группа действий. Например, в данном случае, подпрограмма вычисления степени PowMatrix будет выполнять исходной умножение матрицы на нее же и вызывать самую себя с показателем степени на единицу меньше. Так будет происходить до тех пор, пока показатель степени, передаваемый подпрограмме в виде параметра не станет меньше нуля.

Достоинство метода рекурсий в том, что код получается маленький (и, вернее, он гусарский). Недостаток в том, что неэффективно используется память и при возведении в большую степень может не хватить стека. Тогда стек нужно увеличить за счет кучи. Как это делается, можно посмотреть в стандартной справке, если набрать $M и вызвать контекстную помощь, нажав сочетание Ctrl+F1 .

Замечу, что испытания моей программы показали: переполнение стека наблюдается при возведении матрицы в степень больше 650. А для меньших степеней гораздо вероятнее получить ошибку переполнения. Она возникает, когда в переменную типа Real делается попытка записать значение больше допустимого.

Сначала приведу исходный код программы, а потом дам пояснения. Хотите — читайте .

Исходный код программы

Все основное находится в модуле uMatrics . Он показан в листинге 1.

Для тестирования используется программа Solve006.pas , текст которой приведен в листинге 2.

Пояснения

Как отмечено вначале, здесь использован самый дубовый прямой метод: матрица каждый раз умножается сама на себя столько раз, в какую степень хотим возвести ее. По определению: A 0 = E; A 1 = А; A N = A N-1 ·A. Здесь E — единичная матрица.

Расчет производится по формуле: Cij = ∑ ik* Bkj ; где C, A и B — матрицы. — означает суммирование по индексу k от 1 до max. При этом число строк в матрице A должно быть равно числу столбцов в матрице B . Следовательно, возводить в некоторую степень можно только квадратные матрицы, число столбцов в которых равно числу строк.

Краткое описание модуля uMatrix

В модуле определены шесть подпрограмм для непосредственного решения задачи и две вспомогательные для обеспечения правильной работы с динамической памятью.

В разделе объявлений модуля «объявляются» новые типы переменных:

  1. TMatrics = array [1..max, 1..max] of Real; — двумерный массив, то есть, матрица ранга max,
  2. PMatrix = ^TMatrix; — указатель на двумерный массив. Благодаря такой переменной программа будет знать о структуре массива-матрицы, размешенной в динамической памяти. Это позволит обращаться к его элементам по их индексам.

В модуле созданы следующие подпрограммы:

  1. function NewMatrix: PMatrix; — размещает в динамической памяти ЭВМ массив и возвращает указатель на него. Очень простая функция. Заключается просто в вызове «стандартной» процедуры New. Легко обойтись без нее. Но с этой функцией код программы читается легче.
  2. function PowMatrix(Source: PMatrix; pow: Integer): PMatrix; — самая главная. Она организует возведение матрицы, указатель на который передан ее в качестве первого параметра Source, в степень pow. Рекурсия происходит в строках

p:=MulMatrix(Source, PowMatrix(Source, Pow-1));
По-моему, подпрограмма простая

  • procedure ShowMatrix(matrix: PMatrix; Dest: String; Size, Digs: Byte; mes: String); — выводит содержимое матрицы matrixна экран, если параметр Dest пустой, или в файл. Если файл с заданным именем существует, то информация дописывается в конец этого файла. Параметры Size , Digsпредназначены для форматирования вывода. Сообщение mesможно добавить перед выводом матрицы.
  • procedure AutoFillMatrix(var Matrix: PMatrix); — подпрограмма автоматического заполнения матрицы. Она же проверяет, была ли уже создана матрица? Если нет, в этом случае указатель Matrixравен nil, то матрица инициализируется с помощью функции NewMatrix. Если захотите заполнить матрицу вводя значения элементов с клавиатуры, то лучше написать свою процедуру.
  • function MulMatrix(source1, source2: PMatrix): PMatrix; — выполняет умножение матрицы source1 на матрицу source2.
  • function UnitaryMatrix: PMatrix; — генерирует единичную матрицу. Все элементы такой матрицы равны нулю, кроме тех, что расположены на главной диагонали. Они равны единице.
  • При работе с динамической памятью могут возникнуть две неприятности:

    • система может не выделить блок нужного Вам размера. Если Вы запускаете программу под Windows, то это скорее всего произойдет, когда попытаетесь разместить матрицу, занимающую в памяти больше 64К. Паскаль — это ДОСовская программа. Она не умеет работать с большими блоками. (Хотя справедливости ради замечу, что Borland Pascal может. Я описывал это в одном из выпусков рассылки по Турбо Паскалю)
    • в предложенном простом варианте в динамической памяти могут остаться лишние массивы. Можно было бы и не делать их, точнее, своевременно удалять ненужные. Но тогда каждая из подпрограмм модуля была бы чуть сложнее. Я решил сделать так:
      • в начале работы программы я «запоминаю» вызовом самый «верхний» адрес в куче вызовом Mark(varForHeapRelease) в исполняемом блоке модуля;
      • когда программа завершает работу, нужно вызвать Release(varForHeapRelease). И я не хочу объяснять это каждому встречному и поперечному. Я использую тот факт, что у Паскаля есть процедура, которая вызывается независимо от Вашего желания. Я подменил ее своею, которая имеет такой код:
        procedure FreeAllMemory; far;
        begin
        Release(varForHeapRelease);
        ExitProc:=SaveExit;
        end;

        Она сначала освобождает память от запомненного уровня до самого верха, а потом «вспоминает» стандрантую процедуру выхода ( ExitProc:=SaveExit). В переменной SaveExit для этого перед установкой своей процедуры ( ExitProc:=@FreeAllMemory;) я запомнил адрес стандартной ( SaveExit:=ExitProc;) в исполняемом блоке модуля.
      • КОНЕЧНО, это способ нельзя признать удачным и абсолютно надежным, но до изобретения объектов (или, по крайней мере, до их использования) приходится мириться с недостатками

    Описание тестирующей программы

    Программа простая. Сначала определена переменная типа PMatrix, указатель на двумерный массив. Затем вызывается процедура автоматического заполнения матрицы. Если хотите, можете написать другую процедуру, которая значение элементов будет считывать с клавиатуры. Затем все просто:

    • сначала записываем содержимое исходной матрицы в файл;
    • возводим матрицу во вторую степень;
    • в тот же файл записываем матрицу после возведения в степень.

    В результате должен получиться файл с содержимым, показанным ниже

    Тестовый пример

    Это результаты работы программы: содержимое файла test.txt

    Заключительное замечание (реклама объектно-ориентированного программирования)

    Недостатком предложенного метода является то, что пользователь может вызвать некоторые из подпрограмм с неверными параметрами. В худшем случае ошибок времени выполнения может и не произойти. Тогда человек будет думать, что расчет выполнен правильно. Избавиться от этого недостатка можно только с помощью объектов. Там можно и удобный интерфейс предоставить и ошибки легко отслеживать. Добавьте еще отмеченные проблемы с использованием памяти

    Исходный текст программы и модуля можно скачать в виде архива по адресу http://www.borlpasc.narod.ru/Boris/Solve006.zip

    Мы приглашаем Вас и Ваших друзей к сотрудничеству. Напишите, какая проблема Вас лично интересует — и мы постараемся помочь Вам. Поделитесь со всеми, если Вам удастся найти красивое решение. Присылайте свои программы, и если они хороши, то опубликуем их с обязательным указанием Вашего авторства.

    По всем вопросам можно писать либо в Гостевую книгу нашего сайта на www.turbopascal.tk, либо

    мне, автору этого выпуска, © Сурину Борису: surin_bp@mail.ru, ICQ: 320096696.

    Постараюсь ответить на все вопросы и учесть все разумные предложения

    Рассылка поддерживается сайтом www.turbopascal.tk. При перепечатке ссылка на сайт обязательна

    Обращаем внимание: наш форум размещается на www.yourpascal.com .

    Внимание: сессия и экзамены еще не начались — самое время подписаться на нашу рассылку:

    Быстрое Возведение В Степень Матрицы

    Существует ли более быстрый метод возведения матрицы в степень для вычисления M^n ( где M-матрица, а n-целое число), чем простой алгоритм деления и завоевания.

    4 Ответов

    Вы можете разложить матрицу на собственные значения и собственные векторы. Тогда вы получите

    Где V-матрица собственных векторов, А D-диагональная матрица. Чтобы поднять это до N-й степени, вы получите что — то вроде:

    Потому что все термины V и V^-1 отменяются.

    Поскольку D диагонально, вам просто нужно поднять кучу (вещественных) чисел до n-й степени, а не полные матрицы. Вы можете сделать это за логарифмическое время в n.

    Вычисление собственных значений и собственных векторов составляет r^3 (где r-число строк / столбцов M). В зависимости от относительных размеров r и n, это может быть быстрее или нет.

    Довольно просто использовать алгоритм Эйлера быстрой мощности. Используйте следующий алгоритм.

    Ниже пожалуйста найдите эквивалент для чисел:

    Возведение в степень путем возведения в квадрат часто используется для получения высоких степеней матриц.

    Я бы рекомендовал подход, используемый для вычисления последовательности Фибоначчи в матричном виде . AFAIK, его эффективность равна O (log (n)).

    Похожие вопросы:

    типичное уравнение для модульного возведения в степень — (a + b) MOD n = ((a MOD n) + (b MOD n)) MOD n. это потрясающе, если a и b очень огромны. однако меня просят сделать это возведение в степень.

    ^ всегда должен был означать возведение в степень. Но он так себя не ведет. Что это на самом деле означает, и есть ли какие-либо функции-члены Int, которые выполняют возведение в степень (кроме.

    Я пытаюсь сделать быстрое возведение в степень. Но результат, похоже, не дает правильного результата. Любая помощь будет оценена по достоинству. EDIT: удалось решить это спасибо за всю помощь. if.

    Я реализую возведение в степень матрицы с использованием FOR: import numpy as np fl=2 cl=2 fl2=fl cl2=cl M = random.random((fl,cl)) M2 = M Result = np.zeros((fl,cl)) Temp = np.zeros((fl,cl)) itera =.

    Я ищу функцию для возведения в степень матрицы с помощью perl. Я искал CPAN, но не могу найти ничего подходящего. Кто-нибудь знает о подходящем пакете или простой функции? Например, для следующей.

    Некоторые другие темы здесь на SO упоминали статью ” быстрое возведение в степень с предварительным вычислением Брикелла и др., который, наряду с простой концепцией предварительного вычисления.

    Я пытаюсь сделать http://www.spoj.com/problems/FIBTWIST / problem с помощью линейной рекурсии. Однако, поскольку ограничения велики, я должен использовать матричное возведение в степень. Я прочитал.

    Я пытался определить более короткий метод расчета gcd ((a^n + b^n), abs (a-b)). Я заметил, что, если я должен был вычислить (используя приведенную выше формулу), скажем, a = 100 и b = 4, начиная с 1.

    Как я могу сделать возведение в степень в clojure? Пока мне нужна только целочисленная экспоненция, но вопрос касается и дробей.

    Я пишу код в Julia, который включает в себя повышение большой матрицы целых чисел до высокой мощности, и я хочу сделать этот код более эффективным. Я искал вокруг на JuliaLang, но я не уверен, что.

    Возведение в степень в паскале

    Вопросы «возвденеие в степень pascal» или «возведение в степень на Паскале» являются наиболее популярными в своей тематике. Не всегда представляется возможным умножать число само на себя (например x := x * x;) в силу динамично изменяющихся параметров задачи, да и при больших показателях степени размер кода может увеличиться во много раз. Кроме того, подобное выражение не предусматривает возможность возведения числа в дробную степень.

    Возведение в степень в паскале можно реализовать несколькими способами. Рассмотрим их, установив преимущества и недостатки каждого

    Универсальная функция возведения в степень в pascal

    Самый эффективный и правильный способ — взятие экспоненты от логарифма Exp(X*Ln(Y)), где X — степень числа, Y — основание. Однако, необходимо учитывать частные случаи когда основание или степень отрицательные числа, либо когда один из них является нулем. Также необходимо учесть тот факт, что при возведении отрицательного числа в четную степень, результат становится положительным

    if (x 0) then pow := Exp(y*Ln(Abs(x))) else

    if (l mod 2 = 0) then R:=Abs(pow);

    if (y = 0) then Pow :=1;

    Возведение в степень с помощью цикла

    Является одним из самых простых и быстрых способов. Задается цикл от единицы до требуемого показателя, в котором основание складывается с самим собой. Организовать подобный алгоритм можно использовав как for, так и while или repeat.

    for i:=1 to pow-1 do

    if ((not odd(pow)) and (pow

    Возведение в степень с помощью рекурсии

    Аналогично предыдущему итерационному способу. Отличие заключается только в том, что вместо очередного вызова тела цикла используется вызов функции (рекурсия).

    Возведение в степень в pascal для целого показателя, вычисляемого за время log2(pow)

    Данный алгоритм также, как и два предыдущих работает только с целыми показателями степени. Однако, время затрачиваемое на вычисление существенно сокращается.

    function power (x,pow:integer):integer;

    var res: integer;

    while (pow > 0) do

    if (pow and 1 = 1) then res := res * x;

    Таким образом, возвести число в степень в паскале с дробным показателем может позволить только универсальная функция возведения в степень. Использование первого способа является наиболее быстродейственным. Это особенно заметно, при больших значениях степени и большого числа знака после запятой. Следует отметить, что помимо перечисленных выше способов существуют и другие алгоритмы реализующие в Turbo Pascal возведение в степень.

    Возведение в степень в pascal — Универсальная функция возведения в степень (1 способ)

    Функция Power — Простое итерационное вычисление степени с помощью цикла (2 способ)

    Рекурсивное возведения числа в степень — Возведение числа в степень с помощью рекурсии (3 способ)

    Быстрое возведение в степень в паскале — Алгоритм с вычислением за время log2(pow) (4 способ)

    Возведение матрицы в степень. Вычисление результатов выражений с матрицами.

    Здесь мы продолжим начатую в первой части тему операций над матрицами и разберём пару примеров, в которых потребуется применять несколько операций сразу.

    Возведение матрицы в степень.

    При этом полагаем, что $A^0=E$, где $E$ – единичная матрица соответствующего порядка.

    Задана матрица $ A=left(begin 1 & 2 \ -1 & -3 end right)$. Найти матрицы $A^2$ и $A^6$.

    Согласно определению $A^2=Acdot A$, т.е. для нахождения $A^2$ нам просто нужно умножить матрицу $A$ саму на себя. Операция умножения матриц рассматривалась в первой части темы, поэтому тут просто запишем процесс решения без подробных пояснений:

    $$ A^2=Acdot A=left(begin 1 & 2 \ -1 & -3 end right)cdot left(begin 1 & 2 \ -1 & -3 end right)= left(begin 1cdot 1+2cdot (-1) & 1cdot 2+2cdot (-3) \ -1cdot 1+(-3)cdot (-1) & -1cdot 2+(-3)cdot (-3) end right)= left(begin -1 & -4 \ 2 & 7 end right). $$

    Чтобы найти матрицу $A^6$ у нас есть два варианта. Вариант первый: банально продолжить домножать $A^2$ на матрицу $A$:

    $$ A^6=A^2cdot Acdot Acdot Acdot A. $$

    Однако можно пойти несколько более простым путём, используя свойство ассоциативности умножения матриц. Расставим скобки в выражении для $A^6$:

    $$ A^6=A^2cdot Acdot Acdot Acdot A=A^2cdot (Acdot A)cdot (Acdot A)=A^2cdot A^2cdot A^2. $$

    Если при решении первым способом потребовалось бы четыре операции умножения, то для второго способа – лишь две. Поэтому пойдём вторым путём:

    $$ A^6=A^2cdot A^2cdot A^2=left(begin -1 & -4 \ 2 & 7 end right)cdot left(begin -1 & -4 \ 2 & 7 end right)cdot left(begin -1 & -4 \ 2 & 7 end right)=\= left(begin -1cdot (-1)+(-4)cdot 2 & -1cdot (-4)+(-4)cdot 7 \ 2cdot (-1)+7cdot 2 & 2cdot (-4)+7cdot 7 end right)cdot left(begin -1 & -4 \ 2 & 7 end right)= left(begin -7 & -24 \ 12 & 41 end right)cdot left(begin -1 & -4 \ 2 & 7 end right)=\= left(begin -7cdot(-1)+(-24)cdot 2 & -7cdot (-4)+(-24)cdot 7 \ 12cdot (-1)+41cdot 2 & 12cdot (-4)+41cdot 7 end right)= left(begin -41 & -140 \ 70 & 239 end right). $$

    Ответ: $A^2=left(begin -1 & -4 \ 2 & 7 end right)$, $A^6=left(begin -41 & -140 \ 70 & 239 end right)$.

    Заданы матрицы $ A=left(begin 1 & 0 & -1 & 2 \ 3 & -2 & 5 & 0 \ -1 & 4 & -3 & 6 end right)$, $ B=left(begin -9 & 1 & 0 \ 2 & -1 & 4 \ 0 & -2 & 3 \ 1 & 5 & 0 end right)$, $ C=left(begin -5 & -20 & 13 \ 10 & 12 & 9 \ 3 & -15 & 8 end right)$. Найти матрицу $D=2AB-3C^T+7E$.

    Вычисление матрицы $D$ начнем с нахождения результата произведения $AB$. Матрицы $A$ и $B$ можно перемножать, так как количество столбцов матрицы $A$ равно количеству строк матрицы $B$. Обозначим $F=AB$. При этом матрица $F$ будет иметь три столбца и три строки, т.е. будет квадратной (если этот вывод кажется неочевидным, посмотрите описание умножения матриц в первой части этой темы). Найдем матрицу $F$, вычислив все её элементы:

    Итак, $F=left(begin -7 & 13 & -3 \ -31 & -5 & 7 \ 23 & 31 & 7 end right)$. Пойдём далее. Матрица $C^T$ – транспонированная матрица для матрицы $C$, т.е. $ C^T=left(begin -5 & 10 & 3 \ -20 & 12 & -15 \ 13 & 9 & 8 end right) $. Что же касаемо матрицы $E$, то это есть единичная матрица. В данном случае порядок этой матрицы равен трём, т.е. $E=left(begin 1 & 0 & 0 \ 0 & 1 & 0 \ 0 & 0 & 1 end right)$.

    В принципе, мы и дальше можем идти пошагово, но оставшееся выражение лучше рассматривать целиком, не отвлекаясь на вспомогательные действия. По сути, нам остались лишь операции умножения матриц на число, а также операции сложения и вычитания.

    $$ D=2AB-3C^T+7E=2cdot left(begin -7 & 13 & -3 \ -31 & -5 & 7 \ 23 & 31 & 7 end right)-3cdot left(begin -5 & 10 & 3 \ -20 & 12 & -15 \ 13 & 9 & 8 end right)+7cdot left(begin 1 & 0 & 0 \ 0 & 1 & 0 \ 0 & 0 & 1 end right) $$

    Умножим матрицы в правой части равенства на соответствующие числа (т.е. на 2, 3 и 7):

    $$ 2cdot left(begin -7 & 13 & -3 \ -31 & -5 & 7 \ 23 & 31 & 7 end right)-3cdot left(begin -5 & 10 & 3 \ -20 & 12 & -15 \ 13 & 9 & 8 end right)+7cdot left(begin 1 & 0 & 0 \ 0 & 1 & 0 \ 0 & 0 & 1 end right)=\= left(begin -14 & 26 & -6 \ -62 & -10 & 14 \ 46 & 62 & 14 end right)-left(begin -15 & 13 & 9 \ -60 & 36 & -45 \ 39 & 27 & 24 end right)+left(begin 7 & 0 & 0 \ 0 & 7 & 0 \ 0 & 0 & 7 end right) $$

    Выполним последние действия: вычитание и сложение:

    $$ left(begin -14 & 26 & -6 \ -62 & -10 & 14 \ 46 & 62 & 14 end right)-left(begin -15 & 30 & 9 \ -60 & 36 & -45 \ 39 & 27 & 24 end right)+left(begin 7 & 0 & 0 \ 0 & 7 & 0 \ 0 & 0 & 7 end right)=\ =left(begin -14-(-15)+7 & 26-30+0 & -6-9+0 \ -62-(-60)+0 & -10-36+7 & 14-(-45)+0 \ 46-39+0 & 62-27+0 & 14-24+7 end right)= left(begin 8 & -4 & -15 \ -2 & -39 & 59 \ 7 & 35 & -3 end right). $$

    Задача решена, $D=left(begin 8 & -4 & -15 \ -2 & -39 & 59 \ 7 & 35 & -3 end right)$.

    Ответ: $D=left(begin 8 & -4 & -15 \ -2 & -39 & 59 \ 7 & 35 & -3 end right)$.

    Пусть $f(x)=2x^2+3x-9$ и матрица $ A=left(begin -3 & 1 \ 5 & 0 end right) $. Найти значение $f(A)$.

    Если $f(x)=2x^2+3x-9$, то под $f(A)$ понимают матрицу:

    Именно так определяется многочлен от матрицы. Итак, нам нужно подставить матрицу $A$ в выражение для $f(A)$ и получить результат. Так как все действия были подробно разобраны ранее, то тут я просто приведу решение. Если процесс выполнения операции $A^2=Acdot A$ для вас неясен, то советую глянуть описание умножения матриц в первой части этой темы.

    $$ f(A)=2A^2+3A-9E=2Acdot A+3A-9E=2 left(begin -3 & 1 \ 5 & 0 end right)cdot left(begin -3 & 1 \ 5 & 0 end right)+3 left(begin -3 & 1 \ 5 & 0 end right)-9left(begin 1 & 0 \ 0 & 1 end right)=\ =2 left(begin (-3)cdot(-3)+1cdot 5 & (-3)cdot 1+1cdot 0 \ 5cdot(-3)+0cdot 5 & 5cdot 1+0cdot 0 end right)+3 left(begin -3 & 1 \ 5 & 0 end right)-9left(begin 1 & 0 \ 0 & 1 end right)=\ =2 left(begin 14 & -3 \ -15 & 5 end right)+3 left(begin -3 & 1 \ 5 & 0 end right)-9left(begin 1 & 0 \ 0 & 1 end right) =left(begin 28 & -6 \ -30 & 10 end right)+left(begin -9 & 3 \ 15 & 0 end right)-left(begin 9 & 0 \ 0 & 9 end right)=left(begin 10 & -3 \ -15 & 1 end right). $$

    Обработка матриц в Паскале

    Матрица — это двумерный массив , каждый элемент которого имеет два индекса: номер строки и номер столбца.

    Объявить двумерный массив (матрицу) можно так:

    имя : array [ индекс1_нач.. индекс1_кон, индекс2_нач.. индекс2_кон ]

    • тип определяет тип элементов массива,
    • имя — имя матрицы,
    • индекс1_нач..индекс1_кон — диапазон изменения номеров строк,
    • индекс2_нач..индекс2_кон — диапазон изменения номеров столбцов матрицы.

    var h : array [ 0.. 1 1, 1.. 10 ] of integer;

    Описана матрица целых чисел h , состоящая из двенадцати строк и десяти столбцов (строки нумеруются от 0 до 11, столбцы от 1 до 10).

    Существует ещё один способ описать матрицы, для этого надо создать новый тип данных :

    новый_тип=array [ индекс1_нач.. индекс1_кон ] of тип;

    имя : array [ индекс2_нач.. индекс2_кон ] of новый_тип;

    новый_тип=array [ список_диапазонов ] of тип;

    В данном случае в матрицах a и b есть 10 строк и 30 столбцов, а с — матрица , в которой есть 16 строк и 14 столбцов.

    Для обращения к элементу матрицы необходимо указать её имя и в квадратных скобках через запятую номер строки и номер столбца:

    имя [ номер_строки, номер_столбца ]

    имя [ номер_строки ] [ номер_столбца ]

    Например, h[2,4] 1 Или h[2][4]. — элемент матрицы h , находящийся в строке под номером два и столбце под номером четыре.

    Для обработки всех элементов матрицы необходимо использовать два цикла . Если матрица обрабатывается построчно, то во внешнем цикле последовательно перебираются строки от первой до последней, затем во внутреннем — все (первый, второй, третий и т. д.) элементы текущей строки. При обработке элементов матрицы по столбцам внешний цикл будет перебирать столбцы, внутренний — строки. На рис. 6.1 представлена блок-схема алгоритма обработки матрицы по строкам, на рис. 6.2 — по столбцам. Здесь i — номер строки, j — номер столбца, N — количество строк, M — количество столбцов матрицы A .

    Рассмотрим основные операции , выполняемые над матрицами при решении задач.

    6.1 Ввод-вывод матриц

    Матрицы, как и массивы, нужно вводить (выводить) поэлементно. Вначале следует ввести размеры матрицы, а затем уже в двойном цикле вводить элементы. Блок-схема ввода элементов матрицы изображена на рис. 6.3.

    Вывод можно осуществлять по строкам или по столбцам, но лучше, если элементы располагаются построчно, например,

    Алгоритм построчного вывода элементов матрицы приведён на рис. 6.4.

    Об описании матриц на языке Паскаль было рассказано в разделе 5.2 главы 5, обращение к элементу матрицы можно осуществить c помощью конструкции или .

    Рассмотрим реализацию ввода-вывода матриц в консольных приложениях.

    Для организации построчного ввода матрицы в двойном цикле по строкам и столбцам можно использовать оператор read .

    В этом случае элементы каждой строки матрицы можно разделять символами пробела или табуляции, и только в конце строки нажимать Enter .

    Ниже приведён пример консольного приложения ввода-вывода матрицы.

    На рис. 6.5 представлены результаты работы программы.

    Ввод матрицы также можно организовать с помощью следующего цикла .

    Авторы предлагают читателю самостоятельно разобраться, в чём будет отличие ввода матрицы в этом случае.

    Для ввода-вывода матриц можно использовать компонент типа TStringGrid, с которым мы познакомились в главе 5.

    В качестве примера рассмотрим следующую задачу.

    Блок-схема транспонирования матрицы приведена на рис. 6.6. При транспонировании матрицы получается матрица B.

    Рассмотрим частный случай транспонирования матрицы фиксированного размера A(4,3) .

    На форме разместим метки Label1 и Label2 со свойствами Caption — Заданная матрица и Транспонированная матрица , два компонента типа TStringGrid , изменив их свойства так, как показано в табл. 6.1, и кнопку Транспонирование матрицы.

    Окно формы приложения представлено на рис. 6.7.

    Ниже приведён текст подпрограммы с комментариями, которая будет выполняться, если пользователь щёлкнет по кнопке Транспонирование матрицы.

    Читать еще:  Ввод в си шарп
    Ссылка на основную публикацию
    Adblock
    detector