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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> шаблон функции от вектора 
:(
    Опции темы
kosmonaFFFt
Дата 31.7.2012, 16:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Доброго времени суток...

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

имеется:
Код

using ::std::vector;
using ::std::function;
using ::boost::numeric::ublas::matrix;

typedef double decimal_t;
typedef vector<decimal_t> vector_t;
typedef function<decimal_t(const vector_t&) > multivariate_function_t;
typedef matrix<decimal_t> matrix_t;

...

matrix_t _pts;
vector_t _I;

void _eval_fn_values(const multivariate_function_t& fn)
{
    for (auto row = 0; row < _pts.size1(); ++row)
    {
        matrix_row<matrix_t> point(_pts, row);
        vector_t x(point.begin(), point.end()); // TODO: Try to rewrite this without matrix row copy.
        _I[row] = fn(x);
    }
}


Соотвественно вопрос - можно ли как-нибудь переопределить тип multivariate_function_t, или сделать еще что-нибудь, чтобы избежать копирования данных из строки матрицы в вектор?

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


--------------------
user posted image
PM MAIL ICQ   Вверх
boostcoder
Дата 31.7.2012, 16:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



почему бы в твою multivariate_function_t не передать ссылку на твой matrix_row ?

Добавлено через 6 минут и 13 секунд
кто такой matrix_row ?
PM WWW   Вверх
kosmonaFFFt
Дата 31.7.2012, 17:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(boostcoder @  31.7.2012,  20:54 Найти цитируемый пост)
кто такой matrix_row ? 

Он из boost::numeric::ublas - шаблон, позволяющий получить доступ к строке матрицы.


Цитата(boostcoder @  31.7.2012,  20:54 Найти цитируемый пост)
почему бы в твою multivariate_function_t не передать ссылку на твой matrix_row ?

Потому что уже есть функции, принимающие ссылку на std::vector и работающие с ним.

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


--------------------
user posted image
PM MAIL ICQ   Вверх
boostcoder
Дата 31.7.2012, 17:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(kosmonaFFFt @  31.7.2012,  17:06 Найти цитируемый пост)
Потому что уже есть функции, принимающие ссылку на std::vector и работающие с ним.

ну так ты сейчас лечишь последствия.
меняй реализацию так, чтоб multivariate_function_t принимала ссылку на matrix_row.
или что?

PM WWW   Вверх
kosmonaFFFt
Дата 31.7.2012, 17:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



В идеале хотелось бы, чтобы функция принимала некий обобщенный вектор, который был бы совместим и с std::vector и с matrix_row... Может в boost есть какой-нибудь враппер для stl-совместимых коллекций и можно было бы использовать его?


--------------------
user posted image
PM MAIL ICQ   Вверх
boostcoder
Дата 31.7.2012, 17:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(kosmonaFFFt @  31.7.2012,  16:34 Найти цитируемый пост)
можно ли как-нибудь переопределить тип multivariate_function_t, или сделать еще что-нибудь, чтобы избежать копирования данных из строки матрицы в вектор?

ох и слеп я, слеп %)

да, ты можешь переопределить тип multivariate_function_t при помощи overloaded_function, и тогда multivariate_function_t сможет вызывать перегруженные функции принимающие вектор и matrix_row.

я все правильно понял?

Добавлено @ 17:18
т.е. в итоге получится что-то типа:
Код

typedef boost::overloaded_function<
      decimal_t(const vector_t&)
    , decimal_t(const matrix_row&)
> multivariate_function_t;

..

decimal_t func_for_vector(const vector_t& v) {}
decimal_t func_for_matrix_row(const matrix_row& m) {}

...

multivariate_function_t func(func_for_vector, func_for_matrix_row);

..

_eval_fn_values(func);


Добавлено @ 17:19
Цитата(kosmonaFFFt @  31.7.2012,  17:13 Найти цитируемый пост)
хотелось бы, чтобы функция принимала некий обобщенный вектор, который был бы совместим и с std::vector и с matrix_row.

это вряд ли...
не могу найти доку по matrix_row. дай плиз ссылку ;)

Это сообщение отредактировал(а) boostcoder - 31.7.2012, 17:20
PM WWW   Вверх
kosmonaFFFt
Дата 31.7.2012, 17:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Кажется я уже ближе к решению проблемы, только вот остается проблема работы оптимизатора со старыми функциями, принимающими вектор... Хотелось бы иметь некий абстрактный враппер для stl-совместимых коллекций, но видимо о многом мечтаю...

