Remontnouta.ru

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

Функция МОПРЕД для нахождения детерминанта матрицы в Excel

Функция МОПРЕД для нахождения детерминанта матрицы в Excel

Функция МОПРЕД в Excel используется для работы с прямоугольными матрицами. Задаваемыми в качестве статических массивов или диапазонов ячеек с числовыми данными, и вычисляет детерминант (определитель) исследуемой матрицы.

Матрица – математический объект, состоящий из совокупности строк из столбцов, каждый элемент которых содержит определенное числовое значение. Детерминант – один из основных вычисляемых параметров матрицы, характеризующих ее ключевые свойства.

Понятие и термины

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

Матрица состоит из столбцов (n) и строк (m). Характеризуется она порядком и размерностью. Обычно говорят, что некий массив В имеет размер m на n. Записывают это как В = . Существует и другой вариант записи: В = (аij), где i и j – индексы, при этом 1≤ i ≤ m; 1 ≤ j ≤ n. В учебниках же просто указывается разрядность в виде 2х2, 3х3 и так далее. Матрица называется квадратной, если количество её строк равно величине столбцов.

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

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

Главной характеристикой массива является определитель, или детерминант. Им называют число, соответствующее алгебраической сумме всех возможных произведений столбцов на строки. Другими словами, чтобы найти значение детерминанта, нужно сумму элементов матрицы n умножить на её размерность m. При перемножении знак произведения определяется по числу инверсий. Их чётное количество соответствует положительному знаку, а нечётное – отрицательному.

Определитель — это число, которое определяет степень матрицы. Характеризуется он порядком. Так, определителем первого порядка называют значение, определяемое единственным элементом массива. Записывают его в виде выражения: A = , detA = |A| = a.

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

Читайте так же:
Можно ли использовать жесткий диск как флешку

Содержание основного курса

Нумерация в прошлой статье закончилась на 3, в этой будем продолжать нумеровать насквозь.
UPD: ВНИМАНИЕ! Раздел, начиная с номера 3.1, 3.14 и 3.141 и далее, будет о тонкостях реализации основы основ компьютерной графики — линейной алгебры и вычислительной геометрии. О принципах графики пишет haqreu, я же буду писать о том, как это можно внятно запрограммировать!

Эта статья является продолжением серии статей о практической реализации элементов вычислительной геометрии, и, в частности, программного отрисовщика, с использованием C++98. Мы с haqreu сознательно идем на использование прошлой версии стандарта и написание собственной геометрической библиотеки для того, чтобы, во-первых, выпустить код примеров, которые без особых трудностей будут компилироваться большинством имеющихся компиляторов, а во-вторых, чтобы в нашем коде не было ничего, что скрыто в недрах библиотеки. В статье излагаются вопросы реализации шаблона прямоугольной матрицы template<size_t DimRows,size_t DimCols,typename number_t> class mat;

4.1 Благодарности
4.2 Небольшое философское замечание о языке, математике, C++, и всем таком

В целом, такие абстракции, как «матрица» и «вектор» и операции над ними необходимы для того, чтобы упростить и формализовать язык изложения геометрии. Без них нам приходилось бы постоянно говорить (и писать в программе) что-то вроде:

После того, как понятие «вектор» вошло в наш речевой оборот, мы уже можем говорить:

А после включения в наш код шаблона vec, мы можем писать:
Таким образом, мы сокращаем написанное, страхуемся от ошибок при копировании-вставке-правке и получаем способ рассуждать более емкими терминами.

Вот что об этом пишет Джефф Элджер в книге «C++ for Real programmers», (издательство AP Professional, перевод выпущен издательством «Питер» под названием «C++: Библиотека программиста»)

Как раз этим мы и займемся — будем строить с использованием C++ язык управления геометрическими примитивами, стараясь делать это как можно ближе к определениям из математики.

5 Шаблон класса для обработки и хранения матриц

Мы храним матрицу как массив вектор-строк, используя соответствующую специализацию шаблона vec. Наш шаблон ориентирован только на работу с матрицами малой размерности (максимум 10×10 элементов. Хотя это уже будет ужас). Но в вычислительной геометрии, как правило, вся работа идет именно с матрицами не больше, чем 4×4. Большие же матрицы получаются, как правило, очень разреженными — для них заранее известно, что они практически полностью заполнены нулями, что позволяет оптимизировать их обработку и хранение.

Читайте так же:
Зайти на гугл переводчик
5.1 Индексные операторы
Константный вариантНеконстантный вариант

Кроме того, мы здесь применяем макрос assert() для отлова попыток обратиться к несуществующей строке матрицы. Подробнее про assert написано в статье 3.1

5.2 Вычисление обратной матрицы
  • если для данной матрицы составить союзную матрицу,
  • а затем транспонировать
  • и поделить ее на определитель данной,

image

