Russian Qt Forum
Июнь 15, 2024, 23:05 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: Передача параметров/аргументов  (Прочитано 17432 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #15 : Август 29, 2009, 17:14 »

Ну и в чем прикол? Не вижу особой разницы.
Разве что
void InvertMatrix( Matrix * theInvertedMatrix, const Matrix * theSourceMatrix );
Лучше чем
void InvertMatrix( Matrix * theInvertedMatrix, Matrix theSourceMatrix );
с точки зрения оптимизации.
В последнем случае - может возникнуть лишнее копирование структуры

Для приколов есть другие threads. Здесь же (увы) прийдется все разжевывать. Часто (в большинстве случаев)  нужно инвертировать матрицу "на месте". В этом случае theInvertedMatrix и theSourceMatrix указывают на тот же адрес. При передаче обеих матриц по адресу/ссылке надо это предусмотреть:

Код:
void InvertMatrix( Matrix * theInvertedMatrix, const Matrix * theSourceMatrix )
{
   Matrix temp;
   if (theInvertedMatrix == theSourceMatrix) {
     temp = *theSourceMatrix;
     theSourceMatrix = &temp;
   }
  
// теперь инвертируем Гауссом и.т.п.
   ....
}

А он просто сказал компилятору то же сделать  и спокойно вызывает

Код:
Matrix M = ...
...
InvertMatrix(&M, M):
« Последнее редактирование: Август 29, 2009, 18:16 от Igors » Записан
spectre71
Гость
« Ответ #16 : Август 29, 2009, 18:28 »

Как я и сказал:
void InvertMatrix( Matrix * theInvertedMatrix, Matrix theSourceMatrix );
ничего особенного, тем более оптимального нет, только лишнее копирование матрицы!

Правильнее и наиболее оптимально:
Код:
void InvertMatrix(Matrix& theInvertedMatrix, const Matrix* theSourceMatrix=NULL)
{
   if (theSourceMatrix && theSourceMatrix != &theInvertedMatrix) {theInvertedMatrix= *theSourceMatrix;}

// invert matrix  theInvertedMatrix

}

InvertMatrix(M) <=> InvertMatrix(M, &M)  <=>  InvertMatrix(M, NULL) - и нет лишнего копирования матрицы
InvertMatrix(M, &N) - где M != N, одно копирование матрицы

Я не знаю алгоритма которым в данном случае инвертируется матрица.
То что я привел оптимально для случая когда работа может быть произведена с одной матрицей, если это не так то я не прав.
В любом случае припостановке задачи нужно описывать исходные условия.
« Последнее редактирование: Август 29, 2009, 18:51 от Spectre » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #17 : Август 29, 2009, 19:03 »

Правильнее и наиболее оптимально:
Код:
void InvertMatrix(Matrix& theInvertedMatrix, const Matrix* theSourceMatrix=NULL)
{
   if (theSourceMatrix && theSourceMatrix != &theInvertedMatrix) {theInvertedMatrix= *theSourceMatrix;}

// invert matrix  theInvertedMatrix

}
Так сходу не получается  Улыбающийся Defaulrt NULL не имеет смысла, нет исходной матрицы - нечего инвертировать. Присвоение theInvertedMatrix ничего не дает т.к. theInvertedMatrix должна (довольно тщательно) вычисляться. Логика мало изменилась со времен Аристотеля - и она столь же неумолима (знание классов мало помогает :-)) 
Записан
spectre71
Гость
« Ответ #18 : Август 29, 2009, 19:24 »

Так сходу не получается  Улыбающийся Defaulrt NULL не имеет смысла, нет исходной матрицы - нечего инвертировать. Присвоение theInvertedMatrix ничего не дает т.к. theInvertedMatrix должна (довольно тщательно) вычисляться. Логика мало изменилась со времен Аристотеля - и она столь же неумолима (знание классов мало помогает :-))  
Я написал что не знаю используемого алгоритма для инвертирования и в данном случае это не важно.
Важно оно производиться с использаванием одной или двух матриц.
Если одной, то выше я привел оптимальный вариант.
Если двух(требуется неизменненная исходная матрица), то лучше будет так:
Код:
void InvertMatrix(Matrix& theInvertedMatrix, const Matrix* theSourceMatrix=NULL)
{
   const Matrix* src;
   if (theSourceMatrix && theSourceMatrix != &theInvertedMatrix) {
     src = theSourceMatrix;
   } else {
     src = new Matrix(theInvertedMatrix); //copy theInvertedMatrix
   }

// invert matrix
// use src instead theSourceMatrix

  if(src != theSourceMatrix) {delete src;}
}

Опять же имем
InvertMatrix(M) <=> InvertMatrix(M, &M)  <=>  InvertMatrix(M, NULL) - инвертирование самой себя
InvertMatrix(M, &N) - где M != N, нет лишнего копирования матрицы

=====