На крайний случай можно использовать vector<vector<double>> вместо матрицы... )


--------------------
user posted image
PM MAIL ICQ   Вверх
boostcoder
Дата 31.7.2012, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



kosmonaFFFt, повторюсь: ты лечишь последствия. последствия кривого дизайна.
но решать тебе, конечно.

PM WWW   Вверх
kosmonaFFFt
Дата 31.7.2012, 17:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



После Java довольно трудно делать хороший дизайн на C++... Пока еще не очень поздно, хотелось бы данный пункт дизайна вылечить как-нибудь...
boostcoder, интересно твое мнение следующего решения:
переопределить vector_t так, чтобы он мог без сильных накладных расходов враппить (например с помощью специализации шаблона и неявного приведения типов) другие коллекции, предоставляя к ним единый интерфейс...


--------------------
user posted image
PM MAIL ICQ   Вверх
boostcoder
Дата 31.7.2012, 18:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(kosmonaFFFt @  31.7.2012,  17:42 Найти цитируемый пост)
переопределить vector_t

а может проще функцию _eval_fn_values сделать шаблонной принимающей произвольный тип? тогда ее можно будет специализировать по множеству критериев.

PM WWW   Вверх
kosmonaFFFt
Дата 31.7.2012, 18:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Немного не то... Идет оптимизация функции, принимающей вектор, а _eval_fn_values ее просто вызывает внутри себя... Вот если бы оптимизируемая функция могла принимать какую-то одну обобщенную обертку вида vector_wrapper<double>, для которой, при необходимости, можно было бы написать специализации для разных коллекций, это было бы то... Тогда бы все функции принимали эту обертку, а при компиляции подсовывалась бы нужная специализация... Такое вообще возможно?


--------------------
user posted image
PM MAIL ICQ   Вверх
boostcoder
Дата 31.7.2012, 19:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(kosmonaFFFt @  31.7.2012,  18:58 Найти цитируемый пост)
если бы оптимизируемая функция могла принимать какую-то одну обобщенную обертку вида vector_wrapper<double>, для которой, при необходимости, можно было бы написать специализации для разных коллекций, это было бы то...

это возможно.

Цитата(kosmonaFFFt @  31.7.2012,  18:58 Найти цитируемый пост)
а при компиляции подсовывалась бы нужная специализация

а в чем тут разница между "функция могла принимать какую-то одну обобщенную обертку", и "при компиляции подсовывалась бы нужная специализация" ?
С++ - компилируемый ЯП.

я все же наверное не очень понимаю задачу... попробуй на пальцах ;)

PM WWW   Вверх
kosmonaFFFt
Дата 31.7.2012, 19:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Хотелось бы как-то так (нерабочий пример):
Код

template<typename T, typename C>
class container_wrapper
{
};

template<typename T>
class container_wrapper<T, vector<T> >
{
};

template<typename T>
class container_wrapper<T, list<T> >
{
};

void fn(const container_wrapper<int>& w)
{
    
}

int main(...)
{
    vector<int> v;
    fn(v);
}


и чтобы при этом можно было бы неявно преобразовывать vector<int> в collection_wrapper<int, vector<int> >.


--------------------
user posted image
PM MAIL ICQ   Вверх
boostcoder
Дата 31.7.2012, 19:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(kosmonaFFFt @  31.7.2012,  18:58 Найти цитируемый пост)
vector_wrapper<double>

мы можем специализировать как для хранимого типа, так и для некоторых условий и констант, обязав себя соблюсти интерфейс.
к примеру:
Код

enum iface_strategy {
    iface_vector
   ,iface_matrix
   ,iface_2d_vector
   ,iface_3d_vector
};

template<typename T, iface_strategy>
struct vector_wrapper;

template<typename T>
struct vector_wrapper<T, iface_vector> {
    typedef typename std::vector<T>::iterator iterator;
    typedef typename std::vector<T>::const_iterator const_iterator;

   iterator begin() {...}
   const_iterator begin() {...}
   iterator end() {...}
   const_iterator end() {...}
};
template<typename T>
struct vector_wrapper<T, iface_matrix> {
    typedef typename boost::matrix<T>::iterator iterator;
    typedef typename boost::matrix<T>::const_iterator const_iterator;

