Как сделать рандомную матрицу на c

Добавил пользователь Алексей Ф.
Обновлено: 05.10.2024

В этом руководстве будет обсуждаться, как сгенерировать или создать случайные числа с помощью функций rand() , randi() , randn() , randperm() , betarand() и random() . в MATLAB.

Сгенерируйте случайные числа, используя функцию rand() в MATLAB

Если вы хотите сгенерировать равномерно распределенные случайные числа, вы можете использовать функцию rand() в MATLAB, которая генерирует случайные числа от 0 до 1. Вы также можете указать размер матрицы, содержащей случайные значения, и каждое значение будет от 0 до 1, которые вы можете масштабировать в соответствии с вашими требованиями, умножая их с помощью масштабатора. Например, сгенерируем матрицу случайных значений 2 на 2 с помощью функции rand() . См. Код ниже.

Как видно из выходных данных, создается матрица 2 на 2, содержащая случайные значения от 0 до 1. Если вы хотите указать диапазон случайных чисел, вы должны использовать приведенную ниже формулу.

В этой формуле a - это нижний предел, b - верхний предел, а n - длина случайных чисел. Например, давайте сгенерируем десять случайных чисел в диапазоне от 2 до 8. См. Код ниже.

Есть десять случайных чисел в диапазоне от 2 до 8. Если вам нужны только целые числа на выходе, вы можете преобразовать эти случайные числа в целые, используя функцию round() , которая округляет число с плавающей запятой до ближайшего целого. . Вы также можете клонировать размер и тип данных случайных чисел из существующего массива, используя функцию size() для размера и свойство like для типа данных. Например, давайте создадим массив и сгенерируем случайные значения в соответствии с размером и типом данных этого массива. См. Код ниже.

Размер и тип данных массива и случайных чисел совпадают. Проверьте эту ссылку, чтобы узнать больше о функции rand() .

Сгенерируйте случайные числа, используя функцию randi() в MATLAB

Вышеупомянутая функция генерирует случайные числа с плавающей запятой, но если вы хотите сгенерировать случайные целые числа, вы можете использовать функцию randi() в MATLAB, которая генерирует случайные целые числа от 1 до заданного целого числа, которое вы можете указать как первый аргумент в функции randi() . Вы также можете указать размер выходной матрицы, содержащей случайные значения, в качестве второго и третьего аргумента. Например, давайте сгенерируем матрицу 3 на 3, содержащую случайные целые числа от 1 до 15. См. Код ниже.

Матрица имеет размер 3 на 3 и содержит случайные целые числа от 1 до 15. Вы также можете генерировать случайные целые числа между определенным диапазоном, и вам просто нужно передать диапазон в квадратных скобках в качестве первого аргумента randi() функция. Например, давайте сгенерируем 10 случайных чисел от -10 до 10. См. Код ниже.

Существует десять случайных чисел в диапазоне от -10 до 10. Вы также можете определить тип данных целых чисел, передав имя типа данных в функции randi() . Вы можете выбрать следующие типы данных: 'single' , 'double' , 'int8' , 'uint8' , 'int16' , 'uint16' , 'int32' . , или 'uint32' . Вы можете определить размер случайных чисел из размера существующего массива с помощью функции size() и числового типа данных с помощью свойства like . Например, давайте сгенерируем матрицу случайных значений в зависимости от размера и числового типа данных существующего массива. См. Код ниже.

Размер и тип данных массива и случайных чисел совпадают. Проверьте эту ссылку, чтобы узнать больше о функции randi() .

Сгенерируйте случайные числа, используя функцию randn() в MATLAB

Если вы хотите сгенерировать нормально распределенные случайные числа, вы можете использовать функцию randn() в MATLAB. Функция randn() аналогична функции rand() , но отличается только типом распределения. Функция rand() генерирует равномерно распределенные случайные числа, а функция randn() генерирует нормально распределенные случайные числа. Вы можете использовать любую из этих функций в зависимости от ваших требований. Проверьте эту ссылку, чтобы узнать больше о функции randn .

Сгенерируйте случайные числа, используя функцию randperm() в MATLAB

Если вы хотите сгенерировать случайную перестановку целых чисел, вы можете использовать функцию randperm() в MATLAB. Случайная перестановка целых чисел будет от 1 до определенного числа, которое вы можете определить в функции randperm() в качестве первого аргумента. Вы также можете определить количество целых чисел, которые хотите сгенерировать, в качестве второго аргумента функции. Например, давайте сгенерируем случайную перестановку 6 уникальных целых чисел. См. Код ниже.

