I need to write constructors for my 3x3 matrix class. I'm not sure whether I'm doing it efficiently and I do not know how to use initializer_list.. I would like a constructor that creates by default the identity matrix, and receives parameteres to set a diagonal matrix. Then I'd also like a constructor that takes a list of cofficients (with initialization_list) and puts them in the matrix. This is what I have:
#include <iostream>
#include <array>
#include <cmath>
#include <initializer_list>
#include "Vecteur.h"
using namespace std;
class Matrice33 {
private :
array<array<double,3>,3> matrice;
public :
Matrice33(double a = 1, double b=1, double c=1)
{ matrice[0][0] = a; matrice[1][1]= b; matrice [2][2]= c;
matrice[0][1] = 0; matrice[0][2] = 0;
matrice[1][0] = 0; matrice[1][2] = 0;
matrice[2][0] = 0; matrice[2][1] = 0;} \\ IS THIS THE ONLY WAY TO SET THE MATRIX OR IS
\\THERE A QUICKER ONE?
Matrice33(initilizer_liste<double> cosnt& coeff)
{ for( auto c : coeff) \\ I DON'T KNOW HOW TO WRITE THIS CONSTRUCTOR...
void affiche() const { for(auto m : matrice){
for(auto n : m) {
cout<<n<<" ";}
cout<<endl;}}
};
int main(){
Matrice33 mat(1.1, 1.2, 1.3,
2.1, 2.2, 2.3,
3.1, 3.2, 3.3); \\I'D LIKE THIS TO BE TAKEN AS THE LIST BY MY CONSTRUCTOR, FOR
\\EXAMPLE
Matrice33 m(2.0,3.0,1.0);
m.affiche(); \\ WHEN I EXECUTE I DON'T GET ANY OUTPUT..
return 0;
}
This is changed version of your code that is just working.
#include <iostream>
#include <array>
#include <cmath>
#include <initializer_list>
#include <vector>
using namespace std;
class Matrice33
{
public:
Matrice33(double a = 1, double b = 1, double c = 1)
: matrice{{ {{a, 0, 0}}, {{0, b, 0}}, {{0, 0, c}} }}
{
}
Matrice33(const std::initializer_list<std::initializer_list<double>> & coeff)
{
int counter = 0;
for (auto row : coeff)
{
copy(row.begin(), row.end(), matrice[counter++].begin());
}
}
void affiche()
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
cout << matrice[i][j] << " ";
}
cout << endl;;
}
}
private:
array<array<double, 3>, 3> matrice;
};
int main()
{
Matrice33 mat{ {1.1, 1.2, 1.3},{2.1, 2.2, 2.3},{3.1, 3.2, 3.3} };
mat.affiche();
Matrice33 m(2.0, 3.0, 1.0);
m.affiche();
return 0;
}
You can use perfect forwarding and template constructor here.
template<typename... Args>
Matrice33(Args&&... args) : matrice(std::forward<Args>(args)...) {}
then initialization will be same as intitialization of std::array.
Related
I'm trying to call a variable which is declared in the constructor in the operator() function. Variable is declared of type boost::multi_array<float, 2>. But still it throws the error:
error: no match for ‘operator /’
I guess boost library has these predefined operators! Can anyone see what I'm doing wrong here?
#ifndef CORRELATOR_CHARACTERISTIC_FUNCTION_HPP
#define CORRELATOR_CHARACTERISTIC_FUNCTION_HPP
#include <halmd/numeric/blas/fixed_vector.hpp>
#include <cmath>
#include <boost/multi_array.hpp>
#include "read_box.hpp"
namespace correlator {
class Characteristic_function
{
public:
typedef std::shared_ptr<boost::multi_array<float, 2>> sample_type;
typedef halmd::fixed_vector<double, 3> result_type;
using k_type = boost::multi_array<float, 2>;
Characteristic_function()
{
// using array_2d_t = boost::multi_array<float, 2>;
read_box read_box_file;
// auto b = read_box_file.open_dataset("file.h5");
k_type frame_b = read_box_file.read_frame(1);
auto w = frame_b[0][0];
}
result_type operator()(sample_type const &first, sample_type const &second) const
{
result_type c_func = 0;
size_t N = first->size();
N = std::min(100UL, N);
Characteristic_function w;
// k_type Characteristic_function wave;
// std::cout << "First wave vector: " << wave[0][1] << std::endl;
double k = 2 * M_PI/w;
for (unsigned int i = 0; i < N; ++i) {
for (unsigned int j = 0; j <= 0; ++j) {
double dr = (*first)[i][j] - (*second)[i][j];
c_func[j] = exp(k*dr);
}
}
return c_func / static_cast<double>(N);
}
};
}
#endif /* ! CORRELATOR_CHARACTERISTIC_FUNCTION_HPP */
w just a float number and I want to use this number in the operator() function.
You can do something like this:
/* Characteristic function */
#ifndef CORRELATOR_CHARACTERISTIC_FUNCTION_HPP
#define CORRELATOR_CHARACTERISTIC_FUNCTION_HPP
#include <halmd/numeric/blas/fixed_vector.hpp>
#include <cmath>
#include <boost/multi_array.hpp>
#include <complex>
#include "read_box.hpp"
namespace correlator {
class Characteristic_function
{
private:
double w;
public:
typedef std::shared_ptr<boost::multi_array<float, 2>> sample_type;
typedef halmd::fixed_vector<double, 3> result_type;
// using k_type = boost::multi_array<float, 2>;
typedef boost::multi_array<float, 2> k_type;
Characteristic_function()
{
read_box read_box_file;
k_type frame_b = read_box_file.read_frame(1);
w = frame_b[0][0];
}
result_type operator()(sample_type const &first, sample_type const &second) const
{
result_type c_func = 0;
size_t N = first->size();
N = std::min(100000UL, N);
double k = 2 * M_PI / w;
for (unsigned int i = 0; i < N; ++i) {
for (unsigned int j = 0; j <= 0; ++j) {
double dr = exp( k*((*first)[i][j] - (*second)[i][j]) );
c_func[j] = dr;
}
}
return c_func / static_cast<double>(N);
}
};
}
#endif /* ! CORRELATOR_CHARACTERISTIC_FUNCTION_HPP */
It will automatically reads the value of w.
I implented a contructor for my matrix class to do brace-enclosed initialization using nested std::initializer_list. The constructor works fine for primary type: `int`, `double`; but renders error-reading for `complex`. How to fix this error reading?
The matrix class
template <typename T> class xxx
{
public:
T *ptr;
int col, row, size;
xxx() = delete;
xxx(const int i, const int j):row(i), col(j), size(i*j)
{
ptr = new T [this->size] ;
}
xxx(const std::initializer_list< std::initializer_list<T> > s):xxx(s.size(), s.begin()->size())
{
int j = 0;
for (const auto& i : s) { std::copy (i.begin(), i.end(), ptr + j*col); ++j ; }
}
~xxx() {delete [] this->ptr;}
T operator()(const int i, const int j) const { return ptr[i*col+j]; }
};
A typical ouput overload is added here for complete.
template <typename X> std::ostream& operator<<(std::ostream&p, const xxx<X>&a)
{
for (int i=0; i<a.row; i++) {
for (int j=0; j <a.col; j++) p << std::setw(6) << a(i, j);
p << std::endl;
}
return p;
}
The first test main() with type `double` works well.
#include <iostream>
#include <initializer_list>
#include <iomanip>
#include <complex>
int main()
{
xxx<double> x = {{1, 2,3,4} , {3, 4,5,6}, {5, 6,7,8} };
std::cout << x << std::endl;
}
It prints what is expected:
$ ./a.exe
1 2 3 4
3 4 5 6
5 6 7 8
Then, I try with another type of my interested, `complex`:
int main()
{
xxx< std::complex<double> > z = { {(1,2), (3,4)}, {(5,6), (7,8)} };
std::cout << z << std::endl;
}
The outpur is wrong as follows:
$ ./a.exe
(2,0) (4,0)
(6,0) (8,0)
The imaginery part is missing, and the real parts are taking values of the counter imaginery part. Any idea or suggestion will be highly appreciated.
Your problem is not related to the initializer list. The problem is that this code
#include <iostream>
#include <complex>
int main()
{
std::complex<double> x = (1,2);
std::cout << x;
}
Is not doing what you expect it to do. Output is
(2,0)
Because (1,2) is the comma operator at work. std::complex<double> x = (1,2); is the same as std::complex<double> x = 2;.
You need to use curly braces for initialization:
#include <iostream>
#include <complex>
int main()
{
std::complex<double> x = {1,2};
std::cout << x;
}
Output
(1,2)
PS I would strongly advise you to use a std::vector<T> to hold the data rather than a T*. Currently copying a xxx will cause undefined behavior, due to not following the rule of 3/5.
I'm trying to transform a float3 array by using containers into a container of a specific structure. Code below:
#include <thrust/device_ptr.h>
#include <thrust/extrema.h>
#include <thrust/reduce.h>
#include <thrust/execution_policy.h>
#include <thrust/functional.h>
// Ouput structure for thrust::transform
struct cloud_point_index_idx {
unsigned int idx;
float3 cloud_point;
cloud_point_index_idx(unsigned int idx_, float3 cloud_point_) :
idx(idx_), cloud_point(cloud_point_) {}
bool operator < (const cloud_point_index_idx &p) const {
return (idx < p.idx);
}
};
// Functor for thrust::transform
struct point2voxelcentroid {
float3 leaf_size;
int min_x, min_y, min_z;
point2voxelcentroid(float3 leaf_size,int min_x, int min_y, int min_z) {
this->leaf_size = leaf_size;
this->min_x = min_x; this->min_y = min_y; this->min_z = min_z;
}
__host__ __device__
cloud_point_index_idx operator()(const float3 point) const {
int ijk0 = static_cast<int>(floor(point.x / leaf_size.x) -
static_cast<float>(min_x));
int ijk1 = static_cast<int>(floor(point.y / leaf_size.y) -
static_cast<float>(min_y));
int ijk2 = static_cast<int>(floor(point.z / leaf_size.z) -
static_cast<float>(min_z));
int voxel_idx = ijk0 + ijk1 + ijk2;
return cloud_point_index_idx(static_cast<unsigned int>(voxel_idx), point);
}
};
int main() { // Example
int num_points = 5;
float3 data[5] = {{1, 0, 2}, {2, 1, 3}, {1, 1, -5}, {-1, 3, -2}, {-5, -2, 0}}; // Set the data
int min_b_[3] = {-5, -2, -5};
float3 leaf_size = {0.5, 0.5, 0.5};
thrust::device_vector<float3> d_ptr(data, data + num_points); // Wrap it into a device_vector
thrust::device_vector<cloud_point_index_idx> voxel_idx_vector; // Output
voxel_idx_vector.reserve(num_points);
thrust::transform(
thrust::device,
d_ptr.begin(), d_ptr.end(),
voxel_idx_vector.begin(),
point2voxelcentroid(leaf_size, min_b_[0], min_b_[1], min_b_[2]));
thrust::host_vector<cloud_point_index_idx> indices; // Host vector to verify
indices.reserve(num_points);
thrust::copy(voxel_idx_vector.begin(), voxel_idx_vector.end(), indices.begin()); // Copy device to host
// Print out values
std::cout << "\n---\nAfter assignment\n";
for (int i = 0; i < num_points; i++) {
std::cout << "Voxel idx: " << indices[i].idx << ". Point: [" << indices[i].cloud_point.x << ", "
<< indices[i].cloud_point.y << ", " << indices[i].cloud_point.z << std::endl;
}
}
I inspected my functor values and they seem to correctly parse the data but when I print my host_vector I get really weird values, nothing related to what my output must be. I suspect I'm not initializing my output host/device vectors correctly. I tried other methods to initialize them but they all give me errors when compiling. I'm not sure what I'm doing wrong.
There are a couple of problems here, but the most severe is the use of reserve which doesn't actually allocate memory for a thrust container.
What you need to do is define a default constructor and explicitly allocate a size at instantiation. Something like this:
struct cloud_point_index_idx {
int idx;
float3 cloud_point;
cloud_point_index_idx()=default;
__host__ __device__
cloud_point_index_idx(unsigned int idx_, float3 cloud_point_) :
idx(idx_), cloud_point(cloud_point_) {}
__host__ __device__
bool operator < (const cloud_point_index_idx &p) const {
return (idx < p.idx);
}
};
(requires -std=c++11) will define a default constructor on both device and host which the container must call during initialization of each class instance.
This modification of your code works for me:
$ cat bodgey.cu
#include <thrust/device_vector.h>
#include <thrust/device_ptr.h>
#include <thrust/extrema.h>
#include <thrust/reduce.h>
#include <thrust/execution_policy.h>
#include <thrust/functional.h>
#include <iostream>
// Ouput structure for thrust::transform
struct cloud_point_index_idx {
int idx;
float3 cloud_point;
cloud_point_index_idx()=default;
__host__ __device__
cloud_point_index_idx(unsigned int idx_, float3 cloud_point_) :
idx(idx_), cloud_point(cloud_point_) {}
__host__ __device__
bool operator < (const cloud_point_index_idx &p) const {
return (idx < p.idx);
}
};
// Functor for thrust::transform
struct point2voxelcentroid {
float3 leaf_size;
int min_x, min_y, min_z;
point2voxelcentroid(float3 leaf_size,int min_x, int min_y, int min_z) {
this->leaf_size = leaf_size;
this->min_x = min_x; this->min_y = min_y; this->min_z = min_z;
}
__host__ __device__
cloud_point_index_idx operator()(const float3 point) const {
int ijk0 = static_cast<int>(floor(point.x / leaf_size.x) -
static_cast<float>(min_x));
int ijk1 = static_cast<int>(floor(point.y / leaf_size.y) -
static_cast<float>(min_y));
int ijk2 = static_cast<int>(floor(point.z / leaf_size.z) -
static_cast<float>(min_z));
int voxel_idx = ijk0 + ijk1 + ijk2;
return cloud_point_index_idx(voxel_idx, point);
}
};
int main() { // Example
int num_points = 5;
float3 data[5] = {{1, 0, 2}, {2, 1, 3}, {1, 1, -5}, {-1, 3, -2}, {-5, -2, 0}}; // Set the data
int min_b_[3] = {-5, -2, -5};
float3 leaf_size = {0.5, 0.5, 0.5};
thrust::device_vector<float3> d_ptr(data, data + num_points); // Wrap it into a device_vector
thrust::device_vector<cloud_point_index_idx> voxel_idx_vector(num_points); // Output
thrust::transform(
thrust::device,
d_ptr.begin(), d_ptr.end(),
voxel_idx_vector.begin(),
point2voxelcentroid(leaf_size, min_b_[0], min_b_[1], min_b_[2]));
thrust::host_vector<cloud_point_index_idx> indices(num_points); // Host vector to verify
thrust::copy(voxel_idx_vector.begin(), voxel_idx_vector.end(), indices.begin()); // Copy device to host
// Print out values
std::cout << "\n---\nAfter assignment\n";
for (int i = 0; i < num_points; i++) {
std::cout << "Voxel idx: " << indices[i].idx << ". Point: [" << indices[i].cloud_point.x << ", "
<< indices[i].cloud_point.y << ", " << indices[i].cloud_point.z << std::endl;
}
}
$ nvcc -std=c++11 -arch=sm_52 -o bodgey bodgey.cu
$ ./bodgey
---
After assignment
Voxel idx: 18. Point: [1, 0, 2
Voxel idx: 24. Point: [2, 1, 3
Voxel idx: 6. Point: [1, 1, -5
Voxel idx: 12. Point: [-1, 3, -2
Voxel idx: -2. Point: [-5, -2, 0
I'm trying to develop a nice basic class Matrix , it's container is a simpler pointer to data_type (template argument);
I'would like to figure out how can i construct my Matrix in this way :
Matrix<type> mat = { {1,2,3}, {4,5,6} };
right now the only way to construct with given an arbitrary number of parameter is using this constructor :
//--- construct by list of arguments
template<typename data_type>
template <typename ... Ts>
constexpr Matrix<data_type>::Matrix(std::size_t row ,
std::size_t col ,
Ts&&... args ) noexcept : row{row}, columns{col},
data{ new data_type[row*col] }
{
assert(sizeof...(args) == row*columns );
std::initializer_list<data_type> il ( { std::forward<Ts>(args)... } );
std::copy(il.begin(), il.end(), data);
}
but for using this I have to use this crap expression in the user-side code :
Matrix<double> m3(3,2,1.12,2.434,3.546546,4.657,5.675675,6.542354);
thanks in advance for your precious support !
I've found this solutions.. but i don't know if there is a better way to doing so .... here the completly code (I wrote a matrix class with only this constructor in order to doing some try ) :
# include <iostream>
# include <initializer_list>
# include <iterator>
using namespace std;
template <typename data_type>
class Matrix {
public:
constexpr Matrix(std::initializer_list<std::initializer_list<data_type>> rows) {
size_t row = rows.size() ;
cout << "Here" << endl;
auto il = *(rows.begin());
size_t col = il.size();
cout << row << ' ' << col << endl;
size_t i=0;
size_t n = row * col;
cout << n << endl;;
data = new data_type[ n ];
i=0;
for(auto& row : rows )
for(auto & r : row){
data[i] = r ;
i++;
}
for (i=0; i < n ; i++ )
cout << data[i] << endl;
}
private:
data_type* data;
};
int main(){
Matrix<int> mat = {{1,2,3}, {4,5,6}};
return 0;
}
Would something like this work?
#include <cstddef>
#include <initializer_list>
#include <iostream>
#include <vector>
template<typename data_type>
class Matrix {
public:
constexpr Matrix(std::initializer_list<std::initializer_list<data_type>> rows) {
// Add rows to data
data.reserve(rows.size());
for (auto &row : rows)
data.push_back(std::vector<data_type>{row});
}
private:
// 2-D array-type for storing data
std::vector<std::vector<data_type>> data;
};
int main() {
// New matrix:
// 1 2 3
// 4 5 6
Matrix<int> mat = {{1, 2, 3}, {4, 5, 6}};
return 0;
}
In using packaged_task, I collected all the futures in a vector. After that, I push back the future values with get(). However, I got the wrong answer. Can anyone help? Thank you very much.
#define BOOST_THREAD_PROVIDES_FUTURE
#include <boost/thread/future.hpp>
#include <vector>
#include <iostream>
using namespace std;
vector<int> subFun(int n) {
vector<int> a{ 2 * n, 3 * n };
return a;
}
int main() {
vector<boost::future<vector<int>>> g;
vector<vector<int>> x(10, vector<int>(2));
int i;
for (i = 0; i < 10; i++) {
boost::packaged_task<vector<int>> task{ boost::bind(&subFun, i) };
g.push_back(task.get_future());
boost::thread t{ std::move(task) };
}
for (auto& m : g) {
x.push_back(m.get());
}
cout << x[3][0] << endl;//should be 6, now is 0
return 0;
}
The realest issue is that you push_back into x, but you already had it initialized here:
vector<vector<int>> x(10, vector<int>(2));
So, you just add 10 more elements, instead of putting the result at indices 0..9. I'd suggest not pre-filling, like #patrick's answer, or instead filling the designated slot:
#define BOOST_THREAD_PROVIDES_FUTURE
#include <boost/thread/future.hpp>
#include <vector>
#include <iostream>
using namespace std;
void subFun(int n, vector<int>& into) {
into = { 2 * n, 3 * n };
}
int main() {
vector<boost::future<void>> futures;
vector<vector<int>> x(10, vector<int>(2));
for (size_t i = 0; i < x.size(); i++) {
boost::packaged_task<void> task{ boost::bind(&subFun, i, std::ref(x[i])) };
futures.push_back(task.get_future());
boost::thread(std::move(task)).detach();
}
for (auto& f : futures)
f.wait();
cout << x[3][0] << endl;
}
Of course you can be more complex:
#define BOOST_THREAD_PROVIDES_FUTURE
#include <boost/thread/future.hpp>
#include <vector>
#include <iostream>
struct TaskResult {
int index;
std::vector<int> data;
};
TaskResult subFun(int n) {
return { n, { 2 * n, 3 * n } };
}
int main() {
std::vector<boost::future<TaskResult>> futures;
std::vector<std::vector<int>> x(10, std::vector<int>(2));
for (size_t i = 0; i < x.size(); i++) {
boost::packaged_task<TaskResult> task{ boost::bind(&subFun, i) };
futures.push_back(task.get_future());
boost::thread(std::move(task)).detach();
}
for (auto& f : futures) {
auto r = f.get();
x[r.index] = r.data;
}
std::cout << x[3][0] << std::endl;
}
After much tinkering, I found this program works without abort traps (which I'm surprised you weren't getting):
#include <future>
#include <thread>
#include <functional>
#include <vector>
#include <iostream>
std::vector<int> subFun(int n) {
std::vector<int> a { 2 * n, 3 * n };
return a;
}
int main() {
std::vector<std::future<std::vector<int>>> g;
std::vector<std::vector<int>> x;
int i;
for (i = 0; i < 10; i++) {
std::packaged_task<std::vector<int>(int)> task{ subFun };
g.push_back(task.get_future());
std::thread { std::move(task), i }.detach();
}
for (auto& m : g) {
m.wait();
x.push_back(m.get());
}
std::cout << x[3][0] << std::endl; // is now 6
return 0;
}
Convert to boost as necessary. This answer was extremely helpful in finding a couple of key issues.