   iterator begin() {...}
   const_iterator begin() {...}
   iterator end() {...}
   const_iterator end() {...}
};

PM WWW   Вверх
kosmonaFFFt
Дата 31.7.2012, 19:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



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


--------------------
user posted image
PM MAIL ICQ   Вверх
boostcoder
Дата 31.7.2012, 19:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(kosmonaFFFt @  31.7.2012,  19:08 Найти цитируемый пост)
Хотелось бы как-то так (нерабочий пример):

так-то можно. но я все равно не понимаю, зачем..

PM WWW   Вверх
kosmonaFFFt
Дата 31.7.2012, 19:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Чтобы было:
Код

typedef function<double(const vector_wrapper<double>& v)> fn_t;

class optimizer1 {
    void optimize(const fn_t& fn, other_params params);
}

class optimizer2 {
    void optimize(const fn_t& fn, other_params params);
}

...

void optimizer1::optimize(const fn_t& fn, other_params params) {
    some_vector_like_container c;
    fn(c);
}

double fn_1(const vector_wrapper<double>& v) {
}

...

vector<double> v;
fn_1(v);

...

optimizer1 o;
o.optimize(fn, ...);



--------------------
user posted image
PM MAIL ICQ   Вверх
boostcoder
Дата 31.7.2012, 19:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(kosmonaFFFt @  31.7.2012,  19:21 Найти цитируемый пост)
А можно ли добиться, чтобы передаваемый в функцию враппер параметризовался только одним аргументом - типом хранящегося в коллекции значения?

да. но а как тогда специализировать контейнер который представляет враппер?

PM WWW   Вверх
kosmonaFFFt
Дата 31.7.2012, 19:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(boostcoder @  31.7.2012,  23:41 Найти цитируемый пост)
да. но а как тогда специализировать контейнер который представляет враппер?

А компилятор не может этого сделать по типу передаваемого аргумента? Т. е. если передаем аргумент типа vector<int>, то он кастуется в wrapper<int, vector<int>>...


--------------------
user posted image
PM MAIL ICQ   Вверх
boostcoder
Дата 31.7.2012, 19:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(kosmonaFFFt @  31.7.2012,  19:21 Найти цитируемый пост)
типом хранящегося в коллекции значения? 

 - я понял в прямом смысле. т.е. double, float, long...
а ты про специализированный контейнер?
типа?:
Код

template<typename C>
struct vector_wrapper<vector<double>> {};
template<typename C>
struct vector_wrapper<matrix<double>> {};

?

PM WWW   Вверх
kosmonaFFFt
Дата 31.7.2012, 19:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Ага, так тоже пойдет, вроде у всех контейнеров, что я видел, есть внутри что-то наподобие
Код

typedef typename T value_type;

и его можно использовать в враппере...


--------------------
user posted image
PM MAIL ICQ   Вверх
boostcoder
Дата 31.7.2012, 20:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



так вопрос решен?

PM WWW   Вверх
kosmonaFFFt
Дата 31.7.2012, 20:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Теоретически... ) Как решу практически, закрою тему...
Спасибо за помощь...

З.Ы. В общем немного разобрался с параметризацией шаблонов, проблему решил, хоть и немного по другому...

Это сообщение отредактировал(а) kosmonaFFFt - 7.8.2012, 04:40


--------------------
user posted image
PM MAIL ICQ   Вверх
kosmonaFFFt
Дата 10.9.2012, 18:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Ап...

Посмотрел вот тут на std::function, и подумал, а нельзя ли сделать подобный враппер для объектов, имеющих оператор [], чтобы можно было бы написать что-то подобное следующему:
Код

void superFunction(const ArrayWrapper<int>& w)
{
...
}

std::vector<int> v1;
int* v2 = new int[...];
SomeOtherIntVector v3;

superFunction(v1);
superFunction(v2);
superFunction(v3);

Попытался разобраться в исходниках std::function, но суть так и не понял, как именно там реализовали то, что можно создать объект std::function из всего, что имеет operator(), соответствующей сигнатуры...

Это сообщение отредактировал(а) kosmonaFFFt - 10.9.2012, 18:19


--------------------
user posted image
PM MAIL ICQ   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

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

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


 




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


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

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