C++ 2D Vector initialization with another vector - c++

vector<vector<double>> weights
{
{1},
{1}
};
Above is my code to make a 2x1 vector each holding 1.
I would like to make a matrix of 2xN that I could use to multiply with that vector.
I have seen other stackoverflow questions that talk about creating matrices, and most of the ones I've seen are with fixed values, or user input.
But what I would like to do, is initialize the entire first column of N length with 1s, and the initialize the entire second column with a second vector I already have.
I am unsure how in C++ I could accomplish this. I'm way more familiar with R, and in R this is a pretty simple task. Any thoughts or guidance?

You mean like this?
std::vector<int> vinner {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
};
std::vector<std::vector<int>> v {
std::vector<int>(10, 1),
vinner
};
int main(int argc, char **argv)
{
for (auto i : v) {
for (auto j : i) {
std::cout << j << " ";
}
std::cout << "\n";
}
return 0;
}
Output:
$ clang++ -o vect vect.cpp -std=c++17
$ ./vect
1 1 1 1 1 1 1 1 1 1
1 2 3 4 5 6 7 8 9 10

Related

How to roll the rows of a Eigen:Matrix?

I want to reindex a Eigen:Matrix by rolling N∈ℤ rows like this (here N=+1):
1 4 7 -> 3 6 9
2 5 8 1 4 7
3 6 9 2 5 8
Is there a simple way, or do I have to create a new matrix and copy over the data?
I suggest setting up a new matrix and copying the data. Eigen's block operations allow doing this in an efficient way. Here is how a shift by n rows can be done for the example above.
MatrixXi A(3,3);
A << 1, 2, 3, 4, 5, 6, 7, 8, 9;
A.transposeInPlace();
int n = 1; // number of shifts
n = n % A.rows();
MatrixXi B(A.rows(), A.cols());
B.bottomRows(A.rows() - n) = A.topRows(A.rows() - n);
B.topRows(n) = A.bottomRows(n);
std::cout << "B = " << B << std::endl;
If you are interested in a matlab-like syntax you can also use
MatrixXd A;
//... fill A
VectorXi indices = {{2,0,1}};
A(indices, Eigen::all);
I don't know, whether this internally makes a copy.
Note: This does not work for Sparse matrices, see Subset columns of sparse eigen matrix

Pointer to portions of array

I have an object of std::vector<std::array<double, 16>>
vector entry Data
[0] - 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
[1] - 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
[2] - 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
[...] - 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
This is intended to represent a 4x4 matrix in ravel format.
To not duplicate information I would like to create a pointer to extract a 3x3 from the above structure:
I have mathematical operations for the 3x3 structure (std::array<double, 9>)
someStructure: pointing to data elements [0, 1, 2, 4, 5, 6, 8, 9 10]
The end goal is do: std::array<double, 9> tst = someStructure[0] + someStructure[1];
Is this doable?
Best Regards
The 3x3 part is not contiguous, hence a pointer alone wont help here.
You can write a view_as_3x3 that allows you to access elements of the submatrix of the 4x4 as if it was contiguous:
struct view_as_3x3 {
double& operator[](size_t index) {
static const size_t mapping[] = {0, 1, 2, 4, 5, 6, 8, 9, 10};
return parent[mapping[index]];
}
std::array<double, 16>& parent;
};
Such that for example
for (size_t = 0; i< 9; ++i) std::cout << " " << view_as_3x3{orignal_matrix}[i];
is printing the 9 elements of the 3x3 sub-matrix of the original 4x4 original_matrix.
Then you could more easily apply your 3x3 algorithms to the 3x3 submatrix of a 4x4 matrix. You just need to replace the std::array<double, 9> with some generic T. For example change
double sum_of_elements(const std::array<double, 9>& arr) {
double res = 0;
for (int i=0;i <9; ++i) res += arr[i];
return res;
}
To:
template <typename T>
double sum_of_elements(const T& arr) {
double res = 0;
for (int i=0;i <9; ++i) res += arr[i];
return res;
}
The calls are then
std::array<double, 16> matrix4x4;
sum_of_elements(view_as_3x3{matrix4x4});
// or
std::array<double, 9> matrix3x3;
sum_of_elements(matrix3x3);
It would be nicer to use iterators instead of indices, however, writing the view with custom iterators requires considerable amount of boilerplate. On the other hand, I would not suggest to use naked std::arrays in the first place, but rather some my_4x4matrix that holds the array as member and provides iterators and more convenience methods.

Weird issue with range based for loop

I am working on learning vectors in my C++ object oriented 1 class and we have been introduced the concept of range based for loops. I decided to practice the range based for-loops separately so that I could get used to the syntax but I came across a weird issue.
#include<iostream>
using namespace std;
int main()
{
int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
for ( auto i: a)
{
cout << a[i] << " ";
}
return 0;
}
When I run the above code my output is the following.
2 3 4 5 6 7 8 9 0 1 Press any key to continue...
My output should read
1 2 3 4 5 6 7 8 9 0 Press any key to continue...
Can anyone tell me why my first index is skipped? I have visual studio 2013 professional.
You get the weird output because i in the range loop is the value from the array, not an index. That is,
for (auto i : a)
loops through the values of a. In your code you're effectively printing the sequence a[a[0]], a[a[1]], etc.
The code you probably want is
for (auto i : a) {
std::cout << i << std::endl;
}

