C++ trying to use max and accumulate function - c++

I am new to C++ and this is my first program that I am trying to write. In the below code I want to simulate a price of an option and calculate its value. I am getting an error for the accumulate function.
I have already tried std::max and std::accumulate but they don't work as well.
#include <iostream>
#include <algorithm>
#include <cmath>
#include<random>
#include<numeric>
#include<vector>
using namespace std;
double mc(int S, int K, float r, float vol, int T, int sim, int N){
mt19937 rng;
normal_distribution<>ND(0,1);
ND(rng);
std::vector<double> s(sim);
double dt = T/N;
for(int i =0;i<sim;i++)
{
std::vector<double> p(N);
p[0]=S;
for(int k = 0;k<N;k++)
{
double phi = ND(rng);
p[i+1] = p[i]*(1+r*dt+vol*phi*sqrt(dt));
}
s[i] = max(p[N-1]-K,0);
}
float payoff = (accumulate(s)/sim)*exp(-r*T);
return payoff;
}
int main(){
cout << mc(100,100,0.05,0.2,1,100,100) << endl;
return 0;
}
Errors :
> test1.cpp:26:21: error: no matching function for call to 'accumulate'
> float payoff = (accumulate(s)/sim)*exp(-r*T);
> ^~~~~~~~~~ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/numeric:158:1:
> note: candidate function template not viable: requires 3 arguments,
> but 1 was provided accumulate(_InputIterator __first, _InputIterator
> __last, _Tp __init) ^ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/numeric:168:1:
> note: candidate function template not viable: requires 4 arguments,
> but 1 was provided accumulate(_InputIterator __first, _InputIterator
> __last, _Tp __init, _BinaryOperation __binary_op) ^ 2 errors generated.
EDIT: fixed max function. it uses 0.0 instead of 0

Reading the C++ standard library documentation on std::accumulate would solve your problem. But since you're new to the language and the STL is a bit hard to decipher for beginners, here's how to read the documentation.
template< class InputIt, class T >
T accumulate( InputIt first, InputIt last, T init );
std::accumulate is a generic function, so it's templated on a generic type, T. In your case, T = double. It takes two input iterators, first and last, and an initial value init, of type T = double. So, below is an example on how to accumulate a std::vector<double>.
std::vector<double> v = { 1., 2., 3. };
double result = std::accumulate(v.begin(), v.end(), 0.);
Note that vector::begin and vector::end return iterators to the beginning and end, respectively, of the container.
Replace your call to accumulate using iterators and supplying an initial value.

Related

How to call std::unique with custom predicate in C++03?

