Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблемы с перегрузкой операторов. 
V
    Опции темы
Elfet
  Дата 19.4.2010, 13:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



Всем привет! 

Столкнулся с непонятной мне проблемой при перегрузке операторов. Пожалуйста, помогите разобраться! 

Вот у меня есть класс матрицы:
Код

#ifndef MATRIX_H
#define MATRIX_H

#include <ostream>
using namespace std;

#include <linalg.h>

class Matrix
{
private:
    ap::real_2d_array data;
public:
    Matrix()
    {
    }

    Matrix(int size1, int size2)
    {
        data.setlength(size1, size2);
    }

    Matrix(const Matrix &rhs) : data(rhs.data)
    {
    }

    int size1()
    {
        return data.getnumrows();
    }

    int size2()
    {
        return data.getnumcolumns();
    }

    const Matrix& operator=(const Matrix &rhs)
    {
        data = rhs.data;
        return *this;
    }

    const double& operator()(int i1, int i2) const
    {
        return data(i1, i2);
    }

    double& operator()(int i1, int i2)
    {
        return data(i1, i2);
    }

    friend ostream & operator&(ostream & out, Matrix & data);
    friend ostream & operator<<(ostream & out, Matrix & data);

    friend Matrix operator+(Matrix & obj1, Matrix & obj2);
    friend Matrix operator-(Matrix & obj1, Matrix & obj2);
    friend Matrix operator*(double s, Matrix & o);
};

inline ostream & operator<<(ostream & out, Matrix & d)
{
    out << "Matrix " << d.size1() << "x" << d.size1() << ":" << endl;
    for(int i = 0; i < d.size1(); i++)
    {
        for(int j = 0; j < d.size2(); j++)
        {
            out << " " << d(i, j);
        }
        out << endl;
    }
    return out;
}

inline ostream & operator&(ostream & out, Matrix & d)
{
    out << "{";
    for(int i = 0; i < d.size1(); i++)
    {
        out << "{";
        for(int j = 0; j < d.size2(); j++)
        {
            if(j != 0)
                out << ",";
            out << d(i, j);
        }
        out << "}";
        if(i != d.size1() - 1)
            out << ",";
    }
    out << "}";
    return out;
}

inline Matrix operator+(Matrix & obj1, Matrix & obj2)
{
    Matrix n(obj1.size1(), obj1.size2());
    matrixadd(obj1.data, obj2.data, n.data);
    return n;
}

inline Matrix operator-(Matrix & obj1, Matrix & obj2)
{
    Matrix n(obj1.size1(), obj1.size2());
    matrixsubtract(obj1.data, obj2.data, n.data);
    return n;
}

inline Matrix operator*(double s, Matrix & o)
{
    Matrix n(o.size1(), o.size2());

    for(int i = 0; i < o.size1(); i++)
    {
        for(int j = 0; j < o.size2(); j++)
        {
            n(i, j) = s * o(i, j);
        }
    }
    return n;
}

#endif // MATRIX_H



В нём я переопределил операции:
Цитата
m+m
m-m
2*m


Однако вот такое вот выражение не хочет компилироваться :
Код

Matrix n;
n = m - 2 * m;


Говорит:
Цитата
D:/Qt/tvmet/main.cpp:57: error: no match for 'operator-' in 'm - operator*(double, Matrix&)(((Matrix&)(& m)))'


Что делать? 

Заранее спасибо!


--------------------
PM MAIL WWW Skype   Вверх
W4FhLF
Дата 19.4.2010, 13:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 2
Всего: 121



Код

Matrix n;
n = m - m * 2;



--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
Elfet
Дата 19.4.2010, 13:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



W4FhLF, 
Цитата
D:/Qt/tvmet/main.cpp:57: error: no match for 'operator-' in 'm - operator*(Matrix&, double)(2.0e+0)'



--------------------
PM MAIL WWW Skype   Вверх
W4FhLF
Дата 19.4.2010, 13:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 2
Всего: 121



Ну так определи оператор. smile Компилятор же всё сказал. 

Код

inline Matrix operator*(Matrix & o, double s)
{
    Matrix n(o.size1(), o.size2());

    for(int i = 0; i < o.size1(); i++)
    {
        for(int j = 0; j < o.size2(); j++)
        {
            n(i, j) = s * o(i, j);
        }
    }
    return n;
}



--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
azesmcar
Дата 19.4.2010, 13:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Elfet

