I have a matrix with some zero rows. I would like to remove the zero rows. The matrix is Nx3. What I've done is simple. I create std::vector in which every three elements represent a row then I convert it to Eigen::MatrixXd. Is there an elegant way to remove the zero rows?
#include <iostream>
#include <vector>
#include <Eigen/Dense>
Eigen::MatrixXd VecToMat(const std::vector<double> vec)
{
int rows(vec.size()/3) , cols(3);
Eigen::MatrixXd temp( rows , cols);
int count(0);
for ( int i(0); i < rows; ++i)
{
temp(i,0) = vec[count];
temp(i,1) = vec[count+1];
temp(i,2) = vec[count+2];
count += 3;
}
return temp;
}
Eigen::MatrixXd getNewMat(Eigen::MatrixXd& Z)
{
std::vector<double> vec;
for ( int i(0); i < Z.rows(); ++i)
{
if ( (Z(i,0) && Z(i,1) && Z(i,2)) != 0 ){
vec.push_back(Z(i,0));
vec.push_back(Z(i,1));
vec.push_back(Z(i,2));
}
}
Eigen::MatrixXd temp = VecToMat(vec);
return temp;
}
int main()
{
Eigen::MatrixXd Z(5,3);
Z.setOnes();
Z(0,0) = 0;
Z(0,1) = 0;
Z(0,2) = 0;
Z(1,0) = 0;
Z(1,1) = 0;
Z(1,2) = 0;
Z(2,0) = 0;
Z(2,1) = 0;
Z(2,2) = 0;
std::cout << Z << std::endl << std::endl;
std::cout << getNewMat(Z) << std::endl;
std::cin.get();
return 0;
}
Here is a full implementation I find quite elegant. Note that this one does not preserve order of non-zero rules, which maybe isn't what you want, but is more efficient both in complexity and lines of code:
void removeZeroRows(Eigen::MatrixXd& mat)
{
Matrix<bool, Dynamic, 1> empty = (mat.array() == 0).rowwise().all();
size_t last = mat.rows() - 1;
for (size_t i = 0; i < last + 1;)
{
if (empty(i))
{
mat.row(i).swap(mat.row(last));
empty.segment<1>(i).swap(empty.segment<1>(last));
--last;
}
else
++i;
}
mat.conservativeResize(last + 1, mat.cols());
}
Basically you can follow a pseudocode like this:
get N = rows, M = columns
iterate by each N
if N[0] = 0 iterate on rows exiting on first non-zero
if N[0] = 0 && .. && N[M] = 0
remove row
For removing single row:
void removeRow(Eigen::MatrixXd& matrix, unsigned int rowToRemove) {
unsigned int numRows = matrix.rows() - 1;
unsigned int numCols = matrix.cols();
unsigned int rowPos = numRows - rowToRemove;
if( rowToRemove < numRows ) {
matrix.block(rowToRemove, 0, rowPos, numCols) = matrix.block(rowToRemove + 1, 0, rowPos,numCols);
}
matrix.conservativeResize(numRows, numCols);
}
Save each nonempty row into a vector, then make a new matrix
vector<block> buffer; //not sure of the type name for the rows
VectorXd zero(3); //or appropriate comparable type
for(int i = 0; i < Z.rows(); i++){ //note: possibly a function call each time
if(Z.row(i) != zero)
//if((Z.row(i) != 0).any()) //broadcasting comparison?
buffer.push_back(Z.row(i));
}
MatrixXd return_value(buffer.size(), 3);
for(int i = buffer.size(); i --> 0;)
return_value.row(i) = buffer[i];
return return_value;
Warning: Resizing the old one instead of making a new one may erase the contents before you can save them.
I can't read the docs from here, so you will have to see for yourself what kind of comparison operations you can do on block objects. As a last result, try row.any() (faster?) or row.squaredNorm() == 0.
Related
I am trying to remove odd numbers from an array, but I'm not allowed to create a new array to store the new values.
So, if I have arr[1,2,3,4,5,6,7,8,9]
then I need it to be arr[2,4,6,8] so that arr[0] will be 2 and not 1.
I can't seem to be able to drop the even numbers without creating a new array to store the values and then feed it back into the original array with the new values.
I have tried to make arr[i] = 0 if its an odd number but then I wasn't able to drop the 0 and replace it with the next even number.
So far, I have this:
void removeOdd(int arr[], int& arrSize){
int i, j = 0;
int temp;
int newArrSize;
for(i = 0, newArrSize = arrSize; i < arrSize; i++){
if(arr[i] % 2 != 0){
arr[i] = 0;
}
}
arrSize = newArrSize;
}
// Moves all even numbers into the beginning of the array in their original order
int removeOdd(int arr[], int arrSize) {
int curr = 0; // keep track of current position to insert next even number into
for (int i = 0; i < arrSize; ++i) {
if (arr[i] % 2 == 0) {
arr[curr++] = arr[i];
}
}
return curr;
}
int main() {
int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
int newSize = removeOdd(arr, 10);
for (int i = 0; i < newSize; ++i) {
std::cout << arr[i] << " ";
}
}
0 2 4 6 8
You might want to use std::vector:
void removeOdd(std::vector<int>& arr) {
int curr = 0;
for (int i = 0; i < (int)arr.size(); ++i) {
if (arr[i] % 2 == 0) {
arr[curr++] = arr[i];
}
}
arr.resize(curr);
}
int main() {
std::vector<int> arr = { 0,1,2,3,4,5,6,7,8,9 };
removeOdd(arr);
for (int number : arr) {
std::cout << number << " ";
}
}
Normally (unless this is homework of some sort), you should use the algorithms in the <algorithm> header.
Using std::remove_if with std::vector's erase member function, you will accomplish exactly what you want with less code:
std::vector<int> vec{ 1,2,3,4,5,6,7,8,10 };
vec.erase(std::remove_if(std::begin(vec), std::end(vec), [](auto const& i) {
return i % 2 != 0;
}), std::end(vec));
Demo
I wanna list all arrangement, the following is my sample code:
const unsigned char item1[] = {'b'};
const unsigned char item2[] = { 'A', 'C' ,'D'};
const unsigned char item3[] = {'1','2'};
int _tmain(int argc, _TCHAR* argv[])
{
for (int i = 0; i < sizeof(item1) / sizeof(unsigned char); i++){
for (int j = 0; j < sizeof(item2) / sizeof(unsigned char); j++){
for (int k = 0; k < sizeof(item3) / sizeof(unsigned char); k++){
printf("%c%c%c\n",item1[i],item2[j],item3[k]);
}
}
}
return 0;
}
This will print all arrangement, but I am worried about if the array item is from item1 to item99, the code is difficult to maintain. Is there a better solution to print all arrangement? Thanks!
You might store your "iterator" in vector, then you might do something like:
bool increase(const std::vector<std::string>& v, std::vector<std::size_t>& it)
{
for (std::size_t i = 0, size = it.size(); i != size; ++i) {
const std::size_t index = size - 1 - i;
++it[index];
if (it[index] == v[index].size()) {
it[index] = 0;
} else {
return true;
}
}
return false;
}
void do_job(const std::vector<std::string>& v, std::vector<std::size_t>& it)
{
for (std::size_t i = 0, size = v.size(); i != size; ++i) {
std::cout << v[i][it[i]];
}
std::cout << std::endl;
}
void iterate(const std::vector<std::string>& v)
{
std::vector<std::size_t> it(v.size(), 0);
do {
do_job(v, it);
} while (increase(v, it));
}
Demo
A nice way of accomplishing this is to look at the problem as an integer base conversion problem. So, the total number of combinations is the product of all the array sizes. The output string n would be enough to determine the array indeces that should be printed in the string.
Since you have tagged it as a C++ question I would use 2-D vectors, as this makes life much simpler:
int _tmain(int argc, _TCHAR* argv[])
{
// Initialize the vector
vector<vector<char>> v( 3 );
v[0].push_back( 'b' );
v[1].push_back( 'A' );
v[1].push_back( 'C' );
v[1].push_back( 'D' );
v[2].push_back( '1' );
v[2].push_back( '2' );
// This is a convenience vector of sizes of each 1-D vector
vector<size_t> sizes( v.size() );
// Get the total number of combinations and individual vector
// sizes
size_t total = 1;
for( size_t i = 0; i < v.size(); ++i )
{
sizes[i] = v[i].size();
total *= sizes[i];
}
size_t done = 0;
// Loop till all the combinations are printed
while( done != total )
{
// Remainder, which is the index of the element
// in the 1-D vector that is to be printed
size_t r = 0;
// Quotient to be used for the next remainder
size_t q = done;
// Combination to be printed
string s = "";
// Loop over the 1-D vectors, picking the correct
// character from each
for( size_t i = 0; i < v.size(); ++i )
{
r = q % sizes[v.size() - 1 - i];
q = static_cast<size_t>( floor( q/sizes[v.size() - 1 - i] ) );
s = v[v.size() - 1 - i][r] + s;
}
cout<<s<<"\n";
done++;
}
return 0;
}
I'm not so advanced in c++ yet, but I'm trying to perform clustering analysis,
the data, vector< vector< double>> X, is M by T, with M features and T data points, I'm trying to group features into sets in which the distance correlation between each of the features within the set is above a certain threshold. The distCorrelation function is already defined by the way.
set<vector<double>> clusterIndices(vector<vector<double>> &X, double threshold){
vector<double> feature[X.size()];
for(int i = 0; i < X.size(); i++){
for(int j = 0; j < X[0].size(); j++){
feature[i].push_back(X[i][j]);
}
}
vector<vector<double>> distCorrMatrix(X.size(), vector<double> (X.size()));
for (int i = 0; i < X.size(); i++){
for (int j = 0; j < X.size(); j++){
distCorrMatrix[i][j] = (distCorrelation(feature[i],feature[j]) >= threshold ? 1.0 : 0.0);
}
}
set<vector<double>> rows;
for (int i = 0; i < X.size(); i++){
vector<int> temp;
for (int j = 0; j < X.size(); j++){
if (distCorrMatrix[i][j] == 1){
temp.push_back(j);
}
}
rows.insert(temp);
}
return rows;
}
So the above code will produce sets of features with mutually high correlation but will only give indices of those features.
That is, the returned rows could be (1,2,5) , (3,7,8,10) ... etc which translates to (feature[1],feature[2],feature[5]) , (feature[3],feature[7],feature[8],feature[10]) ...etc in which feature[i] represents i'th row of the data matrix.
The problem is I don't know how I can create a function that turns those each sets into matrices and return them.
No, your code won't compile. You should do it like this:
// k is the number of clusters
vector<vector<vector<double> > > myFunction(vector<vector<double> > &X, int k) {
vector<vector<vector<double> > > result(k);
for (int i = 0; i < X.size(); i++){
//do something then know X[i] belongs to cluster j
result[j].push_back(X[i]);
}
return result;
}
From what I can tell, you want this
std::vector<int> myclusteringfunction(std::vector<std::vector<double> > const &dataitems)
{
/* assign a cluster id to each data item */
std::vector<int> answer;
for(i=0;i<dataitems.size();i++)
answer.push_back( /* get the cluster id for each data item */);
/* return the ids as a list of the same length as your input list
eg {0, 1, 2, 1, 1, 1, 2, 2, 0, 0, 3, 1, 1, 1, 1} for four clusters */
return answer;
}
Your input seems unclear, but we can go this way: (check function getVectorOfMatrices)
#include <vector>
#include <iostream>
/**
* A classic 2D matrix implementation.
* Pay attention to the constructors and the operator=.
*/
class Matrix2D {
public:
// Standard constructor, allocates memory and initializes.
Matrix2D(const unsigned int rows, const unsigned int columns)
: m_rows(rows), m_columns(columns) {
m_data = new float*[rows];
for(unsigned row = 0; row < rows; ++row) {
m_data[row] = new float[columns];
for (unsigned column = 0; column < columns; ++column) {
m_data[row][column] = 0;
}
}
}
// Copy-constructor - also allocates and initializes.
Matrix2D(const Matrix2D& rhs) {
m_rows = rhs.m_rows;
m_columns = rhs.m_columns;
m_data = new float*[rhs.m_rows];
for (unsigned row = 0; row < rhs.m_rows; ++row) {
m_data[row] = new float[rhs.m_columns];
for (unsigned column = 0; column < rhs.m_columns; ++column) {
m_data[row][column] = rhs.at(row, column);
}
}
}
// Affectation operator - also allocates memory and initializes.
Matrix2D& operator=(const Matrix2D& rhs) {
m_rows = rhs.m_rows;
m_columns = rhs.m_columns;
m_data = new float*[rhs.m_rows];
for (unsigned row = 0; row < rhs.m_rows; ++row) {
m_data[row] = new float[rhs.m_columns];
for (unsigned column = 0; column < rhs.m_columns; ++column) {
m_data[row][column] = rhs.at(row, column);
}
}
}
// Used to set values in the 2D matrix
// NOTA : This function should check row vs m_rows and column vs m_columns
float& at(const unsigned int row, const unsigned int column) {
return m_data[row][column];
}
// Used to get values of the 2D matrix
// NOTA : This function should check row vs m_rows and column vs m_columns
const float at(const unsigned int row, const unsigned int column) const {
return m_data[row][column];
}
// Debug tool - prints the matrix
void print() const {
for (unsigned row = 0; row < m_rows; ++row) {
for (unsigned column = 0; column < m_columns; ++column) {
std::cout << " " << m_data[row][column] << " ";
}
std::cout << std::endl;
}
}
// Destructor - deallocates the memory
~Matrix2D() {
for (unsigned int row=0; row<m_rows; ++row) {
delete[] m_data[row];
}
delete[] m_data;
}
private:
unsigned int m_rows; // y-size
unsigned int m_columns; // x-size
float** m_data; // the data
};
/*
* Function that creates and returns a vector of 2D matrices
* Matrices are of different sizes
*/
std::vector<Matrix2D> getVectorOfMatrices() {
Matrix2D m1(1,1);
Matrix2D m2(2,2);
Matrix2D m3(3,3);
Matrix2D m4(4,2);
m1.at(0, 0) = 4;
m2.at(0, 1) = 2;
m4.at(1, 1) = 8;
std::vector<Matrix2D> result;
result.push_back(m1);
result.push_back(m2);
result.push_back(m3);
result.push_back(m4);
return result;
}
/*
* Main - simply call our function.
*/
int main () {
std::vector<Matrix2D> vec = getVectorOfMatrices();
for(std::vector<Matrix2D>::iterator it = vec.begin(); it != vec.end(); ++it) {
it->print();
}
return 0;
}
I am trying to solve this puzzle: http://www.puzzleup.com/2015/puzzle/?13
to do that, I want to calculate all the possible codes and pass them in a vector
You will produce a set of 7-letter codes using the the letters A, B,
C, D, E, F and G
So I tried to create vector of char arrays. The code is shared below:
#include <iostream>
#include <string>
#include <vector>
#include <array>
#include <cmath>
char letters[] = {'a','b','c','d','e','f','g'};
char * tempArr;
char * pastArr;
std::vector<char * > deneme;
char s1[] = {'a', 'b'};
char s2[] = {'c', 'd'};
void calculateAllPossibilities(int depth, int lastDepth)
{
//depth 1 den baĆ¾layacak
for( int i = 0; i < sizeof(letters); i++ )
{
//
if ( depth != 1 && depth != lastDepth )
{
//
tempArr = new char[depth];
for( int j = 0; j < depth-1; j++ )
{
//
*tempArr = pastArr[j];
tempArr++;
}
*tempArr = letters[i];
for( int x = 0; x < depth; x++ )
{
//
std::cout << tempArr[x] << ",";
}
std::cout << std::endl;
delete pastArr;
pastArr = new char[depth];
for( int k = 0; k < depth; k++ )
{
//
*pastArr = tempArr[k];
pastArr++;
}
delete tempArr;
calculateAllPossibilities(depth + 1, lastDepth );
}
else if( depth == lastDepth )
{
//
tempArr = new char[depth];
for( int k = 0; k < depth - 1; k++ )
{
//
*tempArr = pastArr[k];
tempArr++;
}
*tempArr = letters[i];
for( int x = 0; x < depth; x++ )
{
//
std::cout << tempArr[x] << ",";
}
std::cout << std::endl;
deneme.push_back(tempArr);
delete tempArr;
}
else if( depth == 1 )
{
//
pastArr = new char[depth];
*pastArr = letters[i];
std::cout << pastArr[0] << std::endl;
delete tempArr;
calculateAllPossibilities(depth + 1, lastDepth );
}
}
}
int main()
{
calculateAllPossibilities(1,7);
std::cout << deneme[0][2];
return 0;
}
The problem is, when I try to cout the values of deneme vector without using cout in functions, it gives me different thing in each compilation. Like those: ":", "_", "X", "2" :)
However, then I added couts to function and tried to see whats going on and BAM! My computer goes crazy after couts!
What am I doing wrong here? First time I encountered something like this.
This is not going to work, at all
deneme.push_back(tempArr);
delete tempArr;
You save a pointer to an array in the vector, and then you delete the array. Now the saved pointer points nowhere.
It would work much better with a vector of std::string.
Also, when you allocate an array with tempArr = new char[depth];, the [] should also be used when deleting, like delete[] tempArray. That lets the compiler know that you are deleting an array, and not just one char. Not that it matters too much here.
I'm trying to devise an algorithm in the form of a function that accepts two parameters, an array and the size of the array. I want it to return the mode of the array and if there are multiple modes, return their average. My strategy was to take the array and first sort it. Then count all the occurrences of a number. while that number is occurring, add one to counter and store that count in an array m. So m is holding all the counts and another array q is holding the last value we were comparing.
For example: is my list is {1, 1, 1, 1, 2, 2, 2}
then i would have m[0] = 4 q[0] = 1
and then m[1] = 3 and q[1] = 2.
so the mode is q[0] = 1;
unfortunately i have had no success thus far. hoping someone could help.
float mode(int x[],int n)
{
//Copy array and sort it
int y[n], temp, k = 0, counter = 0, m[n], q[n];
for(int i = 0; i < n; i++)
y[i] = x[i];
for(int pass = 0; pass < n - 1; pass++)
for(int pos = 0; pos < n; pos++)
if(y[pass] > y[pos]) {
temp = y[pass];
y[pass] = y[pos];
y[pos] = temp;
}
for(int i = 0; i < n;){
for(int j = 0; j < n; j++){
while(y[i] == y[j]) {
counter++;
i++;
}
}
m[k] = counter;
q[k] = y[i];
i--; //i should be 1 less since it is referring to an array subscript
k++;
counter = 0;
}
}
Even though you have some good answers already, I decided to post another. I'm not sure it really adds a lot that's new, but I'm not at all sure it doesn't either. If nothing else, I'm pretty sure it uses more standard headers than any of the other answers. :-)
#include <vector>
#include <algorithm>
#include <unordered_map>
#include <map>
#include <iostream>
#include <utility>
#include <functional>
#include <numeric>
int main() {
std::vector<int> inputs{ 1, 1, 1, 1, 2, 2, 2 };
std::unordered_map<int, size_t> counts;
for (int i : inputs)
++counts[i];
std::multimap<size_t, int, std::greater<size_t> > inv;
for (auto p : counts)
inv.insert(std::make_pair(p.second, p.first));
auto e = inv.upper_bound(inv.begin()->first);
double sum = std::accumulate(inv.begin(),
e,
0.0,
[](double a, std::pair<size_t, int> const &b) {return a + b.second; });
std::cout << sum / std::distance(inv.begin(), e);
}
Compared to #Dietmar's answer, this should be faster if you have a lot of repetition in the numbers, but his will probably be faster if the numbers are mostly unique.
Based on the comment, it seems you need to find the values which occur most often and if there are multiple values occurring the same amount of times, you need to produce the average of these. It seems, this can easily be done by std::sort() following by a traversal finding where values change and keeping a few running counts:
template <int Size>
double mode(int const (&x)[Size]) {
std::vector<int> tmp(x, x + Size);
std::sort(tmp.begin(), tmp.end());
int size(0); // size of the largest set so far
int count(0); // number of largest sets
double sum(0); // sum of largest sets
for (auto it(tmp.begin()); it != tmp.end(); ) {
auto end(std::upper_bound(it, tmp.end(), *it));
if (size == std::distance(it, end)) {
sum += *it;
++count;
}
else if (size < std::distance(it, end)) {
size = std::distance(it, end);
sum = *it;
count = 1;
}
it = end;
}
return sum / count;
}
If you simply wish to count the number of occurences then I suggest you use a std::map or std::unordered_map.
If you're mapping a counter to each distinct value then it's an easy task to count occurences using std::map as each key can only be inserted once. To list the distinct numbers in your list simply iterate over the map.
Here's an example of how you could do it:
#include <cstddef>
#include <map>
#include <algorithm>
#include <iostream>
std::map<int, int> getOccurences(const int arr[], const std::size_t len) {
std::map<int, int> m;
for (std::size_t i = 0; i != len; ++i) {
m[arr[i]]++;
}
return m;
}
int main() {
int list[7]{1, 1, 1, 1, 2, 2, 2};
auto occurences = getOccurences(list, 7);
for (auto e : occurences) {
std::cout << "Number " << e.first << " occurs ";
std::cout << e.second << " times" << std::endl;
}
auto average = std::accumulate(std::begin(list), std::end(list), 0.0) / 7;
std::cout << "Average is " << average << std::endl;
}
Output:
Number 1 occurs 4 times
Number 2 occurs 3 times
Average is 1.42857
Here's a working version of your code. m stores the values in the array and q stores their counts. At the end it runs through all the values to get the maximal count, the sum of the modes, and the number of distinct modes.
float mode(int x[],int n)
{
//Copy array and sort it
int y[n], temp, j = 0, k = 0, m[n], q[n];
for(int i = 0; i < n; i++)
y[i] = x[i];
for(int pass = 0; pass < n - 1; pass++)
for(int pos = 0; pos < n; pos++)
if(y[pass] > y[pos]) {
temp = y[pass];
y[pass] = y[pos];
y[pos] = temp;
}
for(int i = 0; i < n;){
j = i;
while (y[j] == y[i]) {
j++;
}
m[k] = y[i];
q[k] = j - i;
k++;
i = j;
}
int max = 0;
int modes_count = 0;
int modes_sum = 0;
for (int i=0; i < k; i++) {
if (q[i] > max) {
max = q[i];
modes_count = 1;
modes_sum = m[i];
} else if (q[i] == max) {
modes_count += 1;
modes_sum += m[i];
}
}
return modes_sum / modes_count;
}