I saw this example of how to do it in C++11:
std::unique(v.begin(), v.end(), [](float l, float r)
{
return std::abs(l - r) < 0.01;
});
However, this fails for me in C++03:
error: template argument for 'template<class _FIter, class _BinaryPredicate> _FIter std::unique(_FIter, _FIter, _BinaryPredicate)' uses local type 'CRayTracer::myFunc()::<lambda(float, float)>'
How can I do this in C++03? I think Lambdas may have already existed, and functors/function objects existed, right? Just looking for a simple solution, does not need to be extendable - it will only ever be used here.
Here is an example of code which will not compile for me:
#include <iostream>
#include <vector>
#include <algorithm>
int main(){
std::vector<float> v;
v.push_back(1.0);
v.push_back(1.0);
v.push_back(3.5);
v.push_back(3.5);
struct approx_equal
{
bool operator()(float l, float r)
{
return std::abs(l - r) < 0.01;
}
};
approx_equal f;
std::unique(v.begin(), v.end(),f);
}
Here's the error it produced:
testUnique.cpp: In function 'int main()':
testUnique.cpp:21:37: error: no matching function for call to 'unique(std::vector<float>::iterator, std::vector<float>::iterator, main()::approx_equal&)'
21 | std::unique(v.begin(), v.end(),f);
| ^
In file included from C:/msys64/mingw64/include/c++/9.2.0/algorithm:62,
from testUnique.cpp:3:
C:/msys64/mingw64/include/c++/9.2.0/bits/stl_algo.h:995:5: note: candidate: 'template<class _FIter> _FIter std::unique(_FIter, _FIter)'
995 | unique(_ForwardIterator __first, _ForwardIterator __last)
| ^~~~~~
C:/msys64/mingw64/include/c++/9.2.0/bits/stl_algo.h:995:5: note: template argument deduction/substitution failed:
testUnique.cpp:21:37: note: candidate expects 2 arguments, 3 provided
21 | std::unique(v.begin(), v.end(),f);
| ^
In file included from C:/msys64/mingw64/include/c++/9.2.0/algorithm:62,
from testUnique.cpp:3:
C:/msys64/mingw64/include/c++/9.2.0/bits/stl_algo.h:1025:5: note: candidate: 'template<class _FIter, class _BinaryPredicate> _FIter std::unique(_FIter, _FIter, _BinaryPredicate)'
1025 | unique(_ForwardIterator __first, _ForwardIterator __last,
| ^~~~~~
C:/msys64/mingw64/include/c++/9.2.0/bits/stl_algo.h:1025:5: note: template argument deduction/substitution failed:
testUnique.cpp: In substitution of 'template<class _FIter, class _BinaryPredicate> _FIter std::unique(_FIter, _FIter, _BinaryPredicate) [with _FIter = __gnu_cxx::__normal_iterator<float*, std::vector<float> >; _BinaryPredicate = main()::approx_equal]':
testUnique.cpp:21:37: required from here
testUnique.cpp:21:37: error: template argument for 'template<class _FIter, class _BinaryPredicate> _FIter std::unique(_FIter, _FIter, _BinaryPredicate)' uses local type 'main()::approx_equal'
21 | std::unique(v.begin(), v.end(),f);
| ^
testUnique.cpp:21:37: error: trying to instantiate 'template<class _FIter, class _BinaryPredicate> _FIter std::unique(_FIter, _FIter, _BinaryPredicate)'
And here was my set of flags:
g++ -c -g -O3 -Wp,-D_FORTIFY_SOURCE=2 -m64 -Wshadow -Wall -DMX_COMPAT_32 -fexceptions -fno-omit-frame-pointer -D__WIN32__ -std=c++03 testUnique.cpp -o testUnique.o
I think Lambdas may have already existed,
No. Lambdas have been introduced in C++11.
... and functors/function objects existed, right?
Functors are simply objects with an operator(), so they always have been there (though not sure when the term "functor" was actually introduced for them).
For the formal correct way to put it I refer you to other references, sloppy speaking this
auto f = [](float l, float r){
return std::abs(l - r) < 0.01;
};
f(0.1,0.2);
Is equivalent to
struct unnamed {
bool operator()(float l, float r) {
return std::abs(l - r) < 0.01;
}
};
unnamed f;
f(0.1,0.2);
I.e. you can always replace a lambda with a handwritten functor class. Create an instance of the functor and pass that instead of the lambda.
Complete example:
#include <iostream>
#include <vector>
#include <algorithm>
struct approx_equal{
bool operator()(float l, float r) {
return std::abs(l - r) < 0.01;
}
};
int main(){
std::vector<float> v{1.0, 1.0, 3.5, 3.5 };
approx_equal f;
v.erase(std::unique(v.begin(), v.end(),f),v.end());
// sorry this is c++11, replace with iterator loop to see output pre-c++11
for (const auto& x : v) std::cout << x << " ";
}
PS: In C++03 you cannot define the functor class locally and then use it as template parameter (note you do not explicitly pass it as template parameter, but unique has to deduce its type from the parameter you pass in).
Lambdas don't exist in C++03, they were introduced in C++11.
Since your lambda example does not need to capture values, you can replace it with a simple standalone function, you don't need a functor, eg:
#include <iostream>
#include <vector>
#include <algorithm>
bool approx_equal(float l, float r) {
return std::abs(l - r) < 0.01;
}
int main(){
std::vector<float> v;
v.push_back(1.0);
v.push_back(1.0);
v.push_back(3.5);
v.push_back(3.5);
std::unique(v.begin(), v.end(), approx_equal);
}
However, you can use a functor, too. In your attempt to use a functor, you simply defined the functor type inside of main() itself, making it a local type, which the compiler complained about. Define the functor type in global scope instead (you can still use a local variable to instantiate the type), eg:
#include <iostream>
#include <vector>
#include <algorithm>
struct approx_equal {
bool operator()(float l, float r) {
return std::abs(l - r) < 0.01;
}
};
int main(){
std::vector<float> v;
v.push_back(1.0);
v.push_back(1.0);
v.push_back(3.5);
v.push_back(3.5);
approx_equal f;
std::unique(v.begin(), v.end(), f);
// or:
// std::unique(v.begin(), v.end(), approx_equal{});
}

template function that uses n_copy to copy first n elements form one vector another causing a compilation error

I am using the following template function in order to copy the first n elements from one vector to another.
// Example program
#include <iostream>
#include <string>
#include <vector>
template <typename Range>
inline std::vector<typename Range::value_type> take(const Range &iRange, int nbrElements) {
std::vector<typename Range::value_type> result;
if (nbrElements > iRange.size()) {
nbrElements = iRange.size();
}
std::copy_n(iRange, nbrElements, std::back_inserter(result));
return result;
}
int main()
{
std::vector<int> source = { 1, 2, 3, 4, 5, 6, 7,};
std::vector<int> destination = take(source, 7);
return 0;
}
The problem is that I am getting the following error and I don't understand why:
In instantiation of 'std::vector<typename Range::value_type>
take(const Range&, int) [with Range = std::vector<int>; typename
Range::value_type = int]':
22:48: required from here
10:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
In file included from /usr/include/c++/4.9/algorithm:62:0,
from 5:
/usr/include/c++/4.9/bits/stl_algo.h: In instantiation of '_OIter std::copy_n(_IIter, _Size, _OIter) [with _IIter = std::vector<int>;
_Size = int; _OIter = std::back_insert_iterator<std::vector<int> >]':
14:62: required from 'std::vector<typename Range::value_type> take(const Range&, int) [with Range = std::vector<int>; typename
Range::value_type = int]'
22:48: required from here
/usr/include/c++/4.9/bits/stl_algo.h:804:39: error: no matching function for call to '__iterator_category(std::vector<int>&)'
std::__iterator_category(__first));
^
/usr/include/c++/4.9/bits/stl_algo.h:804:39: note: candidate is:
In file included from /usr/include/c++/4.9/bits/stl_algobase.h:65:0,
from /usr/include/c++/4.9/bits/char_traits.h:39,
from /usr/include/c++/4.9/ios:40,
from /usr/include/c++/4.9/ostream:38,
from /usr/include/c++/4.9/iostream:39,
from 2:
/usr/include/c++/4.9/bits/stl_iterator_base_types.h:201:5: note: template<class _Iter> typename
std::iterator_traits<_Iterator>::iterator_category
std::__iterator_category(const _Iter&)
__iterator_category(const _Iter&)
^
/usr/include/c++/4.9/bits/stl_iterator_base_types.h:201:5: note: template argument deduction/substitution failed:
/usr/include/c++/4.9/bits/stl_iterator_base_types.h: In substitution of 'template<class _Iter> typename
std::iterator_traits<_Iterator>::iterator_category
std::__iterator_category(const _Iter&) [with _Iter =
std::vector<int>]':
/usr/include/c++/4.9/bits/stl_algo.h:804:39: required from '_OIter std::copy_n(_IIter, _Size, _OIter) [with _IIter =
std::vector<int>; _Size = int; _OIter =
std::back_insert_iterator<std::vector<int> >]'
14:62: required from 'std::vector<typename Range::value_type> take(const Range&, int) [with Range = std::vector<int>; typename
Range::value_type = int]'
22:48: required from here
/usr/include/c++/4.9/bits/stl_iterator_base_types.h:201:5: error: no type named 'iterator_category' in 'struct
std::iterator_traits<std::vector<int> >'
There are two issues with the code. The first is that it needs to have #include <algorithm>, which defines std::copy_n, and the second is that you need to take the begin() of range.
When fixed, this is what the code looks like:
// Example program
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
template <typename Range>
inline std::vector<typename Range::value_type> take(const Range &iRange, int nbrElements) {
std::vector<typename Range::value_type> result;
if (nbrElements > iRange.size()) {
nbrElements = iRange.size();
}
std::copy_n(iRange.begin(), nbrElements, std::back_inserter(result));
return result;
}
int main()
{
std::vector<int> source = { 1, 2, 3, 4, 5, 6, 7,};
std::vector<int> destination = take(source, 7);
return 0;
}
Shorter version
We can take advantage of std::vector's range constructor to write a shorter, very efficient version of take by using std::vector's range constructor:
template <class Range, class value_t = typename Range::value_type>
std::vector<value_t> take(const Range &range, size_t count) {
// Ensure count is at most range.size()
count = std::min(count, range.size());
return std::vector<value_t>(range.begin(), range.begin() + count);
}
You are almost there, only the first std::copy_n algorithm is wrong. Change the invocation to
using std::begin;
std::copy_n(begin(iRange), nbrElements, std::back_inserter(result));
and it should work as expected. Also, #include <algorithm> is missing, and you could prevent unnecessary allocations as you know the size of the resulting sequence:
result.reserve(nbrElements); // before the call to copy_n
You could try something like that:
template <typename type>
static std::vector<type> take(const std::vector<type> &iRange, size_t nbrElements)
{
if (nbrElements > iRange.size())
{
nbrElements = iRange.size();
}
std::vector<type> result;
result.insert(result.end(), iRange.begin(), iRange.begin() + nbrElements);
return result;
}
Edit:
You can also return vector directly:
return std::vector<type>(iRange.begin(), iRange.begin() + nbrElements);