Все целые числа уникальны и находятся в диапазоне от 1 до 10. Обратите внимание, что функция randperm() аналогична функции randi() с той разницей, что randperm() генерирует уникальные целые числа, тогда как в randperm() randi() целые числа могут повторяться. Проверьте эту ссылку, чтобы узнать больше о функции randperm .

Сгенерируйте случайные числа с помощью функции betarnd() в MATLAB

Если вы хотите сгенерировать случайные числа из бета-распределения, вы можете использовать функцию betarnd() в MATLAB. Эта функция генерирует случайные целые числа, заданные первым и вторым аргументом: векторы, матрицы или массивы одинакового размера. Например, давайте сгенерируем матрицу случайных чисел размером 1 на 5 из бета-распределения, используя в качестве входных данных два вектора. См. Код ниже.

Вы также можете указать размер выходной матрицы, задав его в третьем и четвертом аргументах функции betarnd() . Посетите эту ссылку, чтобы узнать больше о функции betarnd() .

Сгенерируйте случайные числа, используя функцию random() в MATLAB

Если вы хотите сгенерировать случайные числа из указанного типа распределения, вы можете использовать функцию random() в MATLAB. Вы должны определить имя распределения в качестве первого аргумента, а затем после этого вам необходимо передать параметры распределения. Например, давайте сгенерируем нормально распределенные случайные числа, используя значение сигмы 0 и значение mu 1, используя функцию random() . См. Код ниже.

Вы можете определить необходимое имя дистрибутива в функции. Вы можете использовать множество типов распределений, например: Бета , Биномиальное , Экспоненциальное , Гамма и многие другие. Посетите эту ссылку, чтобы узнать больше о функции random .

Сопутствующая статья - MATLAB Matrix


report this ad

Генераторы списков удобно использовать для матриц (многомерных массивов) чисел заданной размерности. Матрицы можно представлять в виде кортежей или списков.
Лучше матрицы представлять в виде вложенных списков. В наиболее общем случае, представление двумерной матрицы в виде списка на языке Python имеет следующий вид

  • MatrixName – имя матрицы;
  • a11 , …, amn — элементы матрицы. Это могут быть числа, числа с плавающей запятой, символы, строки, логические значения ( true , false ). Также это могут быть более сложные объекты, например, те же списки, кортежи или множества.

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

2. Примеры решения задач с использованием генераторов списков
2.1. Задачи на построение матриц
2.1.1. Построение матрицы заданной размерности. Элементы матрицы формируются случайным образом

Условие задачи. Построить матрицу заданной размерности m*n и вывести ее на экран. Элементы матрицы формируются случайно и имеют значение от 1 до 10 включительно.

Решение.

2.1.2. Формирование двумерной матрицы заданной размерности. Элементы матрицы вводятся с клавиатуры

Условие задачи. Сформировать матрицу размерностью m×n . Значение размеров m , n и значения элементов вводятся с клавиатуры.

Решение.

2.2. Задачи на обработку данных, которые размещаются в матрице
2.2.1. Вычисление количества элементов матрицы, которые больше 5

Условие задачи. Построить матрицу целых чисел размерностью m×n, где m — количество строк матрицы, n — количество столбцов матрицы. Значения m и n вводятся с клавиатуры. Числа в матрице формируются случайным образом и находятся в пределах от 1 до 10. Используя генератор списков вычислить количество элементов матрицы, которые более 5.

Решение.

2.2.2. Задача. Исчисление суммы элементов матрицы согласно условию

Условие задачи. Задан двумерный массив целых чисел размером m×n. Определить сумму элементов массива, которые находятся в пределах [5; 10]. Элементы массива вводятся с клавиатуры.

Решение.

При формировании генератора списка для расчета суммы используется функция sum() .

2.3.2. Создать результирующую матрицу на основе исходной согласно с заданным условием

Условие задачи. Задана квадратная матрица A целых чисел размерностью n . На основе матрицы A образовать матрицу B , каждый элемент которой определяется по правилу:

БлогNot. C++: двумерная матрица на основе контейнера

C++: двумерная матрица на основе контейнера

Двумерную матрицу из объектов нужного типа в QT легко сделать с помощью QVector или же другого списочного контейнера, например, QList .

Основная идея очень проста - организовать вектор, состоящий из векторов:

То же самое можно сделать и с помощью std::vector .

В том и другом случае можно не менять размерность после создания контейнера, а указать её сразу же аргументами конструктора. Доступ к элементу будет осуществляться обычным способом, в виде a[i][j] .

Все 4 способа показаны ниже в маленькой программке (консольное приложение QT), везде использован тип данных double , но это необязательно, в качестве элементов наших матриц можно брать объекты любого простого или составного типа.

