Just a short question:
Is there any C++11 equivalent of Haskell's inits?
The inits function returns all initial segments of the argument,
shortest first.
I'd like to do sth. like
reverse $ inits [1..10]
C++11 supports std::reverse, but i could not find sth. like std::inits.
The List will be represented in C++ as a std::vector.
I think I got it working purely functional:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main(void) {
vector<int> nums = { 1,5,5,9,8,7,6 };
auto inits = accumulate(nums.begin()+1, nums.end(), // Iterate between second and last element
vector< vector<int> >{ vector<int>{nums.front()}}, // Initialize accumulator
[] (vector< vector<int> > &acc, int j) { // Lambda constructing further elements
auto tmp = acc.back();
tmp.push_back(j);
acc.push_back( tmp );
});
return 0;
}
Inits will be a vector of vectors of int's.
Everything without (visible) loops :-)
For a random-access range (since you mention std::vector), a range of successive slices is manageable. This will also work with forward and bidirectional ranges, although that will incur an additional linear cost when computing the distance. With Boost.Range:
#include <boost/range/irange.hpp>
#include <boost/range/adaptor/sliced.hpp>
#include <boost/range/adaptor/transformed.hpp>
namespace R = boost::adaptors;
template<typename Range>
using range_difference_t = typename boost::range_difference<Range>::type;
namespace functors {
template<typename Range>
struct slice {
using difference_type = range_difference_t<Range>;
Range* range;
explicit slice(Range& range)
: range(&range)
{}
boost::sliced_range<Range> operator()(difference_type index) const
{
return R::slice(*range, static_cast<difference_type>(0), index);
}
};
} // functors
template<typename Range>
using inits_type =
boost::transformed_range<
functors::slice<Range>,
const boost::integer_range<range_difference_t<Range>>
>;
// calling inits with rvalues is not supported on purpose
template<typename Range>
inits_type<Range> inits(Range& range)
{
using diff_t = range_difference_t<Range>;
return R::transform(
// use boost::size instead of distance to restrict
// inits to working efficiently on random-access ranges only
boost::irange(static_cast<diff_t>(0), boost::distance(range) + static_cast<diff_t>(1)),
functors::slice<Range> { range }
);
}
Demo here.
This solution benefits greatly from C++14, leaving us with just:
// same includes
template<typename Range>
auto inits(Range& range)
{
namespace R = boost::adaptors;
using diff_t = typename boost::range_difference<Range>::type;
return R::transform(
boost::irange(static_cast<diff_t>(0), boost::distance(range) + static_cast<diff_t>(1)),
[range = &range](diff_t i) { return R::slice(*range, static_cast<diff_t>(0), i); }
);
}
C++14 demo here.
As for a non-slicing solution (i.e. closer in spirit to the Haskell version), this would require writing iterators by hand, with ‘interesting’ lifetime considerations. I would not recommend it.
Related
Here's an illustration of what I am currently doing with two functions.
In both cases I am creating a local copies: either an instance of std::vector<GLfloat> or of std::vector<GLdouble>.
Isn't there a shortcut not involving copies, where I could go from Rcpp::NumericMatrix to GLfloat */GLdouble * in a more direct way?
#include <Rcpp.h>
#include <GLFW/glfw3.h>
using namespace Rcpp;
//' #export
// [[Rcpp::export("glLoadMatrixf")]]
void gl_load_matrixf(Rcpp::NumericMatrix m) {
std::vector<GLfloat> float_v = Rcpp::as<std::vector<GLfloat> >(m);
const GLfloat * _float_v = &float_v[0];
glLoadMatrixf(_float_v);
}
//' #export
// [[Rcpp::export("glLoadMatrixd")]]
void gl_load_matrixd(Rcpp::NumericMatrix m) {
std::vector<GLdouble> double_v = Rcpp::as<std::vector<GLdouble> >(m);
const GLdouble * _double_v = &double_v[0];
glLoadMatrixd(_double_v);
}
On my system GLfloat and GLdouble are defined as:
typedef float GLfloat;
typedef double GLdouble;
And R's numeric data type is always a double. So you can use &m[0] or m.begin() directly to get something convertible to a GLdouble * without the need to copy the data. For GLfloat this is not possible, since it requires a (lossy) cast to go from the (64 bit) double used by R to a (32 bit) float.
Some code as illustration:
Sys.setenv(PKG_LIBS="-lGL -lglfw")
Rcpp::sourceCpp(code = '
#include <Rcpp.h>
#include <GLFW/glfw3.h>
using namespace Rcpp;
// [[Rcpp::export("glLoadMatrixd")]]
void gl_load_matrixd(Rcpp::NumericMatrix m) {
const GLdouble * _double_v = &m[0];
glLoadMatrixd(_double_v);
}
')
glLoadMatrixd(matrix(runif(10), 2, 5))
BTW, I have no idea what dimensions such a matrix should have. 2x5 is probably incorrect ...
For a vector of strings, return the sum of each string's size.
I tried to use accumulate, together with a lambda function (Is it the best way of calculating what I want in 1-line?)
Codes are written in wandbox (https://wandbox.org/permlink/YAqXGiwxuGVZkDPT)
#include <iostream>
#include <numeric>
#include <string>
#include <vector>
using namespace std;
int main() {
vector<string> v = {"abc", "def", "ghi"};
size_t totalSize = accumulate(v.begin(), v.end(), [](string s){return s.size();});
cout << totalSize << endl;
return 0;
}
I expect to get a number (9), however, errors are returned:
/opt/wandbox/gcc-head/include/c++/10.0.0/bits/stl_numeric.h:135:39: note: 'std::__cxx11::basic_string' is not derived from 'const __gnu_cxx::__normal_iterator<_Iterator, _Container>'
135 | __init = _GLIBCXX_MOVE_IF_20(__init) + *__first;
I want to know how to fix my codes? Thanks.
That's because you do not use std::accumulate properly. Namely, you 1) did not specify the initial value and 2) provided unary predicate instead of a binary. Please check the docs.
The proper way to write what you want would be:
#include <iostream>
#include <numeric>
#include <string>
#include <vector>
using namespace std;
int main() {
vector<string> v = {"abc", "def", "ghi"};
size_t totalSize = accumulate(v.begin(), v.end(), 0,
[](size_t sum, const std::string& str){ return sum + str.size(); });
cout << totalSize << endl;
return 0;
}
Both issues are fixed in this code:
0 is specified as initial value, because std::accumulate needs to know where to start, and
The lambda now accepts two parameters: accumulated value, and the next element.
Also note how std::string is passed by const ref into the lambda, while you passed it by value, which was leading to string copy on each invocation, which is not cool
i am trying to use dgels function of lapacke:
when i use it with malloc fucntion. it doesnot give correct value.
can anybody tell me please what is the mistake when i use malloc and create a matrix?
thankyou
/* Calling DGELS using row-major order */
#include <stdio.h>
#include <lapacke.h>
#include <conio.h>
#include <malloc.h>
int main ()
{
double a[3][2] = {{1,0},{1,1},{1,2}};
double **outputArray;
int designs=3;
int i,j,d,i_mal;
lapack_int info,m,n,lda,ldb,nrhs;
double outputArray[3][1] = {{6},{0},{0}};*/
outputArray = (double**) malloc(3* sizeof(double*));
for(i_mal=0;i_mal<3;i_mal++)
{
outputArray[i_mal] = (double*) malloc(1* sizeof(double));
}
for (i=0;i<designs;i++)
{
printf("put first value");
scanf("%lf",&outputArray[i][0]);
}
m = 3;
n = 2;
nrhs = 1;
lda = 2;
ldb = 1;
info = LAPACKE_dgels(LAPACK_ROW_MAJOR,'N',m,n,nrhs,*a,lda,*outputArray,ldb);
for(i=0;i<m;i++)
{
for(j=0;j<nrhs;j++)
{
printf("%lf ",outputArray[i][j]);
}
printf("\n");
}
getch();
return (info);
}
The problem may come from outputArray not being contiguous in memory. You may use something like this instead :
outputArray = (double**) malloc(3* sizeof(double*));
outputArray[0]=(double*) malloc(3* sizeof(double));
for (i=0;i<designs;i++){
outputArray[i]=&outputArray[0][i];
}
Don't forget to free the memory !
free(outputArray[0]);
free(outputArray);
Edit : Contiguous means that you have to allocate the memory for all values at once. See http://www.fftw.org/doc/Dynamic-Arrays-in-C_002dThe-Wrong-Way.html#Dynamic-Arrays-in-C_002dThe-Wrong-Way : some packages, like fftw or lapack require this feature for optimization. As you were calling malloc three times, you created three parts and things went wrong.
If you have a single right hand side, there is no need for a 2D array (double**). outputArray[i] is a double*, that is, the start of the i-th row ( row major). The right line may be outputArray[i]=&outputArray[0][i*nrhs]; if you have many RHS.
By doing this in your code, you are building a 3 rows, one column, that is one RHS. The solution, is of size n=2. It should be outputArray[0][0] , outputArray[1][0]. I hope i am not too wrong, check this on simple cases !
Bye,
I have a code in which the character array is populated by integers (converted to char arrays), and read by another function which reconverts it back to integers. I have used the following function to get the conversion to char array:
char data[64];
int a = 10;
std::string str = boost::lexical_cast<std::string>(a);
memcpy(data + 8*k,str.c_str(),sizeof(str.c_str())); //k varies from 0 to 7
and the reconversion back to characters is done using:
char temp[8];
memcpy(temp,data+8*k,8);
int a = atoi(temp);
This works fine in general, but when I try to do it as part of a project involving qt (ver 4.7), it compiles fine and gives me segmentation faults when it tries to read using memcpy(). Note that the segmentation fault happens only while in the reading loop and not while writing data. I dont know why this happens, but I want to get it done by any method.
So, are there any other other functions which I can use which can take in the character array, the first bit and the last bit and convert it into the integer. Then I wouldnt have to use memcpy() at all. What I am trying to do is something like this:
new_atoi(data,8*k,8*(k+1)); // k varies from 0 to 7
Thanks in advance.
You are copying only a 4 characters (dependent on your system's pointer width). This will leave numbers of 4+ characters non-null terminated, leading to runaway strings in the input to atoi
sizeof(str.c_str()) //i.e. sizeof(char*) = 4 (32 bit systems)
should be
str.length() + 1
Or the characters will not be nullterminated
STL Only:
make_testdata(): see all the way down
Why don't you use streams...?
#include <sstream>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <string>
#include <vector>
int main()
{
std::vector<int> data = make_testdata();
std::ostringstream oss;
std::copy(data.begin(), data.end(), std::ostream_iterator<int>(oss, "\t"));
std::stringstream iss(oss.str());
std::vector<int> clone;
std::copy(std::istream_iterator<int>(iss), std::istream_iterator<int>(),
std::back_inserter(clone));
//verify that clone now contains the original random data:
//bool ok = std::equal(data.begin(), data.end(), clone.begin());
return 0;
}
You could do it a lot faster in plain C with atoi/itoa and some tweaks, but I reckon you should be using binary transmission (see Boost Spirit Karma and protobuf for good libraries) if you need the speed.
Boost Karma/Qi:
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/karma.hpp>
namespace qi=::boost::spirit::qi;
namespace karma=::boost::spirit::karma;
static const char delimiter = '\0';
int main()
{
std::vector<int> data = make_testdata();
std::string astext;
// astext.reserve(3 * sizeof(data[0]) * data.size()); // heuristic pre-alloc
std::back_insert_iterator<std::string> out(astext);
{
using namespace karma;
generate(out, delimit(delimiter) [ *int_ ], data);
// generate_delimited(out, *int_, delimiter, data); // equivalent
// generate(out, int_ % delimiter, data); // somehow much slower!
}
std::string::const_iterator begin(astext.begin()), end(astext.end());
std::vector<int> clone;
qi::parse(begin, end, qi::int_ % delimiter, clone);
//verify that clone now contains the original random data:
//bool ok = std::equal(data.begin(), data.end(), clone.begin());
return 0;
}
If you wanted to do architecture independent binary serialization instead, you'd use this tiny adaptation making things a zillion times faster (see benchmark below...):
karma::generate(out, *karma::big_dword, data);
// ...
qi::parse(begin, end, *qi::big_dword, clone);
Boost Serialization
The best performance can be reached when using Boost Serialization in binary mode:
#include <sstream>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/vector.hpp>
int main()
{
std::vector<int> data = make_testdata();
std::stringstream ss;
{
boost::archive::binary_oarchive oa(ss);
oa << data;
}
std::vector<int> clone;
{
boost::archive::binary_iarchive ia(ss);
ia >> clone;
}
//verify that clone now contains the original random data:
//bool ok = std::equal(data.begin(), data.end(), clone.begin());
return 0;
}
Testdata
(common to all versions above)
#include <boost/random.hpp>
// generates a deterministic pseudo-random vector of 32Mio ints
std::vector<int> make_testdata()
{
std::vector<int> testdata;
testdata.resize(2 << 24);
std::generate(testdata.begin(), testdata.end(), boost::mt19937(0));
return testdata;
}
Benchmarks
I benchmarked it by
using input data of 2<<24 (33554432) random integers
not displaying output (we don't want to measure the scrolling performance of our terminal)
the rough timings were
STL only version isn't too bad actually at 12.6s
Karma/Qi text version ran in 18s 5.1s, thanks to Arlen's hint at generate_delimited :)
Karma/Qi binary version (big_dword) in only 1.4s (roughly 12x 3-4x as fast)
Boost Serialization takes the cake with around 0.8s (or when subsituting text archives instead of binaries, around 13s)
There is absolutely no reason for the Karma/Qi text version to be any slower than the STL version. I improved #sehe implementation of the Karma/Qi text version to reflect that claim.
The following Boost Karma/Qi text version is more than twice as fast as the STL version:
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/karma.hpp>
#include <boost/random.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
namespace ascii = boost::spirit::ascii;
namespace qi = boost::spirit::qi;
namespace karma = boost::spirit::karma;
namespace phoenix = boost::phoenix;
template <typename OutputIterator>
void generate_numbers(OutputIterator& sink, const std::vector<int>& v){
using karma::int_;
using karma::generate_delimited;
using ascii::space;
generate_delimited(sink, *int_, space, v);
}
template <typename Iterator>
void parse_numbers(Iterator first, Iterator last, std::vector<int>& v){
using qi::int_;
using qi::phrase_parse;
using ascii::space;
using qi::_1;
using phoenix::push_back;
using phoenix::ref;
phrase_parse(first, last, *int_[push_back(ref(v), _1)], space);
}
int main(int argc, char* argv[]){
static boost::mt19937 rng(0); // make test deterministic
std::vector<int> data;
data.resize(2 << 24);
std::generate(data.begin(), data.end(), rng);
std::string astext;
std::back_insert_iterator<std::string> out(astext);
generate_numbers(out, data);
//std::cout << astext << std::endl;
std::string::const_iterator begin(astext.begin()), end(astext.end());
std::vector<int> clone;
parse_numbers(begin, end, clone);
//verify that clone now contains the original random data:
//std::copy(clone.begin(), clone.end(), std::ostream_iterator<int>(std::cout, ","));
return 0;
}
In my data.h file I have:
typedef struct {
double ***grid;
} Solver;
In my .c file I have
static Solver _solver;
which first makes a call to a function to do some allocation on grid such as
_solver.grid = malloc(....);
//then makes a call to
GS_init(_solver.grid);
The GS_init function is declared in GS.h as:
void GS_init(double ***grid);
When I try to compile, I get two errors:
the struct "<unnamed>" has no field "grid"
GS_init(_solver.grid)
^
and
too many arguments in function call
GS_init(_solver.grid)
^
Any ideas what is going wrong here?
This code compiles with 'gcc -Wall -Werror -c':
data.h
typedef struct
{
double ***grid;
} Solver;
gs.h
extern void GS_init(double ***grid);
gs.c
#include "data.h"
#include "gs.h"
#include <stdlib.h>
static Solver _solver;
void anonymous(void)
{
_solver.grid = malloc(32 * sizeof(double));
GS_init(_solver.grid);
}
Derek asked:
Why does this work? Is it because of the extern keyword?
The 'extern' is not material to making it work, though I always use it.
When I have to flesh out GS_init() in, say compute.c, would I write void GS_init(double ***grid){ //loop over grid[i][j][k] setting to zero }
Sort of...yes, the GS_init() code could do that if the data structure is set up properly, which is going to need more information than there is currently visible in the structure.
For the compiler to process:
grid[i][j][k] = 0.0;
the code has to know the valid ranges for each of i, j, and k; assume the number of rows in each dimension are Ni, Nj, Nk. The data 'structure' pointed to by grid must be an array of Ni 'double **' values - which must be allocated. Each of those entries must point to Nj 'double *' values. So, you have to do more allocation than a single malloc(), and you have to do more initialization than just setting everything to zero.
If you want to use a single array of doubles only, you will have to write a different expression to access the data:
grid[(i * Ni + j) * Nj + k] = 0.0;
And under this scenario, grid would be a simple double * and not a triple pointer.