inserting values of vector into unordered map

I am trying to insert the values present in a vector into a unordered_map. I passed the vector to another function and declare an unordered_map and an iterator to the vector. But while compiling it gives error(below). I would like to understand why does this fail. Searching online has given me a rough idea as to what might be wrong but it is not clear to me:
1. When i pass the vector without '&', a copy of the vector is sent to the function. What does this exactly mean? How does this works internally?
2. What kind of values does make_pair take? Shouldn't 'n' and '*it' just be simple numerical values that make_pair should accept?
#include<iostream>
#include<vector>
#include<unordered_map>
#include<algorithm>
using namespace std;
void readValues(vector<int>&v, int n)
{
int temp;
while(n--)
{
cin>>temp;
v.push_back(temp);
}
}
unordered_map<int, int> storeinhashmap(vector<int>v, int n)
{
vector<int>::iterator it=v.begin();
unordered_map<int,int>h;
int temp;
while(n--)
{
temp = *it;
//cout<<"iter "<<*it<<" "<<++n<<endl;
h.insert(make_pair<int,int>(n, *it));
it++;
}
return h;
}
int main()
{
int t;
cin>>t;
while(t--)
{
int n, x;
cin>>n;
vector<int>v;
readValues(v, n);
cin>>x;
unordered_map<int, int>h = storeinhashmap(v, n);
//char ans = checksumisx(h, n);
}
return 0;
}
Error -
harshit#harshit-5570:~/Desktop/geeksforgeeks$ g++ -std=c++14 key_pair.cpp
key_pair.cpp: In function ‘std::unordered_map<int, int> storeinhashmap(std::vector<int>, int)’:
key_pair.cpp:26:43: error: no matching function for call to ‘make_pair(int&, int&)’
h.insert(make_pair<int,int>(n, *it));
^
In file included from /usr/include/c++/5/bits/stl_algobase.h:64:0,
from /usr/include/c++/5/bits/char_traits.h:39,
from /usr/include/c++/5/ios:40,
from /usr/include/c++/5/ostream:38,
from /usr/include/c++/5/iostream:39,
from key_pair.cpp:1:
/usr/include/c++/5/bits/stl_pair.h:276:5: note: candidate: template<class _T1, class _T2> constexpr std::pair<typename std::__decay_and_strip<_Tp>::__type, typename std::__decay_and_strip<_T2>::__type> std::make_pair(_T1&&, _T2&&)
make_pair(_T1&& __x, _T2&& __y)
^
/usr/include/c++/5/bits/stl_pair.h:276:5: note: template argument deduction/substitution failed:
key_pair.cpp:26:43: note: cannot convert ‘n’ (type ‘int’) to type ‘int&&’
h.insert(make_pair<int,int>(n, *it));
What kind of values does make_pair take? Shouldn't 'n' and '*it' just be simple numerical values that make_pair should accept?
std::make_pair is declared as follows (e.g. 20.3.3 in n3337):
template <class T1, class T2>
pair<V1, V2> make_pair(T1&& x, T2&& y);
Thus if we explicitly set these template parameters like you, no type deductions occur and this function yields
pair<int, int> make_pair(int&& x, int&& y);
Then
h.insert(make_pair<int,int>(n, *it));
shows compilation error because both n and *it are lvalues, not int&&.
This error is easily removed if we rewrite this line as follows:
h.insert(make_pair<int,int>(std::move(n), std::move(*it)));
But the most simple way to avoid this error is removing explicit template parameters like this:
h.insert(make_pair(n, *it));
As you do not want to modify the vector, you can pass it as const reference argument in order to avoid useless copies:
unordered_map<int, int> storeinhashmap(const vector<int>& v, int n)
{
// Check that the number of elements to be inserted
// is less than the size of vector
if (n < 0 || n > v.size()) {
throw invalid_argument("Wrong number of vector elements to be inserted.");
}
unordered_map<int,int>h;
for (size_t i = 0; i < (size_t)n; i++) {
h.insert(make_pair(n-i, v[i]));
}
return h;
}
In addition, I understood that n is the number of elements of the vector<int> to be inserted within unordered_map<int, int>, hence I have included a previous size check.