Часть кода, основанная на std::vector , сработает и в Visual Studio.

Ну и помните, что на самом деле, "обычные" двумерные массивы тоже являются массивами массивов :)

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

Демонстрация разложения матрицы

Рис. 1. Демонстрация разложения матрицы

Определение матрицы

Независимо от примененной схемы хранения матрицы можно реализовать, используя либо ООП (объектно-ориентированное программирование), либо подход со статическими методами. Так, подход с ООП мог бы быть примерно таким:

Единственно оптимального выбора реализации матриц нет; все зависит от конкретного сценария кодирования, с которым вы имеете дело, и от ваших личных предпочтений в кодировании. В этой статье применяется подход со статическими методами, поскольку он самый простой для понимания и рефакторинга.

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

Этот метод можно вызывать так:

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

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

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

Перемножение матриц

Перемножение матриц

Рис. 2. Перемножение матриц

Заметьте, что вычисление значения каждой ячейки не зависит от значений других ячеек, поэтому каждое вычисление независимо, и потенциально их можно выполнять параллельно на компьютере с несколькими процессорами (или ядрами). Вот стандартный подход к перемножению матриц:

Task Parallel Library упрощает кодирование простой распараллеленной версии перемножения матриц.

Проверка согласованности

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

В дополнение предположим, что ваша матрица создает матрицу тождественности, или единичную матрицу (identity matrix), т. е. квадратную матрицу со значениями 1.0 по основной диагонали и значениями 0.0 в остальных ячейках:

И у вас есть метод, сравнивающий две матрицы на тождественность:

Заметьте, что метод MatrixAreEqual не сравнивает значения ячеек на точное равенство, так как эти значения имеют тип double. Вместо этого метод проверяет, очень ли близки друг к другу значения ячеек (в пределах epsilon).

Поскольку произведение любой квадратной матрицы m и единичной матрицы той же размерности равно исходной матрице m, вы можете протестировать метод MatrixProduct наряду со следующими строками кода:

Разложение матрицы