Получилась рекурсия — алгебраическое дополнение — тоже определитель матрицы, только размерность на единицу меньше. А определитель матрицы размерности 1 — это ее единственный элемент. Рекурсия замкнулась. Мы воспользуемся прекрасной особенностью шаблонов C++ — развернем эту рекурсию прямо во время компиляции.

  • унаследовать от mat класс squareMat, в котором объявить определитель
  • воспользоваться тем, что размеры матрицы нам известны еще на этапе компиляции, поэтому мы можем их сравнить и прервать компиляцию, если они не совпали
  • Оборачивание в отдельную структуру выполнено потому, что стандарт не разрешает делать частичную специализацию для функций.
  • Мы вынесли эту функцию из mat потому, что поступив иначе, были бы вынуждены дописывать в mat<1,1,number_t> часть методов из общей версии, что привело бы к некоторому раздутию кода.

Общая же версия шаблона выполняет разложение матрицы по нулевой строке — она берет элемент с индексом 0, i из первой строки, умножает его на алгебраическое дополнение — cofactor(0,i) а результат накапливает в переменной ret . Все в полном согласии с формулой этого разложения:

5.3 Как происходит рекурсия

ВАЖНО: Строго говоря, механизм обработки шаблонов — личное дело компилятора. Ниже я рассказываю о том, как это могло бы происходить. Это делается только для иллюстрации того, как рекурсивно разворачиваются декларации шаблонов.

Представим, что мы самостоятельно выполняем разворачивание шаблонов. Написан код:Мы встречаем в нем вызов det() из шаблона mat, а значит, должны получить текст функции det() для конкретного случая mat<3,3,int>.

ШаблонРезультат подстановки DimCols=3; DimRows=3; number_t=int

Отлично, теперь нам нужно из шаблона template<size_t Dim,typename number_t> struct dt получить конкретный текст для случая dt<3,int>:

ШаблонРезультат подстановки Dim=3; number_t=int

Мы встретили вызов оператора [] и cofactor() из mat<3,3,int>. Тело [] сейчас для нас интереса не представляет, разбираемся с cofactor():

ШаблонРезультат подстановки DimCols=3; DimRows=3; number_t=int

Здесь вызывается get_minor(). Получим для нее текст:

ШаблонРезультат подстановки DimCols=3; DimRows=3; number_t=int

Мы получили, что этот get_minor() возвращает уже матрицу 2×2. Теперь мы, для матрицы 2×2 будем вызывать mat<2,2,int>::det(). Но у нас есть только тело mat<3,3,int>::det(). Поэтому мы совершаем погружение в рекурсию на один шаг и строим еще один набор методов:

Читайте так же:
Можно ли ускорить установку игры

Мы должны получить текст функции det() для конкретного случая mat<2,2,int>:

ШаблонРезультат подстановки Dim=2; number_t=int

Отлично, теперь нам нужно из шаблона template<size_t Dim,typename number_t> struct dt получить конкретный текст для случая dt<2,int>:

ШаблонРезультат подстановки Dim=2; number_t=int

Мы встретили вызов оператора [] и cofactor() из mat<2,2,int>. Тело [] сейчас для нас интереса не представляет, разбираемся с cofactor():

ШаблонРезультат подстановки DimCols=2; DimRows=2; number_t=int

Здесь вызывается get_minor(). Получим для нее текст:

ШаблонРезультат подстановки DimCols=2; DimRows=2; number_t=int

Развернув цепочку шаблонов, мы снова столкнулись с вызовом get_minor() в теле cofactor(), но уже для случая DimCols=2, DimRows=2. Полученная версия get_minor() возвращает матрицу 1×1. Далее, для нее в теле cofactor() запрашивается определитель. Мы снова должны получить текст mat::det(), но уже для случая DimCols=1; DimRows=1.

ШаблонРезультат подстановки DimCols=1; DimRows=1; number_t=int

Отлично, теперь нам нужно из шаблона template<size_t Dim,typename number_t> struct dt получить конкретный текст для случая dt<1,int>. СТОП, это же попадает под частичную специализацию шаблона dt<1,number_t>! Нужно обрабатывать именно ее, а не общую версию шаблона!

ШаблонРезультат подстановки Dim=1; number_t=int

Видим, что здесь уже нет обращения к cofactor(). На этом раскрутка рекурсии закончена — мы получили тела функций для вычисления определителя матриц 3×3, 2×2, 1×1.
Важное замечание: Может возникнуть желание написать так:

Мотивация простая — это будет вроде как обычная рекурсия, да и частичная специализация не нужна. Однако во время развертывания шаблонов, компилятор ничего не будет делать с условным оператором, а начнет строить шаблоны(3, 2, 1, 0, std::numeric_limits<size_t>::max, std::numeric_limits<size_t>::max-1, . ), пока его не остановит внутренний счетчик -ftemplate-depth= (по умолчанию, эта глубина погружения равна 900).
Возможность использовать привычные операторы управления потоком появляется в C++11 для функций, объявленных c ключевым словом constexpr . Они позволяют организовать еще один вид вычислений во время компиляции, отличный от рекурсии на шаблонах. А не провернуть ли мне весь наш рендер во время компиляции?

Итак, мы описали в терминах C++ отыскание определителя матрицы, а также сопутствующие этому операции — построение минора матрицы и алгебраического дополнения. Для отыскания обратной матрицы осталось только построить союзную матрицу:

