2015-08-21 3 views
2

Я хочу нормализовать (масштабные значения между 0 и 1) вектор скоростей.Как разделить вектор на двойной?

normalized v(i)=v(i)-vmin/(vmax-vmin) 

Мой код

#include <iostream> 
#include <iterator> 
#include <fstream> 
#include <vector> 
#include <algorithm> 

using namespace std; 

int main(){ 
vector<double> velocity; 
vector<double> results; 
double vLower, vUpper, v1; 

ifstream inputFile1("/home/milenko/gust/vel.dat"); 

if (inputFile1) {   
    double value; 

    while (inputFile1 >> value) { 
     velocity.push_back(value); 
    } 
} 

vLower = *min_element(velocity.begin(), velocity.end()); 
vUpper = *max_element(velocity.begin(), velocity.end()); 

v1 = vUpper-vLower; 
transform(velocity.begin(), velocity.end(), velocity.begin(), [vLower](double i) -> double { return i - vLower; }); 
transform (velocity.begin(), velocity.end(), v1, results, divides<double>()); 
for (auto c : results) { std::cout << c << std::endl; } 
} 

Первое преобразование работает нормально, он вычитает минимальное значение из каждого вектора element.The проблема с второй, который должен разделить скорость с v1.

In instantiation of ‘_OIter std::transform(_IIter1, _IIter1, _IIter2, _OIter, _BinaryOperation) [with _IIter1 = __gnu_cxx::__normal_iterator<double*, std::vector<double> >; _IIter2 = double; _OIter = std::vector<double>; _BinaryOperation = std::divides<double>]’: 
v1.cpp:29:76: required from here 
/usr/include/c++/4.8/bits/stl_algo.h:4964:59: error: no match for ‘operator++’ (operand type is ‘std::vector<double>’) 
     for (; __first1 != __last1; ++__first1, ++__first2, ++__result) 
                 ^
/usr/include/c++/4.8/bits/stl_algo.h:4965:37: error: invalid type argument of unary ‘*’ (have ‘double’) 
    *__result = __binary_op(*__first1, *__first2); 
            ^
/usr/include/c++/4.8/bits/stl_algo.h:4965:2: error: no match for ‘operator*’ (operand type is ‘std::vector<double>’) 
    *__result = __binary_op(*__first1, *__first2); 

Любые идеи, как это решить? Или это возможно с одним преобразованием?

+2

[станд :: преобразования] (http://en.cppreference.com/w/cpp/algorithm/transform) принимает либо 3, либо 4 итератора и функтор, во втором вызове вы даете ему 2 итератора 'double' и контейнер в качестве первых 4 аргументов ... – Borgleader

+0

@ Я вижу сейчас, хорошо Я должен делить скорость на v1.Как должен выглядеть функтор? –

+1

'normalized v (i) = v (i) -vmin/(vmax-vmin)' должно быть «нормализовано» v (i) = (v (i) -vmin)/(vmax-vmin) 'и делить ДЕЙСТВИТЕЛЬНО медленно , вам было бы намного лучше установить значение 'double scale = 1/(vmax-vmin)', а затем установить каждый 'v (i) = (v (i) -vmin) * scale' – RyanP

ответ

8

v1 не должно быть в transform.

transform (velocity.begin(), velocity.end(), back_inserter(results), 
bind(divides<double>(), placeholders::_1, v1)); 

Но так как вы используете лямбда в первом трансформировать его будет более простой в использовании лямбда-во второе преобразование тоже.

transform (velocity.begin(), velocity.end(), back_inserter(results), 
[&v1](double v) { return v/v1; }); 
+0

Да, теперь работает отлично –

+0

Для согласованности он должен быть 'std :: dives' слишком – Slava

+0

@Slava, так как существует' using namespace std', все 'std ::' были удалены, спасибо. – ForEveR

2

Прежде всего, вы могли бы использовать стандартный алгоритм std::minmax_element найти минимум и максимум, пересекающий вектор только один раз.

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

Таким образом, вы можете написать

auto minmax = std::minmax_element(velocity.begin(), velocity.end()); 

auto x = *minmax.first/(*minmax.second - *mimax.first); 

for (auto &value : velocity) value -= x; 

Если вам необходимо создать новый вектор, то вы можете написать Insted

auto minmax = std::minmax_element(velocity.begin(), velocity.end()); 

auto x = *minmax.first/(*minmax.second - *mimax.first); 

vector<double> results; 
resultr.reserve(velocity.size()); 

for (auto value : velocity) results.push_back(value - x); 
+0

Я думаю, что мы принимаем 'v (i) = v (i) -vmin/(vmax-vmin)' была опечаткой, а OP означала 'v (i) = (v (i) -vmin)/(vmax-vmin) '. –

+0

@Chris Drew В контексте вопроса на самом деле неважно, какое выражение использовать. :) –

Смежные вопросы