При разложении берется квадратная матрица M и вычисляются две новые квадратные матрицы, которые при перемножении дают исходную матрицу M. Идея аналогичная обычному разложению чисел на множители: число 6 можно разложить на множители 2 и 3, потому что 2 * 3 = 6. Поначалу может показаться, что в разложении матриц нет особого смысла, но оказывается, что такое разложение существенно упрощает очень трудную задачу обращения матрицы. Если много видов разложения матриц, и каждый из них может вычисляться по нескольким алгоритмам. Методика, представленная в этой статье, называется разложением LUP и использует метод Дулитла (Doolittle's method) с выбором ведущего элемента столбца (partial pivoting).

Чтобы понять разложение LUP, полезно сначала разобраться в простом разложении LU, которое было введено знаменитым математиком Аланом Тьюрингом (Alan Turing). Допустим, у вам имеется вот такая матрица M размером 4 × 4:

Одно из возможных разложений LU для M — это L, равная:

Это работает, так как L * U = M. Заметьте, что нижняя матрица L имеет значения 1.0 по диагонали и 0.0 вверху справа. Иначе говоря, значимые значения ячеек нижней матрицы находятся внизу слева. Аналогично значимые значения ячеек верхней матрицы расположены на основной диагонали и вверху справа.

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

Разложение LUP матрицы — небольшая, но важная вариация разложения LU. При разложении LUP берется матрица matrix M и создаются матрицы L и U, а также массив P. Произведение L и U в LUP не точно соответствует исходной матрице M, а является версией M, где некоторые строки переупорядочены. Информация о том, как эти строки были переупорядочены, хранится в массиве P; эту информацию можно использовать для реконструкции исходной матрицы M.

Близкий вариант разложения Дулитла, представленного в этой статье, называется разложением Краута (Crout). Главное различие между методами Дулитла и Краута в том, что Дулитл помещает значения 1.0 на основную диагональ матрицы L, а Краут — на основную диагональ матрицы U.

Причина, по которой разложение LUP используется чаще, чем разложение LU, весьма тонкая. Как вы вскоре увидите, разложение используется для обращения матрицы. Однако, когда разложение матрицы применяется как вспомогательный метод для ее обращения, оказывается, что инверсия заканчивается неудачей, если по основной диагонали матрицы LU имеется значение 0.0. Поэтому в разложении LUP, когда на основной диагонали появляется значение 0.0, алгоритм меняет местами две строки, чтобы сместить значение 0.0 с диагонали, и отслеживает, какие строки были переставлены, в массиве P.

Метод разложения матрицы показан на рис. 3.

Рис. 3. Метод разложения матрицы

Этот метод можно было бы вызвать так:

Метод MatrixDecompose принимает квадратную матрицу и возвращает три значения. Явно возвращается переставленная матрица LU. Остальные два значения возвращаются через выходные параметры. Один из них является массивом перестановки (permutation array), где хранится информация о том, как переставлены строки. Второй выходной параметр — переключатель, принимающий значение либо +1, либо –1 в зависимости от того, было количество перестановок четным (+1) или нечетным (–1). Значение переключателя не используется для обращения матрицы, но необходимо, если разложение применяется для вычисления определителя матрицы.

Метод MatrixDecompose весьма замысловатый, но на самом деле для модификации кода достаточно понимать в нем лишь несколько деталей. Версия, представленная здесь, выделяет новую память под возвращаемую матрицу LU через вспомогательный метод MatrixDuplicate:

Или, поскольку было исключено явно возвращаемое значение, вы могли бы использовать его для массива перестановки или переключателя, например:

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

Другая часть MatrixDecompose, которую вам, может быть, захочется изменить, — это выражение:

Обращение матрицы

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

Рис. 4. Метод HelperSolve

Метод HelperSolve находит массив x, который при умножении на матрицу LU дает массив b. Этот метод весьма непрост, и вы можете полностью понять его, только проследив его работу на нескольких примерах. В нем два цикла. Первый цикл использует прямую подстановку (forward substitution) в нижней части матрицы LU, а второй цикл — обратную подстановку (backward substitution) в верхней части той же матрицы. В некоторых других реализациях разложения матрицы аналогичный метод называют, например, luBackSub.

Хотя этот код короткий, он весьма сложен, но никаких сценариев, где вам могло бы понадобиться его изменение, нет. Заметьте, что HelperSolve принимает матрицу LU от MatrixDecompose, но не использует выходной параметр perm. Это подразумевает, что HelperSolve, по сути, является вспомогательным методом и нуждается в дополнительной оболочке кода для решения системы уравнений. При рефакторинге кода из этой статьи под объектно-ориентированное программирование вы, вероятно, предпочтете сделать метод HelperSolve закрытым.

Создав метод HelperSolve, можно реализовать метод обращения матрицы, как показано на рис. 5.

Рис. 5. Метод MatrixInverse

И вновь сложный код. Алгоритм обращения основан на том, что результат перемножения матрицы M и ее обращения является единичной матрицей. Метод MatrixInverse в основном отвечает за решение системы уравнений Ax = b, где A — матрица разложения LU , а константы b равны либо 1.0, либо 0.0 и соответствуют единичной матрице. Заметьте, что MatrixInverse использует массив perm, возвращаемый после вызова MatrixDecompose.

Вызов метода MatrixInverse мог бы выглядеть так:

Подведем итог. Важной матричной операцией является обращение матрицы, которое весьма сложно. Один из подходов — разложение исходной матрицы, написание вспомогательного метода, выполняющего прямую и обратную подстановки, и последующее использование разложения совместно с массивом перестановок LU и вспомогательного метода для поиска обращенной матрицы. Этот подход может показаться слишком сложным, но обычно он эффективнее и проще, чем прямое вычисление обращенной матрицы.

Определитель матрицы

Когда у вас есть метод разложения матрицы, написать метод для вычисления определителя матрицы нетрудно:

Решение систем уравнений

Метод HelperSolve можно легко адаптировать для решения системы линейных уравнений:

Вот код, который дал вывод, показанный на рис. 1, для решения следующей системы:

Заметьте, что SystemSolve переупорядочивает свой входной параметр b, используя массив perm из MatrixDecompose до вызова HelperSolve.

Что такое массив перестановок

Последние несколько строк вывода на рис. 1 указывают, что матрицы L и U можно перемножить так, чтобы получить исходную матрицу. Знание того, как это делается, не поможет вам в решении практических задач операций над матрицами, но позволит разобраться, что представляет собой часть P в разложении LUP. Восстановление исходной матрицы из ее компонентов L и U также пригодится для тестирования ваших библиотечных методов работы с матрицами на согласованность.

Один из способов восстановления исходной матрицы после разложения LUP — перемножение L и U с последующей перестановкой строк результата на основе массива P:

Метод UnPermute можно закодировать так:

Второй подход — преобразование массива perm в матрицу perm с последующим перемножением матрицы perm и комбинированной матрицы LU:

Матрица perm является квадратной с одним значением 1.0 в каждой строке и каждом столбце. Метод, который создает матрицу perm из массива perm, можно написать следующим образом:

Заключение

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

Выражаю благодарность за рецензирование статьи экспертам Полу Коху (Paul Koch) и Дэну Либлингу (Dan Liebling).

Читайте также: