1) I want to pass a the pointer of a QVector to a function and then do things with it. I tried this:
void MainWindow::createLinearVector(QVector<float> *vector, float min, float max )
{
float elementDiff=(max-min)/(vector->size()-1);
if(max>min) min -= elementDiff;
else min += elementDiff;
for(int i=0; i< vector->size()+1 ; i++ )
{
min += elementDiff;
*(vector+i) = min; //Problematic line
}
}
However the compiler gives me "no match for operator =" for the *(vector+i) = min; line. What could be the best way to perform actions like this on a QVector?
2) The function is supposed to linearly distribute values on the vector for a plot, in a way the matlab : operator works, for instance vector(a:b:c). What is the simpliest and best way to perform such things in Qt?
EDIT:
With help from here the initial problem is solved. :)
I also improved the metod in itself. The precision could be improved a lot by using linear interpolation instead of multiple additions like above. With multiple addition an error is accumulating, which is eliminated in large part by linear interpolation.
Btw, the if statement in the first function was unecessary and possible to remove by just rearranging stuff a little bit even in the multiple addition method.
void MainWindow::createLinearVector(QVector<double> &vector, double min, double max )
{
double range = max-min;
double n = vector.size();
vector[0]=min;
for(int i=1; i< n ; i++ )
{
vector[i] = min+ i/(n-1)*range;
}
}
I considered using some enchanced loop for this, but would it be more practical?
With for instance a foreach loop I would still have to increment some variable for the interpolation right? And also make a conditional for skipping the first element?
I want to place a float a certain place in the QVector.
Then use this:
(*vector)[i] = min; //Problematic line
A vector is a pointer to a QVector, *vector will be a QVector, which can be indiced with [i] like any QVector. However, due to precedence, one needs parentheses to get the order of operations right.
I think, first u need use the Mutable iterator for this stuff: Qt doc link
Something like this:
QMutableVectorIterator<float> i(vector);
i.toBack();
while (i.hasPrevious())
qDebug() << i.{your code}
Right, so it does not make much sense to use a QVector pointer in here. These are the reasons for that:
Using a reference for the method parameter should be more C++'ish if the implicit sharing is not fast enough for you.
Although, most of the cases you would not even need a reference when just passing arguments around without getting the result back in the same argument (i.e. output argument). That is because *QVector is implicitly shared and the copy only happens for the write as per documentation. Luckily, the syntax will be the same for the calling and internal implementation of the method in both cases, so it is easy to change from one to another.
Using smart pointers is preferable instead of raw pointers, but here both are unnecessarily complex solutions in my opinion.
So, I would suggest to refactor your code into this:
void MainWindow::createLinearVector(QVector<float> &vector, float min, float max)
{
float elementDiff = (max-min) / (vector.size()-1);
min += ((max>min) ? (-elementDiff) : elementDiff)
foreach (float f, vector) {
min += elementDiff;
f = min;
}
}
Note that I fixed up the following things in your code:
Reference type parameter as opposed to pointer
"->" member resolution to "." respectively
Ternary operation instead of the unnatural if/else in this case
Qt's foreach instead of low-level indexing in which case your original point becomes moot
This is then how you would invoke the method from the caller:
createLinearVector(vector, fmin, fmax);
Related
I am trying to do a product operand on the values inside of a vector. It is a huge mess of code.. I have posted it previously but no one was able to help. I just wanna confirm which is the correct way to do a single part of it. I currently have:
vector<double> taylorNumerator;
for(a = 0; a <= (constant); a++) {
double Number = equation involving a to get numerous values;
taylorNumerator.push_back(Number);
for(b = 0; b <= (constant); b++) {
double NewNumber *= taylorNumerator[b];
}
This is what I have as a snapshot, it is very short from what I actually have. Someone told me it is better to do vector.at(index) instead. Which is the correct or best way to accomplish this? If you so desire I can paste all of the code, it works but the values I get are wrong.
When possible, you should probably avoid using indexes at all. Your options are:
A range-based for loop:
for (auto numerator : taylorNumerators) { ... }
An iterator-based loop:
for (auto it = taylorNumerators.begin(); it != taylorNuemrators.end(); ++it) { ... }
A standard algorithm, perhaps with a lambda:
#include <algorithm>
std::for_each(taylorNumerators, [&](double numerator) { ... });
In particular, note that some algorithms let you specify a number of iterations, like std::generate_n, so you can create exactly n items without counting to n yourself.
If you need the index in the calculation, then it can be appropriate to use a traditional for loop. You have to watch for a couple pitfalls: std::vector<T>::size() returns a std::vector<T>::size_type which is typically identical to std::size_type, which is (1) unsigned and (2) quite possibly larger than an int.
for (std::size_t i = 0; i != taylorNumerators.size(); ++i) { ... }
Your calculations probably deal with doubles or some numerical type other than std::size_t, so you have to consider the best way to convert it. Many programmers would rely on implicit conversions, but that can be dangerous unless you know the conversion rules very well. I'd generally start by doing a static cast of the index to the type I actually need. For example:
for (std::size_t i = 0; i != taylorNumerators.size(); ++i) {
const auto x = static_cast<double>(i);
/* calculation involving x */
}
In C++, it's probably far more common to make sure the index is in range and then use operator[] rather than to use at(). Many projects disable exceptions, so the safety guarantee of at() wouldn't really be available. And, if you can check the range once yourself, then it'll be faster to use operator[] than to rely on the range-check built into at() on each index operation.
What you have is fine. Modern compilers can optimize the heck out of the above such that the code is just as fast as the equivalent C code of accessing items direclty.
The only optimization for using vector I recommend is to invoke taylorNumerator.reserve(constant) to allocate the needed storage upfront instead of the vector resizing itself as new items are added.
About the only worthy optimization after that is to not use vector at all and just use a static array - especially if constant is small enough that it doesn't blow up the stack (or binary size if global).
double taylorNumerator[constant];
I am using some legacy C code that passing around lots of raw pointers. To interface with the code, I have to pass a function of the form:
const int N = ...;
T * func(T * x) {
// TODO Put N elements in x
return x + N;
}
where this function should write the result into x, and then return x.
Internally, in this function, I am using Eigen extensively to perform some calculations. Then I write the result back to the raw pointer using the Map class. A simple example which mimics what I am doing is this:
const int N = 5;
T * func(T * x) {
// Do a lot of operations that result in some matrices like
Eigen::Matrix<T, N, 1 > A = ...
Eigen::Matrix<T, N, 1 > B = ...
Eigen::Map<Eigen::Matrix<T, N, 1 >> constraint(x);
constraint = A - B;
return x + N;
}
Obviously, there is much more complicated stuff going on internally, but that is the gist of it... Do some calculations with Eigen, then use the Map class to write the result back to the raw pointer.
Now the problem is that when I profile this code with Callgrind, and then view the results with KCachegrind, the lines
constraint = A - B;
are almost always the bottleneck. This is sort of understandable, because such lines could/are potentially doing three things:
Constructing the Map object
Performing the calculation
Writing the result to the pointer
So it is understandable that this line might have the longest runtime. But I am a little bit worried that perhaps I am somehow doing an extra copy in that line before the data gets written to the raw pointer.
So is there a better way of writing the result to the raw pointer? Or is that the idiom I should be using?
In the back of my mind, I am wondering if using the placement new syntax would buy me anything here.
Note: This code is mission critical and should run in realtime, so I really need to squeeze every ounce of speed out of it. For instance, getting this call from a runtime of 0.12 seconds to 0.1 seconds would be huge for us. But code legibility is also a huge concern since we are constantly tweaking the model used in the internal calculations.
These two lines of code:
Eigen::Map<Eigen::Matrix<T, N, 1 >> constraint(x);
constraint = A - B;
are essentially compiled by Eigen as:
for(int i=0; i<N; ++i)
x[i] = A[i] - B[i];
The reality is a bit more complicated because of explicit unrolling, and explicit vectorization (both depends on T), but that's essentially it. So the construction of the Map object is essentially a no-op (it is optimized away by any compiler) and no, there is no extra copy going on here.
Actually, if your profiler is able to tell you that the bottleneck lies on this simple expression, then that very likely means that this piece of code has not been inlined, meaning that you did not enabled compiler optimizations flags (like -O3 with gcc/clang).
Long time ago, inspired by "Numerical recipes in C", I started to use the following construct for storing matrices (2D-arrays).
double **allocate_matrix(int NumRows, int NumCol)
{
double **x;
int i;
x = (double **)malloc(NumRows * sizeof(double *));
for (i = 0; i < NumRows; ++i) x[i] = (double *)calloc(NumCol, sizeof(double));
return x;
}
double **x = allocate_matrix(1000,2000);
x[m][n] = ...;
But recently noticed that many people implement matrices as follows
double *x = (double *)malloc(NumRows * NumCols * sizeof(double));
x[NumCol * m + n] = ...;
From the locality point of view the second method seems perfect, but has awful readability... So I started to wonder, is my first method with storing auxiliary array or **double pointers really bad or the compiler will optimize it eventually such that it will be more or less equivalent in performance to the second method? I am suspicious because I think that in the first method two jumps are made when accessing the value, x[m] and then x[m][n] and there is a chance that each time the CPU will load first the x array and then x[m] array.
p.s. do not worry about extra memory for storing **double, for large matrices it is just a small percentage.
P.P.S. since many people did not understand my question very well, I will try to re-shape it: do I understand right that the first method is kind of locality-hell, when each time x[m][n] is accessed first x array will be loaded into CPU cache and then x[m] array will be loaded thus making each access at the speed of talking to RAM. Or am I wrong and the first method is also OK from data-locality point of view?
For C-style allocations you can actually have the best of both worlds:
double **allocate_matrix(int NumRows, int NumCol)
{
double **x;
int i;
x = (double **)malloc(NumRows * sizeof(double *));
x[0] = (double *)calloc(NumRows * NumCol, sizeof(double)); // <<< single contiguous memory allocation for entire array
for (i = 1; i < NumRows; ++i) x[i] = x[i - 1] + NumCols;
return x;
}
This way you get data locality and its associated cache/memory access benefits, and you can treat the array as a double ** or a flattened 2D array (array[i * NumCols + j]) interchangeably. You also have fewer calloc/free calls (2 versus NumRows + 1).
No need to guess whether the compiler will optimize the first method. Just use the second method which you know is fast, and use a wrapper class that implements for example these methods:
double& operator(int x, int y);
double const& operator(int x, int y) const;
... and access your objects like this:
arr(2, 3) = 5;
Alternatively, if you can bear a little more code complexity in the wrapper class(es), you can implement a class that can be accessed with the more traditional arr[2][3] = 5; syntax. This is implemented in a dimension-agnostic way in the Boost.MultiArray library, but you can do your own simple implementation too, using a proxy class.
Note: Considering your usage of C style (a hardcoded non-generic "double" type, plain pointers, function-beginning variable declarations, and malloc), you will probably need to get more into C++ constructs before you can implement either of the options I mentioned.
The two methods are quite different.
While the first method allows for easier direct access to the values by adding another indirection (the double** array, hence you need 1+N mallocs), ...
the second method guarantees that ALL values are stored contiguously and only requires one malloc.
I would argue that the second method is always superior. Malloc is an expensive operation and contiguous memory is a huge plus, depending on the application.
In C++, you'd just implement it like this:
std::vector<double> matrix(NumRows * NumCols);
matrix[y * numCols + x] = value; // Access
and if you're concerned with the inconvenience of having to compute the index yourself, add a wrapper that implements operator(int x, int y) to it.
You are also right that the first method is more expensive when accessing the values. Because you need two memory lookups as you described x[m] and then x[m][n]. There is no way the compiler will "optimize this away". The first array, depending on its size, will be cached, and the performance hit may not be that bad. In the second case, you need an extra multiplication for direct access.
In the first method you use, the double* in the master array point to logical columns (arrays of size NumCol).
So, if you write something like below, you get the benefits of data locality in some sense (pseudocode):
foreach(row in rows):
foreach(elem in row):
//Do something
If you tried the same thing with the second method, and if element access was done the way you specified (i.e. x[NumCol*m + n]), you still get the same benefit. This is because you treat the array to be in row-major order. If you tried the same pseudocode while accessing the elements in column-major order, I assume you'd get cache misses given that the array size is large enough.
In addition to this, the second method has the additional desirable property of being a single contiguous block of memory which further improves the performance even when you loop through multiple rows (unlike the first method).
So, in conclusion, the second method should be much better in terms of performance.
If NumCol is a compile-time constant, or if you are using GCC with language extensions enabled, then you can do:
double (*x)[NumCol] = (double (*)[NumCol]) malloc(NumRows * sizeof (double[NumCol]));
and then use x as a 2D array and the compiler will do the indexing arithmetic for you. The caveat is that unless NumCol is a compile-time constant, ISO C++ won't let you do this, and if you use GCC language extensions you won't be able to port your code to another compiler.
i´d like to know if there is a quicker way to copy my data from a mysqlpp::storequeryresult to a std::vector.
My example is as follows:
I store my Query Result with query.store() in StoreQueryResult and my result is e.g. a table with one column with doubles in it. Now I want to copy those doubles into a std::vector. The way I´m doing it right now is to access every single double with the [][] operator and copy it to my vector in a for-loop.
This works but it is very time consuming since i´m copying like 277000 double in a loop. Is there a way to just copy the column to my vector? The thing is my other functions use std::vectors in their parameterlists. Alternatively i could change my functions to call a StoreQueryResult i guess, but i´d prefere a std::vector.
Here is my simplified code:
void foo()
{
vector<double> vec;
mysqlpp::StoreQueryResult sqr;
Query query;
query << "SELECT * FROM tablename";
sqr = query.store();
vec.reserve(sqr.num_rows());
vec.resize(sqr.size());
for(int i=0; i != vec.size(); i++)
{
vec[i] = sqr[i]["my_column"];
}
}
I want something like:
vec = sqr["my_column"] // when my_column is a field with doubles
Thx in advance.
Martin
Ultimately, if you need to copy then you need to copy, and whether you write the loop yourself or get a library function to do it isn't particularly relevant.
What you can do is pre-reserve enough space in the destination vector to avoid repeated re-allocations and copies:
vec.reserve(sqr.num_rows());
It is possible that you wish to create a vector, but then only some values will actually be accessed and used.
In which case we may delay the conversion from mysqlpp::String to another datatype:
std::vector<mysqlpp::String> data(res.num_rows());
for(size_t i=0, n=res.num_rows(); i<n; ++i)
{
data[i] = std::move(res[i]["value"]);
}
Several things are happening here:
We are creating the vector that stores mysqlpp::String. It is an interesting datatype that can be converted to many others. In your case you were using operator double () const.
We get the size once, store it, and then use that value. It's the micro-optimisation, together with using ++i rather than i++; they don't add up to many cycles, but should be used, to keep the code in the spirit of optimisation.
We move the data, rather than copying it. See std::move if you've not encountered it before.
If then you have something like:
double sum = 0.0;
for(size_t i=0, n=data.num_rows(); i<n; i+=2)
{
sum+=double(data[i]);
}
You will only run the conversion routine on ½ of your values.
Of course, if you plan to use the resultant vector several times, you will actually start running the same conversions again and again. So this "optimisation" will actually hurt performance.
I have a struct and two vectors in my .h file:
struct FTerm {
int m_delay;
double m_weight;
};
std::vector<FTerm> m_xterms;
std::vector<FTerm> m_yterms;
I've already read in a file to populate values to m_xterms and m_yterms and I'm trying to iterate through those values:
vector<FTerm>::iterator terms;
for (terms = m_xterms.begin(); terms < m_xterms.end(); terms++)
{
int delaylength = m_xterms->m_delay * 2; // Assume stereo
double weight = m_xterms->m_weight;
}
Although I'm pretty sure I have the logic wrong, I currently get the error Error expression must have a pointer type. Been stuck at this for a while, thanks.
Change
int delaylength = m_xterms->m_delay * 2;
double weight = m_xterms->m_weight;
to
int delaylength = terms->m_delay * 2;
// ^^^^^
double weight = terms->m_weight;
// ^^^^^
as you want to access values through
vector<FTerm>::iterator terms;
within the loop
for (terms = m_xterms.begin(); terms < m_xterms.end(); terms++)
// ^^^^^
"Although I'm pretty sure I have the logic wrong, ..."
That can't be answered, unless you give more context about the requirements for the logic.
Along with the problem πάντα ῥεῖ pointed out, your code currently has a problem that it simply doesn't accomplish anything except wasting some time.
Consider:
for (terms = m_xterms.begin(); terms < m_xterms.end(); terms++)
{
int delaylength = m_xterms->m_delay * 2; // Assume stereo
double weight = m_xterms->m_weight;
}
Both delaylength and weight are created upon entry to the block, and destroyed on exit--so we create a pair of values, then destroy them, and repeat for as many items as there are in the vector--but never do anything with the values we compute. They're just computed, then destroyed.
Assuming you fix that, I'd also write the code enough differently that this problem simply isn't likely to happen to start with. For example, let's assume you really wanted to modify each item in your array, instead of just computing something from it and throwing away the result. You could do that with code like this:
std::transform(m_xterms.begin(), m_xterms.end(), // Source
m_xterms.begin(), // destination
[](FTerm const &t) { return {t.m_delay * 2, t.m_weight}; });// computation
Now the code actually accomplishes something, and it seems a lot less likely that we'd end up accidentally writing it incorrectly.
Bottom line: standard algorithms are your friends. Unlike human friends, they love to be used.