2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




На страницу 1, 2  След.
 
 Матлаб: проверка коллинеарности векторов зад-х в символ.виде
Сообщение17.07.2021, 12:03 
Реализовал функцию для проверки коллинеарности двух векторов размерности 2 заданных в символьном виде:
Используется синтаксис Matlab M
function [res] = checkCollinear(A,B)
% если res==1, то коллинеарны, res==0 - нет
с=simplify(A(1)*B(2)-A(2)*B(1));
if с==0
    res=1;
else
    res=0;
end
end
 
Пример ее работы (A и B заданы в символьном виде):
код: [ скачать ] [ спрятать ]
Используется синтаксис Matlab M
>> A
 
A =
 
[ sin(1) + 2*sin(1/2) + 3*sin(1/3), sin(1) + 2*sin(1/2)]
 
>> B
 
B =
 
[ sin(1)/5 + (2*sin(1/2))/5 + (3*sin(1/3))/5, sin(1)/5 + (2*sin(1/2))/5]
 
>> checkCollinear(A,B)

ans =

     1
 
Однако нет уверенности в том, что Матлаб сумеет приравнять к 0 любое сложное символьное выражение.
Прошу предложить для проверки пару заковыристых, но заведомо коллинеарных векторов (в символьном виде) чтобы потестить эту функцию и, возможно, улучшить ее.
Спасибо!

 
 
 
 Re: Матлаб: проверка коллинеарности векторов зад-х в символ.виде
Сообщение17.07.2021, 12:42 
Аватара пользователя
Возможно, надо пояснить, что в решаемой задаче оба вектора $A,B$ двумерны. Индексы массивов принимают только значения $1$ и $2$.
И, если я правильно понимаю, в тестовых примерах не должно быть переменных-параметров (такой случай тоже можно представить). Скажем, $A=(\cos \varphi, \sin\varphi), B=(1, \tg\varphi)$.

 
 
 
 Re: Матлаб: проверка коллинеарности векторов зад-х в символ.виде
Сообщение17.07.2021, 12:45 
Я сразу указал, что функция обрабатывает векторы "размерности 2".
Да, трестируемые вектора должны быть заданы в символьном виде, но не содержать переменных.
Спасибо за уточнение.

 
 
 
 Re: Матлаб: проверка коллинеарности векторов зад-х в символ.виде
Сообщение17.07.2021, 12:49 
Аватара пользователя
А, простите, я страшно невнимательный.

 
 
 
 Re: Матлаб: проверка коллинеарности векторов зад-х в символ.виде
Сообщение17.07.2021, 12:58 
Аватара пользователя
maximkarimov в сообщении #1526397 писал(а):
Однако нет уверенности в том, что Матлаб сумеет приравнять к 0 любое сложное символьное выражение.
А это в принципе неразрешимая проблема. В теории, разумеется.
В Матлабе есть какие-нибудь вспомогательные функции для упрощения выражений? Например, в Математике есть Simplify и FullSimplify.

 
 
 
 Re: Матлаб: проверка коллинеарности векторов зад-х в символ.виде
Сообщение17.07.2021, 13:05 
Я уже задействовал simplify (см. код функции).
Да, я примерно так и предполагал, но очень уж я "тупой" - нужно об стенку лбом удариться, чтобы понять. Поэтому и нужен пример двух коллинеарных векторов, с которыми эта функция не справляется.

 
 
 
 Re: Матлаб: проверка коллинеарности векторов зад-х в символ.виде
Сообщение17.07.2021, 13:11 
Аватара пользователя
maximkarimov в сообщении #1526405 писал(а):
Я уже задействовал simplify (см. код функции).
Прошу прощения, я тоже страшно невнимателен.

 
 
 
 Re: Матлаб: проверка коллинеарности векторов зад-х в символ.виде
Сообщение17.07.2021, 13:18 
svv в сообщении #1526401 писал(а):
если я правильно понимаю, в тестовых примерах не должно быть переменных-параметров (такой случай тоже можно представить). Скажем, $A=(\cos \varphi, \sin\varphi), B=(1, \tg\varphi)$.

Кстати, с приведенными Вами векторами, которые содержат переменную $\varphi$, функция справилась:
код: [ скачать ] [ спрятать ]
Используется синтаксис Matlab M
>> syms x
>> A=[cos(x) sin(x)]
 
A =
 
[ cos(x), sin(x)]
 
>> B=[sym(1) tan(x)]
 
B =
 
[ 1, tan(x)]
 
>> checkCollinear(A,B)

ans =

     1
(если убрать simplify, то не справляется).

 
 
 
 Re: Матлаб: проверка коллинеарности векторов зад-х в символ.виде