Compile error using adjacent_difference

I'm trying to use adjacent_difference with two different iterator types. The functor I have created takes the type used by the InputIterator as parameters and returns the type used by the OutputIterator. I don't understand why the code I included doesn't compile:
In file included from /usr/include/c++/4.9/numeric:62:0,
from 4: /usr/include/c++/4.9/bits/stl_numeric.h: In instantiation of '_OutputIterator
std::adjacent_difference(_InputIterator, _InputIterator,
_OutputIterator, _BinaryOperation) [with _InputIterator = __gnu_cxx::__normal_iterator >; _OutputIterator = __gnu_cxx::__normal_iterator >; _BinaryOperation = {anonymous}::CheckOp]':
48:85: required from here
/usr/include/c++/4.9/bits/stl_numeric.h:374:17: error: cannot convert
'_ValueType {aka Test}' to 'float' in assignment
*__result = __value;
// Example program
#include <iostream>
#include <string>
#include <numeric>
#include <vector>
struct Test
{
float first;
float second;
};
namespace{
class CheckOp {
public:
float operator()(Test x, Test y) const
{
float a = x.first - y.first;
float b = x.second - y.second;
return a + b;
}
};
}
int main()
{
std::vector<Test> testVec;
Test test1;
test1.first = 5.5F;
test1.second = 6.5F;
testVec.push_back(test1);
Test test2;
test2.first = 2.5F;
test2.second = 8.5F;
testVec.push_back(test2);
Test test3;
test3.first = 9.4F;
test3.second = 7.8F;
testVec.push_back(test3);
CheckOp checkOP;
std::vector<float> resultVec(testVec.size());
std::adjacent_difference(testVec.begin(), testVec.end(), resultVec.begin(), checkOP);
}
Note the description of adjacent_difference (from cppreference):
First, creates an accumulator acc whose type is InputIt's value type, initializes it with *first, and assigns the result to *d_first.
This implies that the input and output sequences must have the same, or at least a compatible, type.