Читайте так же:
Можно ли удалить видео с ютуба свое

действует точно по определению — заполняет матрицу алгебраическими дополнениями соответствующих элементов.
Осталось выполнить главный этап построений — найти обратную матрицу (она будет получена в транспонированном виде):

5.4 Умножение матриц

Да, здесь вроде как имеет место быть лишнее копирование (позже мы посмотрим, справится ли компилятор с его выбрасыванием), но главная цель — написать такое краткое и емкое умножение матриц:

Уделим внимание этому тексту. Здесь на C++ изложено математическое определение операции умножения прямоугольных матриц, причем сделано это очень близко к тексту[«заполнение матрицы-результата всевозможными скалярными произведениями вектор-строк левой матрицы на вектор-столбцы правой»].
При этом контроль размерностей (число столбцов левой должно быть равно числу строк правой) выполняется сразу на этапе компиляции — попытка перемножить не подходящие по размеру матрицы даже не откомпилируется.
А это очень важно, ведь ошибка времени выполнения может быть плавающей, трудноуловимой и так далее. А ошибка компиляции вылезает практически всегда. (Нужно учесть сумасшествие IDE, которая может часть проекта закэшировать, часть забыть обновить и так далее. Но от этого есть верное лекарство — Rebuild All).

5.5 Генератор единичных матриц

Есть интересная особенность — запись результата типа bool в переменную априорно неизвестного типа number_t. Здесь может случиться кошмарик у человека, который захотел бы использовать нашу геометрию в своем проекте, причем вместе с самодельным типом для хранения чисел (это может быть тип, который хранит числа с фиксированной запятой). Он может не ожидать, что наши методы будут пытаться записывать в его тип значения bool (оператор == для size_t возвращает bool), и нагородить собственный конструктор, принимающий bool и делающий это преобразование не так, как описано в стандарте ([§4.7/4] требует, чтобы при приведении bool в числовой тип, false превращалось в 0, true — в 1). Так как в данном случае, от стандарта отступает гипотетический пользователь, нам не следует пытаться подстилать ему соломку (мы могли бы сотворить такое: ret[i][j]=static_cast<number_t>(static_cast<int>(i==j)) , и передавать ему хотя бы int) ценой череды преобразований — нарушил стандарт — сам виноват.

5.6 Умножение матрицы на вектор

Теперь мы можем записать оператор умножения матрицы на вектор:
Сработано точно по определению — получили из вектора матрицу с одним столбцом, перемножили, вернули столбец-результат.

Метод Гаусса

Способ Гаусса используется для решения системы уравнений. На их базе составляется массив. Первые столбцы образуют из коэффициентов, стоящих после неизвестных, а последний из значений, расположенных после знака равно. Для нахождения определителя этим способом необходимо выполнить два шага:

  1. Привести матрицу к верхнетреугольной или нижнетреугольной форме путём элементарных преобразований.
  2. Сосчитать произведение всех элементов, расположенных на главной диагонали треугольного массива, заменив при этом полученный знак определителя на противоположный.
Читайте так же:
Бровсек для гугл хром

Например, необходимо найти детерминант системы уравнений:

n1 + 2 * n2 – 3 * n3 = — 4.

2*n1 + 5 * n2 – 4 * n3 = 0.

-3*n1 + n2 – 3 * n3 = 5.

Метод Гаусса

На первом этапе составляют матрицу и решают её. Выделяют первую строку и пытаются обнулить все первые коэффициенты. Для этого каждый элемент нужно умножить на такое число, чтобы последующий элемент обнулился. Затем берут другую строку и обнуляют уже вторые элементы. Так, для заданной системы уравнений первую строку необходимо умножить на -2, а затем сложить со второй строкой. То есть первый элемент в первом столбце будет равен: x11 = -2 * 1 + 2 = 0; второй: x22 = -2 * 2 +5 = 1; третий: x33 = -2*(-3) – 4 = 2; четвёртый: x44 = -2* (-4) + 0 = 8.

Аналогичные действия проводят по отношению к элементам третьей строки. Для обнуления первую строчку умножают уже не на -2, а на тройку. В результате первый столбец будет состоять из двух нулевых элементов. Затем переходят к обнулению элементов во втором столбце. Делают это последовательным умножением третьей строки на – 7. В итоге получится массив с тремя нулевыми членами.

Опираясь на полученную матрицу, составляют новую систему уравнений:

n1 + 2 * n2 – 3 * n3 = -4.

Как найти детерминант небольшого ранга

Затем из последнего равенства находят n3. Полученное значение подставляют во второе уравнение и определяют n2. На последнем этапе, используя найденные величины, вычисляют n1. Для нахождения детерминанта определяют тип матрицы, в этом случае она нижнетреугольная, и вычисляют его значение det = (1 * 1 * (-20)) = -20.

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

Кроме быстрого определения ответа, они также показывают подробное решение поставленной задачи. Если же доступа к интернету нет, то можно выполнить расчёт и в excel. Делается это с помощью функции «=МОПРЕД».

голоса
Рейтинг статьи
Ссылка на основную публикацию
Adblock
detector