To main content
 
Лекция 3
MATLAB.моделирование задачи "о пьянице"
"случайные числа"
В MATLAB существует несколько способов генерации случайных матриц


Функция rand() Генерирует равномерно распределенные случайные числа от 0 до 1
  • Пример: rn = rand(2) создаст матрицу 2x2
Можно задать диапазон: rn = a + (b-a).*rand(n,1), где a - нижняя граница, b - верхняя, n - размер

Функция randi() Генерирует случайные целые числа. Первый аргумент - максимальное значение. Поддерживает типы данных: ‘single’, ‘double’, ‘int8’, ‘uint8’, ‘int16’, ‘uint16’, ‘int32’, ‘uint32’
  • Пример: rn = randi(7,size(v),‘like’,v)

Функция randn() Генерирует нормально распределенные случайные числа
  • Пример: rn = randn(3) создаст матрицу 3x3

Функция randperm() Генерирует уникальные случайные целые числа
  • Пример: rn = randperm(10,5) создаст вектор из 5 уникальных чисел от 1 до 10

Функция betarnd() Генерирует случайные числа из бета-распределения. Принимает два вектора параметров распределения
  • Пример: rng(0,"twister"); A = randi(10,2,3); B = 10+randi(20,2,3);

Функция random() Позволяет генерировать случайные числа из различных распределений: (Beta/Binomial/Exponential/Gamma/И других)

Дополнительные возможности:
  • Можно задавать размер матрицы через size()
  • Можно копировать тип данных существующего массива с помощью like
  • Для округления чисел используется функция round()
% Создаем матрицу с копированием свойств существующей
v = [2 3 1 5];
rn = rand(size(v),'like',v);

% Генерируем целые числа в диапазоне
a = 2;
b = 8;
n = 10;
rn = round(a + (b-a).*rand(n,1));

В MATLAB существует несколько способов генерации матрицы в заданном диапазоне:

  • Для равномерного распределения (числа от 0 до 1):
matrix = rand(m, n);
  • Для равномерного распределения в произвольном диапазоне [a, b]:
matrix = a + (b-a).*rand(m, n);
  • Для целых чисел в диапазоне [a, b]:
matrix = a + (b-a).*randi([0 1], m, n);
  • Для нормального распределения в диапазоне [a, b]:
matrix = a + (b-a).*randn(m, n); matrix = max(min(matrix, b), a);
  • Для целых чисел с использованием randi:
matrix = a + (b-a).*randi([0 1], m, n);

Важные параметры:
  • m, n - размеры матрицы
  • a - нижняя граница диапазона
  • b - верхняя граница диапазона
%%Матрица 3x3 с числами от 1 до 100:
matrix = 1 + 99.*rand(3, 3);

%%Матрица 4x4 с целыми числами от -10 до 10:
matrix = -10 + 20.*randi([0 1], 4, 4);

%%Матрица 5x5 с нормальным распределением от 0 до 10:
matrix = 0 + 10.*randn(5, 5);
matrix = max(min(matrix, 10), 0);

%%матрица 7x7 с числами от -1 до 1:

Равномерное распределение: (для большинства задач подойдет)
matrix = -1 + 2.*rand(7, 7);

%%Нормальное распределение: (нормальное распределение с возможными выбросами)
matrix = 0 + 1.*randn(7, 7);
matrix = max(min(matrix, 1), -1);


%% Целые числа (-1, 0, 1): (только целые значения)
matrix = -1 + 2.*randi(0 1, 7, 7);


%% С использованием truncate (для MATLAB 2019a и выше/метод гарантирует нормальное распределение без выбросов):
pd = makedist('Normal', 'mu', 0, 'sigma', 1);
truncatedPd = truncate(pd, -1, 1);
matrix = random(truncatedPd, 7, 7);

способы определить знак каждого элемента массива


  • Использование встроенной функции sign():
matrix = rand(m, n);
sign_matrix = sign(matrix);

Результат:[1 для положительных чисел / 0 для нуля / -1 для отрицательных чисел]

  • Использование условного оператора:
sign_matrix = zeros(size(your_matrix));
sign_matrix(your_matrix > 0) = 1;
sign_matrix(your_matrix < 0) = -1;

  • С использованием if-else
[m, n] = size(your_matrix);
sign_matrix = zeros(m, n);
for i = 1:m
for j = 1:n
if your_matrix(i,j) > 0
sign_matrix(i,j) = 1;
else if your_matrix(i,j) < 0
sign_matrix(i,j) = -1;
end
end
end

способы сложения значений матриц по компонентам

(кумулятивные суммы)


  • Использование встроенной функции cumsum():
cumulative_sums = cumsum(your_matrix, 1);
где -1 указывает на суммирование по столбцам


  • Использование цикла
[m, n] = size(your_matrix);
cumulative_sums = zeros(m, n);
for i = 1:n
cumulative_sums(:,i) = cumsum(your_matrix(:,i));
end

