Форум программистов, компьютерный форум, киберфорум
Наши страницы
Зосима
Войти
Регистрация
Восстановить пароль
Оценить эту запись

Логические векторы в MATLAB

Запись от Зосима размещена 05.12.2012 в 13:28
Метки matlab

В MATLAB, как и в C/C++ логические переменные легко превращаются в числовые, что открывает широкое поле деятельности. Но если C/C++ обрабатывает массивы поэлементно, то MATLAB счелкает их как орешки!

Пусть задан числовой вектор:

x = [0, 1.2, 2.4, 3.3, 1.05, 7.4];

Тогда результатом сравнения

logic_x = (x<3)

будет вектор такой же длинны:

logic_x = [1 1 1 0 1 0].

Что это нам дает?
Например подсчет кол-ва элементов, удовлетворяющих условию:

n = sum( (x<3) ) = sum([1 1 1 0 1 0]) = 4.

Или нужно этим элементам присвоить некое случайное значенение:

x( x>3 ) = rand(1, sum(x>3));

А если задан массив y = f(x), то также можно записать:

y( x>3 ) = 0;

Подобным образом дело обстоит, если x - многомерный массив(матрица).

А используя лог. операции &(И), |(ИЛИ), ~(НЕ) можно составлять довольно сложные структуры!

Пример: дано натуральное число a, рассчитать сумму его делителей, за исключением самого числа.
Создаем вектор чисел от 1 до a-1:

k = 1:a-1;

Рассчитываем остатки от деления:

ost = mod(a, k);

Рассчитываем логический вектор, где отстаток от деления равен нулю:

isDel = ost==0;

Теперь если поэлементно умножить полученный вектор на вектор чисел k,

Del = isDel.*k;

то в результате неделители числа a станут нулями.
Тогда делители легко вычленить:

Del( Del==0 ) = [];

Теперь и сумму найти не составляет труда:

s = sum(Del);

Однако этот алгоритм можно реализовать еще проще (ведь нулевые элементы сумме не помешают) если применить свойства матричного умножения: элемент равен сумме произведений элементов строки первого на столбец второго вектора. Но для этого нужно, чтобы первый вектор был строкой, а второй - столбцом.
Конструкция типа k = 1:a-1 возвращает вектор-строку, поэтому логический вектор isDel также вектор-строка, поэтому мы его должны транспонировать, тогда получаем:

s = k*isDel'

или одной строкой:

s = (1:a-1)*(mod(a,1:a-1)==0)'

Красота! и мы нигде не использовали циклы и условные операторы!

Еще одним полезным применением логических векторов является:
созднае строчных выражений для кусочных фунций!

Пример: пусть задана кусочная ф-ция:

y = 0, x<=-pi
y = cos(x), -pi<x<0
y = 1, x=0;
y = sin(exp(-x)), x>0


Нужно построить график в диапазоне [-10, 10].

Первым делом задаем вектор значений x, пусть их будет 200, в заданном дианазоне:

x = linspace(-10, 10, 200);

Теперь можно было бы соорудить конструкцию if-else, но мы пойдем другим путем!
Трах тибидох тибидох!

y = 0*(x<=-pi) + cos(x).*( (x>-pi)&(x<0) ) + 1*(x==0) + sin(exp(-x)).*(x>0);

Если выражения для yi или условия x довольно громоздкие, то их можно вычислять постепенно:

inD1 = (x<=-pi);
y1 = 0;
inD2 = (x>-pi)&(x<0);
y2 = cos(x);
inD3 = (x==0);
y3 = 1;
inD4 = ~(inD1 | inD2 | inD3); % если ниодно условие не выполняется
y4 = sin(exp(-x));

Тогда результирующее значение ф-ции

y = y1.*inD1 + y2.*inD2 + y3.*inD3 + y4.*inD4;


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

Тогда уже не составляет труда построить график:
plot(x,y)

Нажмите на изображение для увеличения
Название: 01.png
Просмотров: 757
Размер:	3.4 Кб
ID:	1541

При помощи логических векторов очень удобно моделировать такие хитрые ф-ции как ф-ция Дирака и ф-ция Хевисайда!
Возможно Вы возразите, мол зачем изобретать велосипед, если есть встроенные ф-ции dirac(t) и heaviside(t)?
Однако встроенные ф-ции ведут себя немного не так, как хотелось бы:

в особой точке t=0: dirac(t)=Inf, heaviside(t)=NaN.

Если их использовать при построении графиков, то plot просто проигнорирует такого рода значения!

А чтобы получить нормальную взвешенную дельта-функцию в импульсной характеристике, например, нужно использовать выражение типа (x==0):
h(t) = h(0).*(t==0) + ht>0(t);
Подобным образом моделируется ф-ция Хевисайда, при помощи выражения (x>=0) :
g(t) = g(t).*(t>=0)

Вот как-бы и всё, направление мысли я указал, а дальше все ограничивается только фантазией и законами природы
Спасибо за внимание!
Размещено в Без категории
Просмотров 2857 Комментарии 0
Всего комментариев 0
Комментарии
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru