Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
In my project, I am responsible for migrating some MATLAB code to C++. The code below refers to serial communication from a computer to a microcontroller. The function CreatePackage generates a package which is then sent to the microcontroller using MATLAB's fwrite(serial) function.
function package = CreatePackage(V)
for ii = 1:size(V,2)
if V(ii) > 100
V(ii) = 100;
elseif V(ii) < -100
V(ii) = -100;
end
end
vel = zeros(1, 6);
for ii = 1:size(V,2)
if V(ii) > 0
vel(ii) = uint8(V(ii));
else
vel(ii) = uint8(128 + abs(V(ii)));
end
end
package = ['BD' 16+[6, vel(1:6)], 'P' 10 13]+0;
And then, to send the package:
function SendPackage(S, Package)
for ii = 1:length(S)
fwrite(S(ii), Package);
end
How can I create an array/vector in C++ to represent the package variable used in the MATLAB code above?
I have no experience with MATLAB so any help would be greatly apreciated.
Thank you!
The package variable is being streamed as 12, unsigned 8-bit integers in your MATLAB code, so I would use a char[12] array in C++. You can double check sizeof(char) on your platform to ensure that char is only 1 byte.
Yes, MATLAB default data-type is a double, but that does not mean your vector V isn't filled with integer values. You have to look at this data or the specs from your equipment to figure this out.
Whatever the values are coming in, you are setting/clipping the outgoing range to [-100, 100] and then offsetting them to the byte range [0, 255].
If you do not know a whole lot about MATLAB, you may be able to leverage what you know from C++ and use C as an interim. MATLAB's fwrite functionality lines up with that of C's, and you can include these functions in C++ with the #include<cstdio.h> preprocessor directive.
Here is an example solution:
#include <cstdio.h> // fwrite
#include <algorithm> // min, max
...
void makeAndSendPackage(int * a6x1array, FILE * fHandles, int numHandles){
char packageBuffer[13] = {'B','D',24,0,0,0,0,0,0,'P','\n','\r',0};
for(int i=0;i<6;i++){
int tmp = a6x1array[i];
packageBuffer[i+3] = tmp<0: abs(max(-100,tmp))+144 ? min(100,tmp)+16;
}
for(int i=0;i<6;i++){
fwrite(fHandles[i],"%s",packageBuffer);
}
}
Let me know if you have questions about the above code.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am trying to work with a C library, and I had to create the following bit of code:
void *foo = malloc(sizeof(MAGtype_MagneticModel *));
MAGtype_MagneticModel* *MagneticModels = (MAGtype_MagneticModel **)foo;
this is then passed to one of the C library functions as follows:
if(!MAG_robustReadMagModels(filename, (MAGtype_MagneticModel* (*)[]) &MagneticModels, epochs)) {
//ERROR
}
When it passes the above function, I then am wanting to get the value from one of the components of this function.
int var = 0;
if (var < (&MagneticModels[0]->nMax)) var = (&MagneticModels[0]->nMax);
This gives the compiler error:
C2446: '<' : no conversion from 'int *' to 'int'
How would I go about getting the value of MagneticModels[0]->nMax instead of just pointers?
Edit: Here is the struct for MAGtype_MagneticModel:
typedef struct {
double EditionDate;
double epoch; /*Base time of Geomagnetic model epoch (yrs)*/
char ModelName[32];
double *Main_Field_Coeff_G; /* C - Gauss coefficients of main geomagnetic model (nT) Index is (n * (n + 1) / 2 + m) */
double *Main_Field_Coeff_H; /* C - Gauss coefficients of main geomagnetic model (nT) */
double *Secular_Var_Coeff_G; /* CD - Gauss coefficients of secular geomagnetic model (nT/yr) */
double *Secular_Var_Coeff_H; /* CD - Gauss coefficients of secular geomagnetic model (nT/yr) */
int nMax; /* Maximum degree of spherical harmonic model */
int nMaxSecVar; /* Maximum degree of spherical harmonic secular model */
int SecularVariationUsed; /* Whether or not the magnetic secular variation vector will be needed by program*/
double CoefficientFileEndDate;
} MAGtype_MagneticModel;
And for reference, I am working with the library found under WMM2015_Windows.zip that is found here
One thing that may help is to to create an int variable for what you want.
This will allow you to check the variable at compile time
example
int myInt = MagneticModels[0]->nMax
should work
Here is where you need more information on the structure of
MAGtype_MagneticModel
For example, is nMax defined as an integer, or an int *
if the latter, you may need the correct address
&(MagneticModels[0]->nMax)
However, in general, using the array notation [0] 'dereferences the pointer'
Hope this helps
just dont take the address of it
if (var < MagneticModels[0]->nMax)....
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
i just dont understand whats taking so long
its the standard hello world program you write when you first start to learn a new language and its just so un-optimized
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
int main()
{
std::string hello_world = "HELLO WORLD!";
std::string letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ !";
std::vector<long> positions;
std::ostringstream oss;
for(auto l : hello_world){
int position = 0;
position = letters.find(l);
positions.push_back(position);
}
for(long t = 0; t <= 100000000000; t++){
if(t%256465445 == 0){
for(auto p : positions){
oss<<letters[p];
}
}
}
std::cout<<"Hello World!";
}
This seems like it was purposefully un-optimized. I would assume that the time constraints are coming from modding a variable 100,000,000,000 times. But wait, that is not all. Not only do you mod a variable that many times, but when a variable modded to 0, you iterate another 11 times over each char in "Hello World!", or, more precisely, 389 times. That means that the last for loop needs to have done at least 100,000,004,279 calculations. How about you just remove that last for loop, because it seems useless other than to kill time, you'd be better off just doing a sleep(5).
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have the following setup where I am trying to write a custom file header. I have the fields which are described as follows:
// Assume these variables are initialized.
unsigned short x, y, z;
unsigned int dl;
unsigned int offset;
// End assume
u_int8_t major_version = 0x31;
u_int8_t minor_version = 0x30;
u_int_32_t data_offset = (u_int_32_t)offset;
u_int16_t size_x = (u_int16_t)x;
u_int16_t size_y = (u_int16_t)y;
u_int16_t size_z = (u_int16_t)z;
u_int_32_t data_size = (u_int_32_t)dl;
Now, what I would like to do is compute an 8 bit header checksum from the fields starting from major revision to the data_size variables. I am fairly new to this and something simple would suffice for my current needs.
I'm not sure what you are trying to achieve, but to strictly answer your question, a 8-bit checksum is usually computed as
sum_of_all_elements %255
Simply put, add all the elements together, and sum % 255 is your checksum.
Watch out for overflows when doing the addition (you can compute partial sums if you run into trouble).
On a side note, a 8-bit checksum is not that good - It won't help you distinguish all cases and it won't help with data recovery; that's why a 16-bit checksum is usually preferred.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I was implementing a rolling median solution and was not sure why my python implementation was around 40 times slower than c++ implementation.
Here are the complete implementations
C++
#include <iostream>
#include <vector>
#include <string.h>
using namespace std;
int tree[17][65536];
void insert(int x) { for (int i=0; i<17; i++) { tree[i][x]++; x/=2; } }
void erase(int x) { for (int i=0; i<17; i++) { tree[i][x]--; x/=2; } }
int kThElement(int k) {
int a=0, b=16;
while (b--) { a*=2; if (tree[b][a]<k) k-=tree[b][a++]; }
return a;
}
long long sumOfMedians(int seed, int mul, int add, int N, int K) {
long long result = 0;
memset(tree, 0, sizeof(tree));
vector<long long> temperatures;
temperatures.push_back( seed );
for (int i=1; i<N; i++)
temperatures.push_back( ( temperatures.back()*mul+add ) % 65536 );
for (int i=0; i<N; i++) {
insert(temperatures[i]);
if (i>=K) erase(temperatures[i-K]);
if (i>=K-1) result += kThElement( (K+1)/2 );
}
return result;
}
// default input
// 47 5621 1 125000 1700
// output
// 4040137193
int main()
{
int seed,mul,add,N,K;
cin >> seed >> mul >> add >> N >> K;
cout << sumOfMedians(seed,mul,add,N,K) << endl;
return 0;
}
Python
def insert(tree,levels,n):
for i in xrange(levels):
tree[i][n] += 1
n /= 2
def delete(tree,levels,n):
for i in xrange(levels):
tree[i][n] -= 1
n /= 2
def kthElem(tree,levels,k):
a = 0
for b in reversed(xrange(levels)):
a *= 2
if tree[b][a] < k:
k -= tree[b][a]
a += 1
return a
def main():
seed,mul,add,N,K = map(int,raw_input().split())
levels = 17
tree = [[0] * 65536 for _ in xrange(levels)]
temps = [0] * N
temps[0] = seed
for i in xrange(1,N):
temps[i] = (temps[i-1]*mul + add) % 65536
result = 0
for i in xrange(N):
insert(tree,levels,temps[i])
if (i >= K):
delete(tree,levels,temps[i-K])
if (i >= K-1):
result += kthElem(tree,levels,((K+1)/2))
print result
# default input
# 47 5621 1 125000 1700
# output
# 4040137193
main()
On the above mentioned input (in the comments of the code) C++ code took around 0.06 seconds while python took around 2.3 seconds.
Can some one suggest the possible problems with my python code and how to improve to less than 10x performance hit?
I dont expect it to be anywhere near c++ implementation but to the order of 5-10x. I know I can optimize this by using libraries like numpy (and/or scipy). I am asking this question from the point of view of using python for solving programming challenges. These libraries are usually not allowed in these challenges. I am just asking if it is even possible to beat the timelimit for this algorithm in python.
If somebody is interested C++ code is borrowed from Floating median problem at http://community.topcoder.com/tc?module=Static&d1=match_editorials&d2=srm310
[Edit]
For those who think using numpy arrays will improve the performance, it does not. On the otherhand just using numpy ndarray instead of list of list, performace further degraded to around 14 seconds which is more than 200x slowdown from c++.
Pure Python code which is compute-bound and written procedurally is likely to be slow, as you have found. If you want to make something in Python which runs quickly for tasks like this, you'll need to use some C (or C++, Fortran, or other) extensions, which are abundant. For example, statistics and math people use NumPy and SciPy and related tools, which are easy to use from Python but which are actually implemented in compiled languages and have high performance (if used carefully).
If you want to try to squeeze a bit more performance out of pure Python, you can try using the "cProfile" module to analyze your code. But it probably won't get anywhere near C++ speed unless you use smarter modules like NumPy or write your own extensions.
You might gain a small amount by refactoring this:
reversed(xrange(levels))
Especially if you are using Python 2.x, as this will create an actual list. You can instead do something like this:
xrange(levels - 1, -1, -1)
Can some one suggest [...] how to improve to less than 10x performance hit?
Profile the code.
Look into using NumPy instead of native lists.
If that turns out to not be enough, look into using Cython for the critical part.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 4 years ago.
Improve this question
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)