Сообщение17.07.2021, 14:23 
Аватара пользователя
Антипример придумать не получилось, но Вы всегда можете повысить шансы на работу алгоритма, задав число итераций функции Simplify:

Используется синтаксис Matlab M
c = simplify(A(1)*B(2)-A(2)*B(1),'Steps',100);
 

 
 
 
 Re: Матлаб: проверка коллинеарности векторов зад-х в символ.виде
Сообщение17.07.2021, 14:34 
Повысить именно шансы получения верного решения или скорость?

 
 
 
 Re: Матлаб: проверка коллинеарности векторов зад-х в символ.виде
Сообщение17.07.2021, 14:47 
Аватара пользователя
Повысить шансы получения верного решения. С увеличением числа итераций в Simplify работа этой функции замедляется.

 
 
 
 Re: Матлаб: проверка коллинеарности векторов зад-х в символ.виде
Сообщение17.07.2021, 14:58 
Спасибо! Еще добавил expand (перед simplify):
Используется синтаксис Matlab M
function [res] = checkCollinear(A,B)
% проверка коллинеарности двух векторов размерности 2 заданных в символьном виде
% если res=1, то A и В коллинеарны, если res=0 - нет
eq=expand(A(1)*B(2)-A(2)*B(1));
res=simplify(eq, 'Steps',10);
if res==0
    res=1;
else
    res=0;
end
end

 
 
 
 Re: Матлаб: проверка коллинеарности векторов зад-х в символ.виде
Сообщение17.07.2021, 20:21 
1. По поводу текста функции. Функция из начального сообщения возвращает double array, а по смыслу должна — logical. Можно подправить на
Используется синтаксис Matlab M
function [res] = checkCollinear(A,B)
% если res==1, то коллинеарны, res==0 - нет
 c =simplify(A(1)*B(2)-A(2)*B(1));
 if c ==0
    res=true;
 else
    res=false;
 end
end
 
Смысла в данном случае в таком подходе нет. Удобней возвращать результат сравнения (и добавит проверку с генерацией ошибки)
Используется синтаксис Matlab M
function [res] = checkCollinear(A,B)
% если res==1, то коллинеарны, res==0 - нет
 res = simplify(A(1)*B(2)-A(2)*B(1)) == 0;
 if  ~islogical(res)
  error('res checkCollinear not logical')
 end    
end
Если проверка на то, что результат является logical не делается, то можно просто задать анонимной
>> checkCollinear = @(A,B) simplify(A(1)*B(2)-A(2)*B(1)) == 0;
Если есть уверенность в том, что результат сравнения будет логическим, и он действительно должен быть double array, то можно просто преобразовать.
>> checkCollinear = @(A,B) double(simplify(A(1)*B(2)-A(2)*B(1)) == 0);

2. По поводу примеров. В простейших случаях можно столкнуться с тем, что главное значение не соответствует значению, предполагаемому пользователем. Вот тривиальный пример (Matlab 2013b)
Используется синтаксис Matlab M
>> A = sym([1, 1]); B = sym([(-1)^(1/3), -1]);
>> CC = checkCollinear(A,B)
CC = - (3^(1/2)*i)/2 - 3/2 == 0
(Конечно, в практически интересных случаях это будет «замаскировано».)
Что-то ещё встречалось. Если вспомню, то добавлю.

 
 
 
 Re: Матлаб: проверка коллинеарности векторов зад-х в символ.виде
Сообщение17.07.2021, 20:46 
Да, вижу где функция не справляется, спасибо!
А можно ли ее доработать чтоб в подобных случаях получать верный результат?

 
 
 
 Re: Матлаб: проверка коллинеарности векторов зад-х в символ.виде
Сообщение17.07.2021, 22:27 
«Это не баг, а фича.»
В Maple в подобных ситуациях (если абстрагироваться от примитивных случаев, где проблема преодолевается при помощи surd) иногда проблему можно решить при помощи RealDomain.

У меня старая версия Matlab. В новых версиях, вроде, появились какие-то возможности. Но я с этим не знаком. Будем надеяться, что откликнуться специалисты/любители Matlab. Мне также было бы интересно почитать.

PS. surd есть даже в версии Matlab 2013b.
Можно действительные значения корней получать при помощи этой функции
Используется синтаксис Matlab M
>> evalin(symengine,'surd(-27, 3)')
ans = -3
Итого
Используется синтаксис Matlab M
>> A = [1, 1];
>> B = sym([evalin(symengine,'surd(-27, 3)'), -3]);
>> checkCollinear(A,B)
ans = 1
Можно и solve(… real) использовать. Но, в общем случае, это проблему не решает.

 
 
 [ Сообщений: 17 ]  На страницу 1, 2  След.


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group