How to detect all possible subsets from a given vector?

I'm writing a function which should detect all possible subsets from a main vector and push them to another vector. The elements in the subsets are also added to each other before being pushed into the new vector(s1).
At the moment what my code does is the following..
For example, lets say myvec = {1,2,3}, then v1 = {1,3,6,2,5,3}. It only sums consecutive numbers. However I also want it to sum up combinations like 1 & 3 which would add a 4 to the vector v1. At the moment, I have not been able to modify my algorithm in a way that I can achieve that. Any help will be appreciated!
for (k=0; k<myvec.size(); k++) {
total = 0;
for (m=k; m<int_vec.size(); m++) {
total += myvec[m];
v1.push_back(total);
}
}
One way to think about the power set of a given (ordered) set is to think of its elements (the subsets) as bit vectors where the n-th bit is set to 1 if and only if the n-th element from the set was chosen for this subset.
So in your example, you'd have a 3 bit vector that could be represented as an unsigned integer. You'd “count the bit vector” up from 0 (the empty set) to 7 (the entire set). Then, in each iteration, you pick those elements for which the respective bit is set.
As can be readily seen, the power set explodes rapidly which will make it impractical to compute explicitly for any set with more than a dozen or so elements.
Casting these thoughts into C++, we get the following.
#include <climits> // CHAR_BIT
#include <iostream> // std::cout, std::endl
#include <stdexcept> // std::invalid_argument
#include <type_traits> // std::is_arithmetic
#include <vector> // std::vector
template<typename T>
std::vector<T>
get_subset_sums(const std::vector<T>& elements)
{
static_assert(std::is_arithmetic<T>::value, "T must be arithmetic");
if (elements.size() > CHAR_BIT * sizeof(unsigned long))
throw std::invalid_argument {"too many elements"};
const std::size_t power_size {1UL << elements.size()};
std::vector<T> subset_sums {};
subset_sums.reserve(power_size);
for (unsigned long mask = 0UL; mask < power_size; ++mask)
{
T sum {};
for (std::size_t i = 0; i < elements.size(); ++i)
{
if (mask & (1UL << i))
sum += elements.at(i);
}
subset_sums.push_back(sum);
}
return subset_sums;
}
int
main()
{
std::vector<int> elements {1, 2, 3};
for (const int sum : get_subset_sums(elements))
std::cout << sum << std::endl;
return 0;
}
You might want to use a std::unordered_set for the subset-sums instead of a std::vector to save the space (and redundant further processing) for duplicates.
The program outputs the numbers 0 (the empty sum), 1 (= 1), 2 (= 2), 3 (= 1 + 2), 3 (= 3), 4 (= 1 + 3), 5 (= 2 + 3) and 6 (= 1 + 2 + 3). We can make this more visual.
mask mask
(decimal) (binary) subset sum
–––––––––––––––––––––––––––––––––––––––––––––––––
0 000 {} 0
1 001 {1} 1
2 010 {2} 2
3 011 {1, 2} 3
4 100 {3} 3
5 101 {1, 3} 4
6 110 {2, 3} 5
7 111 {1, 2, 3} 6

Regarding vector values

Here is a code snippet below.
Input to program is
dimension d[] = {{4, 6, 7}, {1, 2, 3}, {4, 5, 6}, {10, 12, 32}};
PVecDim vecdim(new VecDim());
for (int i=0;i<sizeof(d)/sizeof(d[0]); ++i) {
vecdim->push_back(&d[i]);
}
getModList(vecdim);
Program:
class dimension;
typedef shared_ptr<vector<dimension*> > PVecDim;
typedef vector<dimension*> VecDim;
typedef vector<dimension*>::iterator VecDimIter;
struct dimension {
int height, width, length;
dimension(int h, int w, int l) : height(h), width(w), length(l) {
}
};
PVecDim getModList(PVecDim inList) {
PVecDim modList(new VecDim());
VecDimIter it;
for(it = inList->begin(); it!=inList->end(); ++it) {
dimension rot1((*it)->length, (*it)->width, (*it)->height);
dimension rot2((*it)->width, (*it)->height, (*it)->length);
cout<<"rot1 "<<rot1.height<<" "<<rot1.length<<" "<<rot1.width<<endl;
cout<<"rot2 "<<rot2.height<<" "<<rot2.length<<" "<<rot2.width<<endl;
modList->push_back(*it);
modList->push_back(&rot1);
modList->push_back(&rot2);
for(int i=0;i < 3;++i) {
cout<<(*modList)[i]->height<<" "<<(*modList)[i]->length<<" "<<(*modList)[i]->width<<" "<<endl;
}
}
return modList;
}
What I see is that the values rot1 and rot2 actually overwrite previous values.
For example that cout statement prints as below for input values defined at top. Can someone tell me why are these values being overwritten?
rot1 7 4 6
rot2 6 7 4
4 7 6
7 4 6
6 7 4
rot1 3 1 2
rot2 2 3 1
4 7 6
3 1 2
2 3 1
You are storing pointers to local variables when you do this kind of thing:
modList->push_back(&rot1);
These get invalidated every loop cycle. You could save yourself a lot of trouble by not storing pointers in the first place.