I want to double a value each time a for loop is processed. I have the following code so far:
constexpr size_t doubleN(size_t n, size_t iteration)
{
return n * iteration;
};
const array<size_t, 9> iterationArray = { 1, 2, 3, 4, 5, 6, 7, 8, 10 };
for (size_t i = 1; i <= 10; i++)
{
Insertionsort<double, doubleN(INITIAL_SIZE_N_INSERTIONSORT, iterationArray[i])> insertionsort;
Util<doubleN(INITIAL_SIZE_N_INSERTIONSORT, iterationArray[i])> util;
array<double, doubleN(INITIAL_SIZE_N_INSERTIONSORT, iterationArray[i])> arrayRef;
util.generateRandomDoubleArray(arrayRef);
util.overwriteProcessorCache();
cout << "Measure Insertionsort version 1 with n = " << INITIAL_SIZE_N_INSERTIONSORT << "." << endl;
util.startTimeMeasure();
insertionsort.sortVersion1(arrayRef);
util.stopTimeMeasure();
cout << "Measureing Insertionsort version 1 successful." << endl;
}
My problem is, that I can't double the value returned by the constexpr, cause it always needs a constant value as parameter. Dou you have any idea how to get a constexpr that returns always a value which is doubled based on the prior doubled value?
First, turn your runtime i parameter into compile time value:
template <std::size_t I>
void foo()
{
Insertionsort<double, doubleN(INITIAL_SIZE_N_INSERTIONSORT, I)> insertionsort;
Util<doubleN(INITIAL_SIZE_N_INSERTIONSORT, I)> util;
array<double, doubleN(INITIAL_SIZE_N_INSERTIONSORT, I)> arrayRef;
util.generateRandomDoubleArray(arrayRef);
util.overwriteProcessorCache();
cout << "Measure Insertionsort version 1 with n = " << INITIAL_SIZE_N_INSERTIONSORT << "." << endl;
util.startTimeMeasure();
insertionsort.sortVersion1(arrayRef);
util.stopTimeMeasure();
cout << "Measureing Insertionsort version 1 successful." << endl;
}
then do a loop:
template <size_t ... Is>
void foos()
{
int dummy[] = {0, (foo<Is>(), 0)...};
(void) dummy; // avoid warning for unused variable
}
or with fold expression of C++17:
template <size_t ... Is>
void foos()
{
(foo<Is>(), ...);
}
And call it:
foos<1, 2, 3, 4, 5, 6, 7, 8, 9, 10>();
Related
I was wondering if there was a more efficient way to do it than with manual for loops.
EDIT: This answer requires the devel branch of eigen! I've been using that branch for so long, that I forgot that e.g. reshaped is not part of the stable branch...
There is a way. Median calculation typically requires sorting, so that's what I did here, too. If you have a mutable object/expression, its values are sorted and the median is calculated. If you have a const object/expression, a copy is sorted and the median calculated. Hope this helps!
#include <Eigen/Dense>
#include <iostream>
#include <algorithm>
template<typename Derived>
typename Derived::Scalar median( Eigen::DenseBase<Derived>& d ){
auto r { d.reshaped() };
std::sort( r.begin(), r.end() );
return r.size() % 2 == 0 ?
r.segment( (r.size()-2)/2, 2 ).mean() :
r( r.size()/2 );
}
template<typename Derived>
typename Derived::Scalar median( const Eigen::DenseBase<Derived>& d ){
typename Derived::PlainObject m { d.replicate(1,1) };
return median(m);
}
int main(){
// vector with odd length
Eigen::Vector3f vec1 { 0.1, 2.3, 1.1 };
std::cout << median(vec1) << " (expected: 1.1)\n";
// vector with even length
Eigen::Vector4f vec2 { 1, 3, 0, 2 };
std::cout << median(vec2) << " (expected: 1.5)\n";
Eigen::Matrix3f mat;
mat <<
0, 8, 3,
2, 1, 5,
4, 7, 6;
// const reference (operates on a copy)
const Eigen::Matrix3f& matCRef { mat };
std::cout << median(matCRef) << " (expected: 4)\n";
// block expression (operates on a copy of that expression)
auto& cBlock { matCRef.block(1,1,2,2) };
std::cout << median(cBlock) << " (expected: 5.5)\n";
// matrix itself last, because it's going to be sorted afterwards:
std::cout << median(mat) << " (expected: 4)\n";
return 0;
}
So, for an odd number of coefficients, the median value is returned, for an even number of coefficients, the average between lower and upper median is returned.
I have these codes below. What's wrong with the const auto& in this context, it caused unexpected outputs.
It works fine while compiled with gcc-4.8.5, but gets unexpected outputs with gcc-4.9.2.
If I remove the & in const auto&, it works fine with both gcc versions.
// max_dim is a protobuf filed: const auto max_dim = msg.max();
// cat2_num is an element in std::vector<int32_t>: const auto cat2_num = vec[i]
const auto& res_num = std::max(1, std::min(max_dim, cat2_num));
LOG(ERROR) << res_num << ", " << max_dim << ", " << cat2_num
<< ", " << std::max(1, std::min(max_dim, cat2_num));
outputs:
-1392522416, 3, 1, 1
2, 3, 2, 2
3, 3, 3, 3
-1392522416, 3, 1, 1
3, 3, 6, 3
2, 3, 2, 2
-1392522416, 3, 1, 1
-1392522416, 3, 1, 1
2, 3, 2, 2
=========== updated ========
I couldn't reproduce the undefined behavior with these codes:
#include <iostream>
#include <vector>
int main() {
std::vector<int32_t> v = {-1, 0, 1, 2, 3, 6};
const int a = 3;
const auto& b = a;
for(size_t i = 0; i < v.size(); i++) {
const auto& c = v[i];
const auto& d = std::max(1, std::min(b, c));
std::cout << d << ", " << b << ", " << c << std::endl;
}
return 0;
}
output:
1, 3, -1
1, 3, 0
1, 3, 1
2, 3, 2
3, 3, 3
3, 3, 6
Your code has undefined behavior. In
const auto& res_num = std::max(1, std::min(max_dim, cat2_num));
The 1 is a prvalue, so a temporary integer is created that gets bound to the function parameter. This would be okay of max was like
template <typename T> const T max(const T&, const T&);
but instead it is defined like
template <typename T> const T& max(const T&, const T&);
So, if that 1 happens to be the maximum value, then max returns to you a reference to that temporary object that was created. After that, the temporary object is destroyed1, leaving res_num as a dangling reference. To fix the code make res_num a non-reference like
const auto res_num = std::max(1, std::min(max_dim, cat2_num));
and now you get a copy of the correct value.
1: all temporaries are destroyed at the end of the full expression the are created in
#NathanOliver has given clear declaration for the cause. Here is some other related infomation.
const T& is helpful for large objects, but it involves lifetime and aliasing problem. So be careful.
For int, double, pointers values, const T& gains nothing. In this situation, copy is cheaper than reference.
reference: int vs const int&
I am using gcc compiler on ubuntu 16 , when I am printing value garbage value is getting displayed
#include <bits/stdc++.h>
int Arrayprint(int r, int l, unsigned int* q)
{
r = 3;
l = 4;
for (int i = 0; i < r; i++) {
for (int j = 0; j < l; j++) {
cout << *(q + sizeof(unsigned int) * (i * l + j)); //Garbage getting diplay
cout << *(q + i + j); //this working
cout << "\t";
}
}
cout << "size of unsigned int : " << sizeof(unsigned int); //4
cout << "size of int : " << sizeof(int); //4
}
int main()
{
unsigned int image[R][L] = { { 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 } };
unsigned int* q = (unsigned int*)image;
Arrayprint(R, L, q);
}
From what I can tell, you understand at a low level that the address of the ith element of an array of T is base + sizeof(T) * i. That's correct, and it's good that you know that.
However, C and C++ handle this for you already. When you say q + i or q[i], it's actually compiling that into q + sizeof(T)*i anyway (with the latter also dereferencing the result).
So when you say q[sizeof(int)*i], that's actually compiling into *(q + sizeof(int)*sizeof(int)*i), which is clearly not what you wanted.
Thus, the index in the array you actually access is off by a factor of sizeof(int) and results in an out of bounds error, which is where your strange numbers are coming from.
I am using gcc compiler on ubuntu 16 , when I am printing value
garbage value is getting displayed
Instead of trying to fix what's broken in your raw array arimethics, consider using the standard containers:
#include <iostream>
#include <array>
constexpr size_t R = 3;
constexpr size_t L = 4;
using image_t = std::array<std::array<unsigned int, L>, R>;
void Arrayprint(const image_t& q) {
// range based for loops for convenience
for(auto& row : q) { // get references to each row
for(unsigned int colval : row) { // get the column values
std::cout << colval << "\t"; // print the values
}
std::cout << "\n";
}
}
int main() {
image_t image = {{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}};
Arrayprint(image);
}
Output:
1 2 3 4
5 6 7 8
9 10 11 12
I have a struct that has hardcoded data in it, however I can't figure out how to get c++ to display the data. What I am trying is:
#include <iostream>
using namespace std;
const int MAX = 8;
struct test {
int x[MAX] = { 16, 21, 308, 45, 51, 63, 17, 38 };
float y[MAX] = { 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5 };
int z[MAX] = { 8, 7, 6, 5, 4, 3, 2, 1 };
} id[MAX] = { 1, 2, 3, 4, 5, 6, 7, 8 };
int main() {
for (int counter = 0; counter < MAX; counter++) {
cout << id[counter].x << ", " << id[counter].y << ", "<< id[counter].z << endl;
}
}
I suggest you change your data layout:
struct Triplet
{
int x;
float y;
int z;
};
Next, make a container of the values:
std::vector<Triplet> test;
Or
Triple test[MAXIMUM_CAPACITY];
This should make your initializations easier.
It may also speed up your program by keeping relevant data closer together in the data cache.
I can't figure out how to get c++ to display the data.
You've been shooting over regarding usage of hardcoded arrays.
You don't need to double up your dimensions for struct. Any struct initialization will preserve the necessary memory for it's members.
You probably meant to write something like
#include <iostream>
using namespace std;
const int MAX = 8;
struct test
{
int x; // A simple int
float y; // A simple float
int z; // A simple int
} const id[MAX] = // Preserve the dimension. Note the const, to prevent changing the
// hardcoded values.
// Initialize the triples as needed
{ { 16, 1.5, 8 } ,
{ 308, 2.5, 7 } ,
// Place more triples here ...
{ 38, 8.5, 1 }
};
int main()
{
for (int counter = 0; counter < MAX; counter++)
{
cout << id[counter].x << ", " << id[counter].y << ", "<< id[counter].z << endl;
}
return 0;
}
See the Live Demo
The idiomatic c++ way to write this would be
struct test {
int x; // A simple int
float y; // A simple float
int z; // A simple int
};
std::array<test,MAX> id {{
{ 16, 1.5, 8 } ,
{ 308, 2.5, 7 } ,
// Place more triples here ...
{ 38, 8.5, 1 }
}};
See Live Demo
I know this has been asked before but I still don't know how to do it. I Have to write a function which returns the number of times 2, 5 and 9 appear in an array.
include <iostream>
int twofivenine(int array[], int n)
{
int i = 0;
int num_2 = 0;
int num_5 = 0;
int num_9 = 0;
for ( i = 0; i < n; i++ ){
switch(){
case (array[i] == 2):
num_2++;
case (array[i] == 5):
num_5++;
case (array[i] == 9):
num_9++;
}
}
return ;
}
int main()
{
int array[6] = {2,2,3,5,9,9};
std::cout << "2: 5: 9:" << twofivenine(array, 6) << std::endl;
}
I'm just not sure how to return (num_2, num_5, and num_9)
Can use std::tuple
std::tuple<int, int, int > twofivenine( int array[], int n)
{
//
return make_tuple( num_2, num_5, num_9 );
}
auto x = twofivenine( array, 6 );
std::cout << std::get<0>( x ) << '\n'
<< std::get<1>( x ) << '\n'
<< std::get<2>( x ) << '\n' ;
There are a number of ways to approach this problem.
Pass the values by reference. You can call a function such as the following:
Example:
void foo(int &a, int &b, int &c)
{
// modify a, b, and c here
a = 3
b = 38
c = 18
}
int first = 12;
int second = 3;
int third = 27;
foo(first, second, third);
// after calling the function above, first = 3, second = 38, third = 18
Store the values to return in a data type. Use a data type from the standard library such as std::vector, std::set, std::tuple, etc. to hold your values then return that entire data member.
Example:
std::vector<int> foo()
{
std::vector<int> myData;
myData.pushBack(3);
myData.pushBack(14);
myData.pushBack(6);
return myData;
}
// this function returns a vector that contains 3, 14, and 6
Create an object to hold your values. Create an object such as a struct or a class to hold your values and return the object in your function.
Example:
struct myStruct
{
int a;
int b;
int c;
};
myStruct foo()
{
// code here that modifies elements of myStruct
myStruct.a = 13;
myStruct.b = 2;
myStruct.c = 29;
return myStruct;
}
// this function returns a struct with data members a = 13, b = 2, and c = 29
The method you choose will ultimately depend on the situation.
Pass objects in by reference, ie
void twofivenine(int array[], int n, int &num_2, int &num_5, int &num_9)
{
//Don't redeclare num_2...
}
Call like so:
int num_2, num_5, num_9;
twofivenine(array, 6, num_2, num_5, num_9);
Return a struct by value which has the counts as the data members:
struct Result {
int num_3;
int num_5;
int num_9;
};
Result twofivenine(int array[], int n)
{
.
.
.
return Result{num_2, num_5, num_9};
}
and in main:
Result result(twofivenine(array, 6));
std::cout << "2: " << result.num_2 << "5: " << result.num_5 << "9: " << result.num_9 << std::endl;
Most compilers will do RVO (return-value-optimization) where the twofivenine function will directly write to the result struct avoiding a struct copy.