Переделай операторы, пусть принимают не ссылку на Matrix а константную ссылку, в результате m * 2 получается temporary object (поскольку оператор * возвращает объект по значению), который не передается в виде ссылки. Да...и почему функции size1(), size2() не константны?
PM   Вверх
W4FhLF
Дата 19.4.2010, 13:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 2
Всего: 121



лучше так:

Код

inline Matrix operator*(const Matrix & o, const double s)
{
    Matrix n(o.size1(), o.size2());

    for(int i = 0; i < o.size1(); i++)
    {
        for(int j = 0; j < o.size2(); j++)
        {
            n(i, j) = s * o(i, j);
        }
    }
    return n;
}



--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
azesmcar
Дата 19.4.2010, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



W4FhLF

Так ведь есть же такой оператор.
PM   Вверх
toxx
Дата 19.4.2010, 13:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 653
Регистрация: 4.3.2009
Где: НН

Репутация: 4
Всего: 13



Код

inline Matrix operator*(double s, const Matrix & o)

Код

inline Matrix operator-(const Matrix & obj1,const Matrix & obj2)

Попробуй так

Это сообщение отредактировал(а) toxx - 19.4.2010, 13:35
PM MAIL   Вверх
Elfet
Дата 19.4.2010, 13:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



Ок, всем спасибо!

Вот что получилось:
Код

#ifndef MATRIX_H
#define MATRIX_H

#include <ostream>
using namespace std;

#include <linalg.h>

class Matrix
{
private:
    ap::real_2d_array data;
public:
    Matrix()
    {
    }

    Matrix(int size1, int size2)
    {
        data.setlength(size1, size2);
    }

    Matrix(const Matrix &rhs) : data(rhs.data)
    {
    }

    const int size1() const
    {
        return data.getnumrows();
    }

    const int size2() const
    {
        return data.getnumcolumns();
    }

    const Matrix& operator=(const Matrix &rhs)
    {
        data = rhs.data;
        return *this;
    }

    const double& operator()(int i1, int i2) const
    {
        return data(i1, i2);
    }

    double& operator()(int i1, int i2)
    {
        return data(i1, i2);
    }

    friend ostream & operator&(ostream & out, const Matrix & data);
    friend ostream & operator<<(ostream & out, const Matrix & data);

    friend Matrix operator-(const Matrix & o);

    friend Matrix operator+(const Matrix & obj1, const Matrix & obj2);
    friend Matrix operator-(const Matrix & obj1, const Matrix & obj2);
    friend Matrix operator*(const double s, const Matrix & o);
    friend Matrix operator*(const Matrix & o,  const double s);
    friend Matrix operator/(const Matrix & o, const double s);
};

inline ostream & operator<<(ostream & out, const Matrix & d)
{
    out << "Matrix " << d.size1() << "x" << d.size1() << ":" << endl;
    for(int i = 0; i < d.size1(); i++)
    {
        for(int j = 0; j < d.size2(); j++)
        {
            out << " " << d(i, j);
        }
        out << endl;
    }
    return out;
}

inline ostream & operator&(ostream & out, const Matrix & d)
{
    out << "{";
    for(int i = 0; i < d.size1(); i++)
    {
        out << "{";
        for(int j = 0; j < d.size2(); j++)
        {
            if(j != 0)
                out << ",";
            out << d(i, j);
        }
        out << "}";
        if(i != d.size1() - 1)
            out << ",";
    }
    out << "}";
    return out;
}

inline Matrix operator-(const Matrix & o)
{
    return -1 * o;
}

inline Matrix operator+(const Matrix & obj1, const Matrix & obj2)
{
    Matrix n(obj1.size1(), obj1.size2());
    matrixadd(obj1.data, obj2.data, n.data);
    return n;
}

inline Matrix operator-(const Matrix & obj1, const Matrix & obj2)
{
    Matrix n(obj1.size1(), obj1.size2());
    matrixsubtract(obj1.data, obj2.data, n.data);
    return n;
}

inline Matrix operator*(const double s, const Matrix & o)
{
    Matrix n(o.size1(), o.size2());

    for(int i = 0; i < o.size1(); i++)
    {
        for(int j = 0; j < o.size2(); j++)
        {
            n(i, j) = s * o(i, j);
        }
    }
    return n;
}

inline Matrix operator*(const Matrix & o, const double s)
{
    return s * o;
}

inline Matrix operator/(const Matrix & o, const double s)
{
    Matrix n(o.size1(), o.size2());

    for(int i = 0; i < o.size1(); i++)
    {
        for(int j = 0; j < o.size2(); j++)
        {
            n(i, j) = o(i, j) / s;
        }
    }
    return n;
}