Default NULL - для простой записи в случае инвертирования самой себя  - InvertMatrix(M), вместо InvertMatrix(M, &M)
« Последнее редактирование: Август 29, 2009, 19:46 от Spectre » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #19 : Август 30, 2009, 10:00 »

Вызов new/delete гораздо дороже чем передача структуры по значению. Само инвертирование довольно сложное, больше 100 строк, поэтому надо держать его в 1 функции. Разумеется, Ваш и мой варианты будут работать, но согласитесь: ковбой из Колорадо написал короче/проще  Улыбающийся   
Записан
spectre71
Гость
« Ответ #20 : Август 30, 2009, 10:42 »

Вызов new/delete гораздо дороже чем передача структуры по значению. Само инвертирование довольно сложное, больше 100 строк, поэтому надо держать его в 1 функции. Разумеется, Ваш и мой варианты будут работать, но согласитесь: ковбой из Колорадо написал короче/проще  Улыбающийся   
Не соглашусь, здесь нет ничего особенного, это дело вкуса.
Я бы однозначно оставил свой вариант объвления он мне кажется удобнее в использовании.
void InvertMatrix(Matrix& theInvertedMatrix, const Matrix* theSourceMatrix=NULL);
А написать лишнюю проверку не проблема, можно и не заморочиваться с псевдооптимизацией, а тупо создавать копию нужной матрицы.
Код:
   Matrix src;
   if (theSourceMatrix && theSourceMatrix != &theInvertedMatrix) {
     src = theSourceMatrix;
   } else  {
     src = theInvertedMatrix;
   }
Записан
Winstrol
Гость
« Ответ #21 : Август 30, 2009, 23:21 »

Часто (в большинстве случаев)  нужно инвертировать матрицу "на месте".
Не так уж и часто. В мат. библиотеках (BLAS,LAPACK)  функции инвертации "на месте" вовсе нет.

Записан
Winstrol
Гость
« Ответ #22 : Август 30, 2009, 23:26 »

Чтоб можно было указать исходную матрицу в качестве результирующей.
Прямое попадание. все правильно. Поздравляю! 
А почему не пара функций?

void InvertMatrix( Matrix * theInvertedMatrix, const Matrix * theSourceMatrix );
Matrix InvertMatrix(const Matrix * theSourceMatrix )
Записан
spectre71
Гость
« Ответ #23 : Август 31, 2009, 00:48 »

А почему не пара функций?
void InvertMatrix( Matrix * theInvertedMatrix, const Matrix * theSourceMatrix );
Matrix InvertMatrix(const Matrix * theSourceMatrix )

Matrix InvertMatrix(const Matrix * theSourceMatrix )
Хуже чем:
InvertMatrix(Matrix * theMatrix) или InvertMatrix(Matrix & theMatrix)
Поскольку получаем дополнительное копирование матрицы при возврате.
=====
Далее: пара функций
void InvertMatrix( Matrix * theInvertedMatrix, const Matrix * theSourceMatrix );
void InvertMatrix(Matrix * theMatrix)
Не лучше чем
void InvertMatrix( Matrix * theInvertedMatrix, const Matrix * theSourceMatrix=NULL);
Поскольку
void InvertMatrix( Matrix * theInvertedMatrix, const Matrix * theSourceMatrix=NULL);
перекрывает эту пару!
Кроме того, для
void InvertMatrix( Matrix * theInvertedMatrix, const Matrix * theSourceMatrix );
все равно необходимо проверять(и правильно обрабатывать) случай, когда theInvertedMatrix == theSourceMatrix
Записан
Winstrol
Гость
« Ответ #24 : Август 31, 2009, 13:46 »

InvertMatrix(Matrix * theMatrix) или InvertMatrix(Matrix & theMatrix)
Поскольку получаем дополнительное копирование матрицы при возврате.
Для такого простого случая, когда Matrix - структура в стиле C без плюсов, слава Богу, не будет.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #25 : Август 31, 2009, 15:08 »

А почему не пара функций?

void InvertMatrix( Matrix * theInvertedMatrix, const Matrix * theSourceMatrix );
Matrix InvertMatrix(const Matrix * theSourceMatrix )

Потому что само инвертирование довольно длинное/сложное и писать его дважды нехорошо
Записан
BlackTass
Гость
« Ответ #26 : Август 31, 2009, 17:17 »

Потому что само инвертирование довольно длинное/сложное и писать его дважды нехорошо
а кто-то говорил о дублировании кода разве? просто одна вызывает другую
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #27 : Август 31, 2009, 17:36 »

а кто-то говорил о дублировании кода разве? просто одна вызывает другую
Кто ж спорит, конечно можно. Но как ни крути, а строк 5 Вам для этого прийдется написать. И делать эти строки будут именно то что делает передача структуры по значению  Улыбающийся
Записан
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.048 секунд. Запросов: 23.