cumulative_sums = arrayfun(@(x) cumsum(your_matrix(:,x)), ...
1:size(your_matrix,2), 'UniformOutput', false);
cumulative_sums = cell2mat(cumulative_sums');

  • Использование cumtrapz (численный метод)
cumulative_sums = cumtrapz(your_matrix, 1);


  1. Для большинства задач оптимально использовать cumsum()
  2. Для больших матриц предпочтительнее использовать встроенные функции
  3. Если вам нужно получить кумулятивные суммы по строкам вместо столбцов, просто измените параметр с 1 на 2 в функции cumsum/cumtrapz

Варианты визуализации


Для больших матриц лучше использовать imagesc или contourf

При небольшом количестве столбцов удобен stacked bar chart

Для анализа - линейный график

colorbar поможет интерпретировать цветовые шкалы



original_matrix = randi([-1, 1], 7, 7); % матрица 7х7

cumulative_sums = cumsum(original_matrix, 1);

Задание
  • балл: -
    часть A:
    описание:
    задача: Матрос, выходя из бара находясь в нулевой точке двигаясь вперед с вероятностью 50 % делает шаг влево или вправо.
    Задания для выполнения
    • Часть 1: построить и оформить средствами MATLAB графики «траектории» движения матроса. Для m -количества испытаний и n- количества шагов
  • балл: -
    часть B:
    описание:
    • Построить второй график с другим типом отображения данных
    • В соответствии с описанием в задании
массивA1A2A3A4
испытаний 200801,00E+03 3,00E+06
шагов 9,01E+051,25E+061,00E+0224
первый график линейный линейныйлинейныйлинейный
блоквторой график дополнение
B1 3D поверхность (~1/1000) на первом графике - отобразить границы дисперсии (квадрат отклонения случайной величины)
B2 тепловая карта на первом графике - найти в массиве сгенерированных данных для первой части для всех m – испытаний, точки верхнего предельного отклонения, и отобразить их для каждого m/100 матроса
B3 график с накоплением на первом графике - найти в массиве сгенерированных данных для первой части для всех m – испытаний, точки нижнего предельного отклонения и отобразить их для каждого m/10 матроса
B4 контурная карта (~1/500) в третьем графическом окне построить график испытания (содержащий максимальное верхнее/нижнее предельное отклонение из всех m-испытаний), в том же коде. (таким образом дописать код, чтобы при повторной компиляции график строился автоматически)

Дисперсия

Sn=a1+a2+a3+...+anS_{n}=a_{1}+a_{2}+a_{3}+...+a_{n}


где: an - отклонение на шаге (1 / -1; p /1-p; 0.5/0.5)


для усреднения умножим Sn само на себя


(Sn)2=[a12a1a2...a1ana2a1a22...a2an.........ana1ana2...an2](S_{n})^{2}=\begin{bmatrix} a_{1}^{2} & a_{1}a_{2} & ... & a_{1}a_{n} \\ a_{2}a_{1} & a_{2}^{2} & ... & a_{2}a_{n} \\ ... & ... & \ddots & ... \\ a_{n}a_{1} & a_{n}a_{2} & ... & a_{n}^{2} \\ \end{bmatrix}


где: a12=[12;12]a_{1}^{2} = [-1^{2}; 1^{2}] a1a2=[11;11;11;11]a_{1}a_{2} = [-1*-1; -1*1; 1*-1; 1*1]


с учетом результатов суммы получатся:


Sn2=[10...001...0.........00...1]\left\langle S_{n} \right\rangle^{2}=\begin{bmatrix} 1 & 0 & ... & 0 \\ 0 & 1 & ... & 0 \\ ... & ... & \ddots & ... \\ 0 & 0 & ... & 1 \\ \end{bmatrix}


средний квадрат отклонения (дисперсия) Sn2=N\left\langle S_{n} \right\rangle^{2} =N


среднеквадратичное отклонение σ=n\sigma=\sqrt{n}


доп.материал

Поиск минимальных/максимальных значений


для матрицы кумулятивных сумм

y=cumsum(siqnum);


определить минимальное(максимальное) значение и получить его индекс

[P1,I1]=min(y);


  • P1 будет содержать само минимальное значение
  • I1 будет содержать индекс, где это минимальное значение находится
далее если неоходимо
isk1=min(P1); минимальное значение, но теперь уже в массиве P1

ВариантЗадания А Задания B
1 / 17 A1 B1
2 / 18 A2 B2
3 / 19 A3 B3
4 / 20 A4 B4
5 / 21 A1 B1
6 / 22 A2 B2
7 / 23 A3 B3
8 / 24 A4 B4
9 / 25 A1 B1
10 / 26 A1 B2
11 / 27 A2 B2
12 / 28 A3 B3
13 / 29 A4 B4
14 / 30 A1 B1
15 / 31 A3 B3
16 / 32 A4 B4
Made on
Tilda