#endif // MATRIX_H



Где бы мне почитать чего-нибудь про все эти константные ссылки и прочие константы? smile Когда-то препод рассказывал про всё это, но всё уже забылось.


--------------------
PM MAIL WWW Skype   Вверх
azesmcar
Дата 19.4.2010, 13:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Цитата(Elfet @  19.4.2010,  13:42 Найти цитируемый пост)
Где бы мне почитать чего-нибудь про все эти константные ссылки и прочие константы? smile Когда-то препод рассказывал про всё это, но всё уже забылось. 

Статуструп, Майерс.

Добавлено через 2 минуты и 46 секунд
Цитата(Elfet @  19.4.2010,  13:42 Найти цитируемый пост)
const int size2() const

const int вовсе не обязателен, можно просто int, это ничего не меняет.

Цитата(Elfet @  19.4.2010,  13:42 Найти цитируемый пост)
const double s

тут тоже самое.

а вообще если изменения не планируются то ставь константу smile 
PM   Вверх
Elfet
Дата 19.4.2010, 13:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



протестировал мой класс в сравнении с uBLAS:
 
Матрицы размером 4х4, 1000000 итераций

вот что получилось:

операция: n = m + m;
CPU time for uBLAS = 1.357
CPU time for Matrix = 0.889


операция: n = 2 * m - m;
CPU time for uBLAS = 1.607
CPU time for Matrix = 1.404


операция: n = 2 * m + m / 3.3 - 0.1 * -m;
CPU time for uBLAS = 2.854
CPU time for Matrix = 3.682

Очёнь странно, получается. Мне нужно сделать так что бы мой класс обгонял uBLAS.

Добавлено через 12 минут и 55 секунд

операция:   n = 2*m;
            n = m - n;
CPU time for uBLAS = 2.761
CPU time for Matrix = 1.778


--------------------
PM MAIL WWW Skype   Вверх
W4FhLF
Дата 19.4.2010, 15:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 2
Всего: 121



Ну так у тебя обгоняет везде, кроме:

Код

n = 2 * m + m / 3.3 - 0.1 * -m;


А это скорее всего из-за временных копий объектов, которые образуются на промежуточных этапах вычисления. 

У тебя дефайн:

Код

#define NO_AP_ASSERT


Есть?


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
Elfet
Дата 19.4.2010, 15:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



ага, есть. И у буста тоже стоит: 
Код

#define BOOST_UBLAS_NDEBUG 1


Добавлено через 1 минуту и 23 секунды
Порылся в uBLAS-е, у них там есть какие-то классы matrix_expression<AE> - возможно как-то хитро через них сделано. Понять бы как smile


--------------------
PM MAIL WWW Skype   Вверх
W4FhLF
Дата 19.4.2010, 15:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 2
Всего: 121



В uBLAS'е хорошо оптимизированы типовые выражения типа xGEMM. Возможно они как раз этими классами представлены. 

Но вот интересно, если твою формулу переписать двойным циклом типа:

Код

for(i:rows)
  for(j:cols)
  {
    v = m(i, j);
    n(i, j) = 2 * v + v / 3.3 - 0.1 * -v;
  }



сколько будет по времени?


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
Elfet
Дата 19.4.2010, 21:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



Гораздо быстрее:
Цитата
CPU time for uBLAS = 3.479
CPU time for Matrix = 3.682
CPU time for For,For = 0.514


Интересно, можно ли как-нибудь ускорить мой класс?

Добавлено через 13 минут и 11 секунд
Вот что я могу придумать  smile  :
Код

#define MatrixExpValue(n, m, exp, value) \
for(unsigned i = 0; i < m.size1(); i++)  \
for(unsigned j = 0; j < m.size2(); j++){ \
    double value = m(i, j); \
    n(i, j) = exp; \
}
#define MatrixExp(n, m, exp) MatrixExpValue(n, m, exp, v)


Пример использования:
Код

        Matrix n;
        n = m + 2 * m - -m*0.1;
        cout << n;

        Matrix n2(m.size1(), m.size2());
        MatrixExp(n2, m, v + 2 * v - -v*0.1)
        cout << n2;



--------------------
PM MAIL WWW Skype   Вверх
Elfet
Дата 19.4.2010, 22:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



 smile  smile  smile 
Код

#define MatrixExp(n, exp) \
for(unsigned i = 0; i < n.size1(); i++)  \
for(unsigned j = 0; j < n.size2(); j++) \
    n(i, j) = exp;



--------------------
PM MAIL WWW Skype   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0673 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.