Error using for_each and lambda

I am trying to solve a simple Fibonacci problem using the lambda function, but I came across this error and I cant solve it.
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
string str;
auto N{0};
auto i{0};
cout<<"Digite o valor de N desejado: ";
getline(cin,str); //pega linha
stringstream(str) >> N;
if (N == 0){cout<<0;}
else if (N == 1){cout<<1;}
else
{
vector<int> v{0,1}; //cria vetor v
for_each(v.begin(),N,
[&](){
v.push_back(v[i]+v[i+1]);
i++;
});
i = 0;
for_each(v.begin(),N,
[&](){
cout<<v[i];
i++;
});
}
return 0;
}
And the error is the following:
quest1.cpp: In function ‘int main()’: quest1.cpp:30:4: error: no matching function for call to ‘for_each(std::vector<int>::iterator, int&, main()::<lambda()>)’ });
^ In file included from /usr/include/c++/6.3.1/algorithm:62:0,
from quest1.cpp:5: /usr/include/c++/6.3.1/bits/stl_algo.h:3763:5: note: candidate: template<class _IIter, class _Funct> _Funct std::for_each(_IIter,
_IIter, _Funct)
for_each(_InputIterator __first, _InputIterator __last, _Function __f)
^~~~~~~~ /usr/include/c++/6.3.1/bits/stl_algo.h:3763:5: note: template argument deduction/substitution failed: quest1.cpp:30:4: note: deduced conflicting types for parameter ‘_IIter’ (‘__gnu_cxx::__normal_iterator<int*, std::vector<int> >’ and ‘int’) });
^ quest1.cpp:38:5: error: no matching function for call to ‘for_each(std::vector<int>::iterator, int&, main()::<lambda()>)’
});
^ In file included from /usr/include/c++/6.3.1/algorithm:62:0,
from quest1.cpp:5: /usr/include/c++/6.3.1/bits/stl_algo.h:3763:5: note: candidate: template<class _IIter, class _Funct> _Funct std::for_each(_IIter,
_IIter, _Funct)
for_each(_InputIterator __first, _InputIterator __last, _Function __f)
^~~~~~~~ /usr/include/c++/6.3.1/bits/stl_algo.h:3763:5: note: template argument deduction/substitution failed: quest1.cpp:38:5: note: deduced conflicting types for parameter ‘_IIter’ (‘__gnu_cxx::__normal_iterator<int*, std::vector<int> >’ and ‘int’)
});
There's two problems in your code. One (already covered by other answers), you're passing the number of iterations as the second parameter to std::for_each, but it actually expects an end iterator. std::for_each(a, b, f) is designed to iterate from iterator a to iterator b and call f on each element in that range.
The second problem is more fundamental: if you modify the vector while iterating over it, you'll get Undefined Behaviour because any modification operation invalidates all iterators to the vector.
Looking at your code, it seems you want the first loop to a normal counting loop and not iteration over the container. The second loop could be done with for_each and a lambda:
vector<int> v{0,1};
for (int i = 0; i < N; ++i) {
v.push_back(v[i] + v[i+1]);
}
for_each(v.begin(), v.end(),
[](int element) {
cout << element;
}
);
Notice that the functor used in for_each is not nullary: the algorithm will pass the element to it.
Alternatively, the printing functionality could be implemented without lambdas:
copy(v.begin(), v.end(), ostream_iterator<int>(cout));
Or, if you prefer to keep the loop, you could just as well use a range-based for loop instead of for_each. The code will be shorter and [subjective]easier to read[/subjective]:
for (int elem : v) {
std::cout << elem;
}
std::for_each requires (as the error tries to tell you) an iterator where to start looping and an iterator where to end. You however are passing an iterator and an int, which are "conflicting types". If you want to loop over an whole vector do something like that:
std::vector<int> v{1, 2, 3};
std::for_each(v.begin(), // start at the front
v.end(), // loop over each element
[&] (int& i) {
i++;
});
If you just need to loop over a part of the vector do that
std::vector<int> v{1, 2, 3};
std::for_each(v.begin(), // start at the front
v.begin() + 2, // loop over the first two elements
[&] (int& i) {
i++;
});
You are not using the for_each function correctly. C++ does not know the signature you are using. Please refer to the documentation, e.g. for_each.
The compiler says exactly that. The second parameter of the for_each you are calling is of type int&, but the signature is for_each(InputIterator, InputIterator, Function) and not for_each(InputIterator, int&, Function), so it fails to compile.