Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 2 years ago.
I have to switch from Python to C/C++.
Do you know a quick "reference tutorial" or something like that to have a reference to how to start? For example something like the Numpy and Scipy tutorials.
I have read a lot of "documentation", for example
- C++ for dummies
- the K&R C Programming Language
- a lot of blog and online documentation such as: http://eli.thegreenplace.net/2010/01/11/pointers-to-arrays-in-c/,
- http://newdata.box.sk/bx/c/
- tons of Q&A here on StackOverflow
- ...
but it's still not clear to me even how to do start porting to C/C++ something like:
#!/usr/bin/env python
import time
import numpy as np
import tables as tb
"""Retrieve 3D positions form 1000 files and store them in one single HDF5 file.
"""
t = time.time()
# Empty array
sample = np.array([])
sample.shape = (0,3)
# Loop over the files
for i in range(0, 1000):
filename = "mill2sort-"+str(i)+"-extracted.h5"
print "Doing ", filename
# Open data file
h5f = tb.openFile(filename, 'r')
# Stack new data under previous data
sample = np.vstack((sample, h5f.root.data.read()))
h5f.close()
# Create the new file
h5 = tb.openFile("mill2sort-extracted-all", 'w')
# Save the array
h5.createArray(h5.root, 'data', sample, title='mill_2_sub_sample_all')
h5.flush()
h5.close()
print "Done in ", time.time()-t, " seconds."
in C or C++. In this example I was not even able to understand how to pass a 3D array to a function that find it's dimensions, something like
int getArrayDimensions(int* array, int *dimensions){
*dimensions = sizeof(*array)/sizeof(array[0]);
return 0;
}
With array being
int array[3][3][3] = ...
Thank you for any suggestion!:)
OK, for that particular example:
- you can get the time services from the standard library here
- you can use eigen for linear algebra. It's an amazing library, I'm in love with it.
- check here to learn how to manipulate files
While using C++, you might miss some features from python, but most of them are actually provided by the boost libraries. For instance returning multiple values from a function is very easy with boost.tuple library as in here. You can use boost::shared_ptr if you don't want to bother yourself with memory management. Or if you want to keep using python to play with your c++ classes, you can use boost.python. Boost.parameter helps you define functions with named arguments. There is also Boost.lambda for lambda functions, but if your environment supports it, you can also use C++11 to have language support for lambda functions. Boost is a gold mine, never stop digging. Just assume that it's part of the standard library. I develop C++ in many different platforms, and neither eigen nor boost has let me down yet.
Here's a good FAQ for C++ best practices. This is a very important principle that you have to keep in mind at all times, while working in C++. I extend it a bit, in my mind and think; If you're going to do something dangerous such as: Allocate memory with a raw new
, or index a raw C style array, pass around raw pointers, or do static_cast
(even worse reinterpret_cast
) etc. They should usually happen in a class somehow dedicated to them, and the code to make sure they don't cause trouble lives very close to them, so that you can see at a glance that everything is under control.
Finally, my favourite!!! Do you want to keep using generators in C++? Here's some dark magic.
Alright, lets just start with C for now.
void readH5Data(FILE *file, int ***sample); // this is for you to implement
void writeH5Data(FILE *file, int ***sample); // this is for you to implement
int main(int argc, const char *argv[])
{
#define width 3
#define height 3
#define depth 3
time_t t = time(NULL);
int ***sample = calloc(width, sizeof(*sample));
for (int i = 0; i < width; i++)
{
sample[i] = calloc(height, sizeof(**sample));
for (int j = 0; j < height; j++)
{
sample[i][j] = calloc(depth, sizeof(***sample));
}
}
for (int i = 0; i < 1000; i++)
{
char *filename[64];
sprintf(filename, "mill2sort-%i-extracted.h5", i);
// open the file
FILE *filePtr = fopen(filename, "r");
if (filePtr == NULL || ferror(filePtr))
{
fprintf(stderr, "%s\n", strerror(errno));
exit(EXIT_FAILURE);
}
readH5Data(filePtr, sample);
fclose(filePtr);
}
char filename[] = "mill2sort-extracted-all";
FILE *writeFile = fopen(filename, "w");
if (writeFile == NULL || ferror(writeFile))
{
fprintf(stderr, "%s\n", strerror(errno));
exit(EXIT_FAILURE);
}
writeH5Data(writeFile, sample);
fflush(writeFile);
fclose(writeFile);
printf("Done in %lli seconds\n", (long long int) (time(NULL) - t));
for (int i = 0; i < width; i++)
{
for (int j = 0; j < width; j++)
{
free(sample[i][j]);
}
free(sample[i]);
}
free(sample);
}
As long as you remember that your array is 3x3x3, you should have no problems overstepping the bounds in your 'writeH5Data' method.
This question is getting quite old, but here is a couple of references that have been useful to me:
A Transition Guide: Python to C++ (pdf)
A Brief Introduction to C++ for Python programmers (incomplete but quite good)