2014 dxdy logo

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

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




Начать новую тему Ответить на тему На страницу 1, 2  След.
 
 Матлаб: проверка коллинеарности векторов зад-х в символ.виде
Сообщение17.07.2021, 12:03 


26/09/17
341
Реализовал функцию для проверки коллинеарности двух векторов размерности 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 
Заслуженный участник
Аватара пользователя


23/07/08
10908
Crna Gora
Возможно, надо пояснить, что в решаемой задаче оба вектора $A,B$ двумерны. Индексы массивов принимают только значения $1$ и $2$.
И, если я правильно понимаю, в тестовых примерах не должно быть переменных-параметров (такой случай тоже можно представить). Скажем, $A=(\cos \varphi, \sin\varphi), B=(1, \tg\varphi)$.

 Профиль  
                  
 
 Re: Матлаб: проверка коллинеарности векторов зад-х в символ.виде
Сообщение17.07.2021, 12:45 


26/09/17
341
Я сразу указал, что функция обрабатывает векторы "размерности 2".
Да, трестируемые вектора должны быть заданы в символьном виде, но не содержать переменных.
Спасибо за уточнение.

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


23/07/08
10908
Crna Gora
А, простите, я страшно невнимательный.

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


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

 Профиль  
                  
 
 Re: Матлаб: проверка коллинеарности векторов зад-х в символ.виде
Сообщение17.07.2021, 13:05 


26/09/17
341
Я уже задействовал simplify (см. код функции).
Да, я примерно так и предполагал, но очень уж я "тупой" - нужно об стенку лбом удариться, чтобы понять. Поэтому и нужен пример двух коллинеарных векторов, с которыми эта функция не справляется.

 Профиль  
                  
 
 Re: Матлаб: проверка коллинеарности векторов зад-х в символ.виде
Сообщение17.07.2021, 13:11 
Аватара пользователя


11/06/12
10390
стихия.вздох.мюсли
maximkarimov в сообщении #1526405 писал(а):
Я уже задействовал simplify (см. код функции).
Прошу прощения, я тоже страшно невнимателен.

 Профиль  
                  
 
 Re: Матлаб: проверка коллинеарности векторов зад-х в символ.виде
Сообщение17.07.2021, 13:18 


26/09/17
341
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 
Заслуженный участник
Аватара пользователя


11/04/08
2748
Физтех
Антипример придумать не получилось, но Вы всегда можете повысить шансы на работу алгоритма, задав число итераций функции Simplify:

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

 Профиль  
                  
 
 Re: Матлаб: проверка коллинеарности векторов зад-х в символ.виде
Сообщение17.07.2021, 14:34 


26/09/17
341
Повысить именно шансы получения верного решения или скорость?

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


11/04/08
2748
Физтех
Повысить шансы получения верного решения. С увеличением числа итераций в Simplify работа этой функции замедляется.

 Профиль  
                  
 
 Re: Матлаб: проверка коллинеарности векторов зад-х в символ.виде
Сообщение17.07.2021, 14:58 


26/09/17
341
Спасибо! Еще добавил 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 
Заслуженный участник


12/07/07
4522
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 


26/09/17
341
Да, вижу где функция не справляется, спасибо!
А можно ли ее доработать чтоб в подобных случаях получать верный результат?

 Профиль  
                  
 
 Re: Матлаб: проверка коллинеарности векторов зад-х в символ.виде
Сообщение17.07.2021, 22:27 
Заслуженный участник


12/07/07
4522
«Это не баг, а фича.»
В 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  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group