This slices MatrixXd with a Array<bool, Dynamic, 1>, just like in Matlab you can do A(A>5), here you can do slice(A, A.array() > 5). I'd like to turn this into a templated version, so that it can take any type of matrices or vectors, for instance Matrix3i or VectorXi. This page tell me to use MatrixBase<Derived>, but I was not able to get very far with it. Idk how to declare a templated matrix of a certain size.
https://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html
#include <Eigen/Dense>
using namespace Eigen;
MatrixXd slice(const MatrixXd & mat, const Array<bool, Dynamic, 1> & ind)
{
assert(mat.cols() == ind.size());
// find out dimensions of the matrix going out
int _cols = 0;
for(int i = 0; i < ind.size(); ++i)
{
if(ind[i] == 1)
{
_cols += 1;
}
}
//populate the matrix going out, in a column major way
int _pos = 0;
MatrixXd out = MatrixXd::Zero(mat.rows(), _cols);
for(int i = 0; i < ind.size(); ++i)
{
if(ind[i] == 1)
{
out.col(_pos) = mat.col(i);
_pos += 1;
}
}
return out;
}
And usage is like this:
MatrixXd A(4, 4);
A << 1,2,3,4,
5,6,7,8,
1,5,6,3,
9,8,6,5;
VectorXd b(4);
b << 23,-4,1234,3;
cout << A << endl;
cout << (b.array() > 5) << endl;
cout << slice(A, b.array() > 5) << endl;
Output is as such:
1 2 3 4
5 6 7 8
1 5 6 3
9 8 6 5
1
0
1
0
1 3
5 7
1 6
9 6
I'd appreciate if anyone would show me how to do this!
PS: There seems to be a similar functionality in the docs:
https://eigen.tuxfamily.org/dox-devel/group__TutorialSlicingIndexing.html
But I was literally unable to find the keyword all in Eigen/Core, as
std::vector<int> ind{4,2,5,5,3};
MatrixXi A = MatrixXi::Random(4,6);
cout << "Initial matrix A:\n" << A << "\n\n";
cout << "A(all,ind):\n" << A(all,ind) << "\n\n";
And my IDE is unable to resolve it either.
Related
i tried to use the strtok function but it requires me to provide the number of rows and columns
void getvalues(char* t,float** v, int n, int m)
{
char* c;
c = strtok(t, "[ ,");
while (c != NULL)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
v[i][j] = atof(c);
c = strtok(0, "[ ,");
}
}
}
}
int main()
{
float** matrix1 = new float* [100];
for (int i = 0; i < 100; i++)
matrix1[i] = new float[100];
float** matrix2 = new float* [100];
for (int i = 0; i < 100; i++)
matrix2[i] = new float[100];
float** matrix3 = new float* [100];
for (int i = 0; i < 100; i++)
matrix3[i] = new float[100];
int n, m,r ,f;
char s[999];
char d[999];
char choice;
cin.getline(s, 999);
getvalues(s, matrix1, n, m);
To solve this issue in C++, the C library function strtok() as well as
character arrays char* shouldn't be used.
Better use the vector container from the C++ STL, which can hold dynamical data
and takes care about the memory allocation/deallocation, hence garbage collection.
The final matrix shall be stored in vector<vector<float>>. Please check also the
vector reference.
The input shall be saved in std::string, as it is very robust against input
error, e.g. characters instead of numbers, etc. Please have a look to the
string reference.
The idea of my code is to hold the [1 2 3,4 5 6,7 8 9] matrix input as string
and to submit it to some string manipulation using the methods
string::find and
string::substr to
cut the rows and subsequently the numbers out of the input string.
Every detected number is than converted from string to float using
std::stof, before
it is stored by push_back into the final matrix.
#include <iostream>
#include <string>
#include <vector>
using namespace std; // Should be avoided in real life C++ projects, but for samples ok
// Detect all numbers in one row and store it to a vector of floats (no error handling right now)
vector<float> getMatrixRowNum(const string& givenRow) // Hand row string over as const reference
{
vector<float> ret;
float myFloat;
int startColIndex = 0;
int endColIndex = 0;
while ((endColIndex = givenRow.find(' ', startColIndex)) != string::npos)
{
myFloat = stof(givenRow.substr(startColIndex, endColIndex - startColIndex));
ret.push_back(myFloat);
startColIndex = endColIndex + 1;
}
myFloat = stof(givenRow.substr(startColIndex, endColIndex - startColIndex));
ret.push_back(myFloat);
return ret;
}
int main()
{
string matrixInput;
vector<vector<float>> myMatrix; // STL container for parsed matrix (std::vector)
cout << "Give a matrix in format [1 2 3,4 5 6,7 8 9]:" << endl;
getline(cin, matrixInput);
if (!matrixInput.empty() && matrixInput[0] == '[' && matrixInput.back() == ']')
{
cout << "Given matrix to parse: " << matrixInput << endl;
string matrixTemp = matrixInput.substr(1, matrixInput.length() - 2);
// Start parsing the given matrix string
string matrixRow;
int startRowIndex = 0;
int endRowIndex = 0;
while ((endRowIndex = matrixTemp.find(',', startRowIndex)) != string::npos)
{
matrixRow = matrixTemp.substr(startRowIndex, endRowIndex - startRowIndex);
startRowIndex = endRowIndex + 1;
auto matrixRowNum = getMatrixRowNum(matrixRow);
myMatrix.push_back(matrixRowNum);
};
matrixRow = matrixTemp.substr(startRowIndex);
auto matrixRowNum = getMatrixRowNum(matrixRow);
myMatrix.push_back(matrixRowNum);
// Write the parsed matrix to console output
cout << "\nParsed numerical matrix:" << endl;
for (const auto& row : myMatrix)
{
for (const auto& ele : row)
{
cout << ele << ' ';
}
cout << endl;
}
}
else
{
cout << "Wrong matrix format given: " << matrixInput << " Please try again." << endl;
}
return 0;
}
The console output looks like this:
Give a matrix in format [1 2 3,4 5 6,7 8 9]:
[1 2 3,4 5 6,7 8 9]
Given matrix to parse: [1 2 3,4 5 6,7 8 9]
Parsed numerical matrix:
1 2 3
4 5 6
7 8 9
Some input error handling is added in the code, but it still could be improved, e.g. catching exceptions
for std::stof.
I need to sort a table by column. My tables are represents by a single vector.
example :
col_name A B C
vector : 1 2 3 6 5 4 7 8 9
that give me the table :
A B C
1 6 7
2 5 8
3 4 9
After a sort on column B , I need to obtain :
A B C
3 4 9
2 5 8
1 6 7
my code :
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
int main()
{
std::vector<std::string> vec = {"1","8","1","2","3","2","3",
"5","5","2","5","6","5","6",
"9","3","3","4","8","3","9"};
std::vector<std::string> rec = {"1","1","8","2","2","3","3",
"2","5","5","5","5","6","6",
"3","9","3","4","3","8","9"};
int size = 7;
int col_idx = 1;
for(int i = 0; i<3;++i)
{
if(i==col_idx)
continue;
std::sort(vec.begin() + i*size, vec.begin() + (i+1)*size,
[col_idx, size, i](std::string& s1,std::string& s2)
{
std::cout << s1 << " "
<< s2 << " "
<< *(&s1 +(col_idx - i)*size) << " "
<< *(&s2 +(col_idx - i)*size) << " "
<< (*(&s1 +(col_idx - i)*size) < *(&s2 +(col_idx - i)*size)) << std::endl;
return *(&s1 +(col_idx - i)*size) < *(&s2 +(col_idx - i)*size);
});
}
std::sort(vec.begin() + col_idx*size, vec.begin() + (col_idx+1)*size);
}
assert(vec==res);
I have a segmentation fault error : only the first line appear from the cout.
Honestly, your approach looks rather complicated to me. Most of its complexity is due to the fact that you have rows in your code but they are present only implicitly. Making stuff explicit in code not only helps to increase readability but also makes code easier to write.
Lets say you use std::array<std::string,3> for rows, then your code could be as leightweight as this:
#include <vector>
#include <array>
#include <algorithm>
#include <iostream>
int main() {
using row_t = std::array<std::string,3>;
std::vector<row_t> vec = { {"1","8","1"},{"2","3","2"},{"3","5","5"},{"2","5","6"}};
std::sort(vec.begin(),vec.end(),[](const row_t& a, const row_t& b) { return a[2] < b[2]; });
for (const auto& row : vec) {
for (const auto& e : row) std::cout << e << " ";
std::cout << '\n';
}
}
Output:
1 8 1
2 3 2
3 5 5
2 5 6
Ok, that's probably a good approch for this problem, and maybe it's what should I do, but I can't pass 2 months to change all the code ...
You could have made the requirements more clear in the question. I think if you have 10k lines of code that depend on this particular issue using a flat vector, when a different data structure would be more appropriate, then you have a bigger problem than how to sort rows. Anyhow...
Using a flat std::vector is usually not a bad idea. What I miss from your code is something along the line of
template <int stride>
std::string& access_at(std::vector<std::string>& vec,size_t row,size_t col) {
return vec[ row * stride + col ];
}
template <int stride>
const std::string& access_at(const std::vector<std::string>& vec,size_t row,size_t col) {
return vec[ row * stride + col ];
}
That lets you iterate the table like this:
for (size_t i=0;i < vec.size()/3;++i) {
for (size_t j=0;j<3;++j) {
std::cout << access_at<3>(vec,i,j) << " ";
}
std::cout << '\n';
}
Next I am going to shamelessly steal and modify code from this answer. The basic idea is to sort a vector of indices instead of sorting the vector directly:
using index_t = std::vector<size_t>;
template <int stride>
index_t make_sorted_index(const std::vector<std::string>& values,size_t col) {
index_t index(values.size() / stride);
std::iota(index.begin(), index.end(), 0);
std::sort(index.begin(),
index.end(),
[&values,&col](size_t a, size_t b) {
return access_at<stride>(values,a,col) < access_at<stride>(values,b,col);
}
);
return index;
}
Once you have that, the loop to print the sorted table need only a minor modification:
for (size_t i=0;i < vec.size()/3;++i) {
for (size_t j=0;j<3;++j) {
std::cout << access_at<3>(vec,index[i],j) << " ";
}
std::cout << '\n';
}
Putting everything together:
#include <vector>
#include <numeric>
#include <algorithm>
#include <iostream>
template <int stride>
std::string& access_at(std::vector<std::string>& vec,size_t row,size_t col) { return vec[ row * stride + col ]; }
template <int stride>
const std::string& access_at(const std::vector<std::string>& vec,size_t row,size_t col) { return vec[ row * stride + col ]; }
using index_t = std::vector<size_t>;
template <int stride>
index_t make_sorted_index(const std::vector<std::string>& values,size_t col) {
index_t index(values.size() / stride);
std::iota(index.begin(), index.end(), 0);
std::sort(index.begin(),
index.end(),
[&values,&col](size_t a, size_t b) { return access_at<stride>(values,a,col) < access_at<stride>(values,b,col); }
);
return index;
}
int main() {
std::vector<std::string> vec = { "1","8","1","2","3","2","3","5","5","2","5","6"};
for (size_t i=0;i < vec.size()/3;++i) {
for (size_t j=0;j<3;++j) {
std::cout << access_at<3>(vec,i,j) << " ";
}
std::cout << '\n';
}
std::cout << '\n';
auto index = make_sorted_index<3>(vec,1);
for (size_t i=0;i < vec.size()/3;++i) {
for (size_t j=0;j<3;++j) {
std::cout << access_at<3>(vec,index[i],j) << " ";
}
std::cout << '\n';
}
}
With output:
1 8 1
2 3 2
3 5 5
2 5 6
2 3 2
3 5 5
2 5 6
1 8 1
I'll leave it to you to actually copy the vector to get the sorted one, if you really need that.
PS: In the first version above I sorted with respect to column C, the last part sorts with respect to B as requested.
PPS: I still dont understand your code. I don't understand why you have std::cout inside the predicate and to be honest I have no clue how your call to sort is supposed to achieve what you want.
I have a deque that contains a series of numbers {0, 1, 2, 3, 4, 5, 6} and I am trying to create all possible combinations of these numbers using recursion.
Here is my current code
void combination(vector<node> &comb, deque<node> &numbers) {
if (numbers.empty()) {
for (unsigned int i = 0; i < comb.size(); i++) {
cout << comb[i].id << " ";
}
cout << "\n";
return;
}
comb.push_back(numbers.front());
numbers.pop_front();
combination(comb, numbers);
comb.pop_back();
combination(comb, numbers);
}
I've ran this through on paper and it makes sense but when I run it this is the output:
0 1 2 3 4 5 6
0 1 2 3 4 5
0 1 2 3 4
0 1 2 3
0 1 2
0 1
0
Why isn't the function printing out all possible combinations?
Also, this is what I want to use - A deque that contains the numbers and a vector that contains each combination.
You are using Pass by reference, i have made some minor changes and it works
code :
#include <bits/stdc++.h>
using namespace std;
void combination(vector<int> comb, deque<int> numbers) {
if (numbers.empty()) {
for (unsigned int i = 0; i < comb.size(); i++) {
cout << comb[i] << " ";
}
cout << "\n";
return;
}
comb.push_back(numbers.front());
numbers.pop_front();
combination(comb, numbers);
comb.pop_back();
combination(comb, numbers);
}
int main() {
// your code goes here
vector<int> comb;
deque<int> numbers;
for(int i = 0;i < 7;i++) numbers.push_back(i);
combination(comb, numbers);
return 0;
}
Link to solution on ideone : http://ideone.com/vgukF3
I am a python programmer, and I am trying to understand boost.
Here is what I got:
>>> import numpy as np
>>> a
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])
>>> b
array([[20, 21, 22],
[23, 24, 25]])
>>> a[[0,2]] = b
>>> a
array([[20, 21, 22], # first row of b
[ 3, 4, 5],
[23, 24, 25], # second row of b
[ 9, 10, 11]])
I can do this using boost:
#include <iostream>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>
using namespace std;
int main()
{
using namespace boost::numeric::ublas;
matrix<double> a (4, 3);
for (unsigned i = 0; i < a.size1 (); ++ i)
for (unsigned j = 0; j < a.size2 (); ++ j)
a (i, j) = a.size2() * i + j;
matrix<double> b (2,3);
for (unsigned i = 0; i < b.size1 (); ++ i)
for (unsigned j = 0; j < b.size2 (); ++ j)
b (i, j) = b.size2() * i + j + 20;
cout << "matrix a : " << a << endl;
cout << "matrix b : " << b << endl;
// replace row 0 in a with row 0 in b
// replace row 2 in a with row 1 in b
unsigned rows[] = {0,2};
int length = sizeof(rows) / sizeof(rows[0]);
for(int i = 0; i < length; i++)
for(int j = 0; j < a.size2(); j++)
a(rows[i], j) = b(i, j);
cout << "matrix a : " << a << endl;
return 0;
}
However, I am not sure whether this is the best way to do it. Looking at the documentation I did not see a built in method for indexing, so it looks like looping is the only option, am I missing anything?
However, looping in C++ might not be that bad. Looping in python in python is slow, and my above example looping takes place at the C level. But looping is not slow in C++, and hence even if we have to manually loop, the code is still efficient is that correct?
Please let me know if my understanding is correct and/or I am missing a better way to implement the above.
Boost.MultiArray is better suited for this sort of indexing. Your Python example can be reproduced as follows:
// helper type for a 2d matrix of ints
using array_type = boost::multi_array<int, 2>;
array_type a(boost::extents[4][3]); // 4x3 matrix
array_type b(boost::extents[2][3]); // 2x3 matrix
Now fill these matrices
std::iota(a.data(), a.data() + a.num_elements(), 0);
std::iota(b.data(), b.data() + b.num_elements(), 20);
Then define a lambda function that'll print a 2d matrix, so we can see the contents
auto array_printer = [](array_type const& arr) {
for(auto const &row : arr) {
for(auto const& elem : row) {
std::cout << std::setw(2) << elem << ' ';
}
std::cout << '\n';
}
std::cout << '\n';
};
Let's print what we have so far
std::cout << "Before:\na =\n";
array_printer(a);
std::cout << "b =\n";
array_printer(b);
Output:
Before:
a =
0 1 2
3 4 5
6 7 8
9 10 11
b =
20 21 22
23 24 25
Time to create a 2d view of the array
using range_type = boost::multi_array_types::index_range;
using view_type = array_type::array_view<2>::type;
// Create a 2d view of a
// - the rows of the view consist of rows [0, 3) with a stride of 2
// - the columns of the view consist of all columns of a
view_type a_view = a[boost::indices[range_type(0,3,2)][range_type()]];
Now assign b to the view we created, and print the result
a_view = b;
std::cout << "After:\na =\n";
array_printer(a);
Output:
After:
a =
20 21 22
3 4 5
23 24 25
9 10 11
Live demo
I'm writing a basic chess program to calculate how many sets you can make with the given chess figures. The data file:
4
22 3 5 6 2 0
1 1 1 1 1 1
8 4 4 4 1 2
5 3 3 3 0 2
The code:
#include <iostream>
#include <fstream>
#include <vector>
int main
(int argc, char *argv[])
{
std::fstream data_file;
size_t i, k;
std::vector<long> chess;
long t, n;
data_file.open("U1.txt", std::ios::in);
data_file >> n;
for (i = 0; i < n; i++)
chess.push_back(0);
for (i = 0; i < n; i++) {
for (k = 0; k < 6; k++) {
data_file >> t;
std::cout << t << " ";
chess[k] += t;
}
std::cout << std::endl;
}
data_file.close();
for (int i = 0; i < 6; i++)
std::cout << chess[i] << " ";
std::cout << std::endl;
data_file.open("U1rez.txt", std::ios::out);
data_file << n;
std::cout << n << std::endl;
data_file.close();
return EXIT_SUCCESS;
}
The output:
22 3 5 6 2 0
1 1 1 1 1 1
8 4 4 4 1 2
5 3 3 3 0 2
36 11 13 14 3 4
4
Why am I getting 3 and 4 at the end result just after 36, 11, 13 and 14 at line 5? When I print the test values I seem to get the right numbers but something goes terribly wrong in the addition of them in the vector container.
for (i = 0; i < n; i++)
chess.push_back(0);
.
.
.
for (i = 0; i < n; i++) {
for (k = 0; k < 6; k++) {
data_file >> t;
std::cout << t << " ";
chess[k] += t;
}
std::cout << std::endl;
}
here, you initialized n(=4) places in the vector, but here you are accessing the index 4 and 5 of the vector chess which is causing the addition problem.
On an unrelated note, you will have a much easier time with C++ if you let go of some of the rules imposed by C.
The C++ API uses scope-bounded resource management; i.e. there's no need to explicitly close the file handle here, since the class does this for you when its destructor is called at the end of the declared scope.
Prefer std::cout << "\n" to std::cout << std::endl, unless you actually intend to insert a newline and flush the buffer. Many C++ programmers still use printf, and I personally think that it's a lot more elegant than C++'s ugly standard solution to IO -- feel free to use printf.
Do you find your code easier to manage and read when you declare your variable where they are used (e.g. for (size_type i = 0; ... ; ...)), rather than at the beginning of your method? This also allows the compiler to potentially make better choices about register usage, since it has more information about the scopes of your temporary variables.
Here are a few features of C++11 that can also save you some time:
Automatic type inference: when the compiler can infer the type of a variable, it's not necessary for you to explicitly specify it; you can use auto instead (e.g. auto x = parse_data();).
Range-for: if you are operating on a container that provides global definitions begin() and end() (such as any standard container), then instead of this:
typedef typename container_type::const_iterator iter;
for (iter i = begin(container), iter l = end(container); i != l; ++i) { ... }
You can do this:
for (const auto& x : container) { ... }
I just wanted to give you a few quick pointers that can save you some time.