Get the first column of a matrix represented by a vector of vectors
As I mentioned in the comments, it's not practical to represent matrices using vector-of-vector for a few reasons:
- It is fiddly to set up;
- It is difficult to change;
- Cache locality is bad.
Here is a very simple class I have created that will hold a 2D matrix in a single vector. This is pretty much how software like MATLAB does it... albeit a huge simplification.
template <class T>
class SimpleMatrix
{
public:
SimpleMatrix( int rows, int cols, const T& initVal = T() );
// Size and structure
int NumRows() const { return m_rows; }
int NumColumns() const { return m_cols; }
int NumElements() const { return m_data.size(); }
// Direct vector access and indexing
operator const vector<T>& () const { return m_data; }
int Index( int row, int col ) const { return row * m_cols + col; }
// Get a single value
T & Value( int row, int col ) { return m_data[Index(row,col)]; }
const T & Value( int row, int col ) const { return m_data[Index(row,col)]; }
T & operator[]( size_t idx ) { return m_data[idx]; }
const T & operator[]( size_t idx ) const { return m_data[idx]; }
// Simple row or column slices
vector<T> Row( int row, int colBegin = 0, int colEnd = -1 ) const;
vector<T> Column( int row, int colBegin = 0, int colEnd = -1 ) const;
private:
vector<T> StridedSlice( int start, int length, int stride ) const;
int m_rows;
int m_cols;
vector<T> m_data;
};
This class is basically sugar-coating around a single function -- StridedSlice
. The implementation of that is:
template <class T>
vector<T> SimpleMatrix<T>::StridedSlice( int start, int length, int stride ) const
{
vector<T> result;
result.reserve( length );
const T *pos = &m_data[start];
for( int i = 0; i < length; i++ ) {
result.push_back(*pos);
pos += stride;
}
return result;
}
And the rest is pretty straight-forward:
template <class T>
SimpleMatrix<T>::SimpleMatrix( int rows, int cols, const T& initVal )
: m_data( rows * cols, initVal )
, m_rows( rows )
, m_cols( cols )
{
}
template <class T>
vector<T> SimpleMatrix<T>::Row( int row, int colBegin, int colEnd ) const
{
if( colEnd < 0 ) colEnd = m_cols-1;
if( colBegin <= colEnd )
return StridedSlice( Index(row,colBegin), colEnd-colBegin+1, 1 );
else
return StridedSlice( Index(row,colBegin), colBegin-colEnd+1, -1 );
}
template <class T>
vector<T> SimpleMatrix<T>::Column( int col, int rowBegin, int rowEnd ) const
{
if( rowEnd < 0 ) rowEnd = m_rows-1;
if( rowBegin <= rowEnd )
return StridedSlice( Index(rowBegin,col), rowEnd-rowBegin+1, m_cols );
else
return StridedSlice( Index(rowBegin,col), rowBegin-rowEnd+1, -m_cols );
}
Note that the Row
and Column
functions are set up in such a way that you can easily request an entire row or column, but are a little more powerful because you can slice a range by passing one or two more parameters. And yes, you can return the row/column in reverse by making your start value larger than your end value.
There is no bounds-checking built into these functions, but you can easily add that.
You could also add something to return an area slice as another SimpleMatrix<T>
.
Have fun.
C++ using vector vector to represent matrix with continuous data buffer
The code doesn't do what you think it does.
The line
res.emplace_back(buffer + i * M, buffer + (i + 1) * M);
creates a new std::vector<float>
to add to res
. This std::vector<float>
will allocate its own memory to hold a copy of the data in the range [buffer + i * M, buffer + (i + 1) * M)
, which also causes undefined behavior because you never initialized the data in this range.
So, in the end you are not using the memory you obtained with malloc
at all for the vectors. That memory is simply leaked at the end of the function.
You can't specify what memory a vector<vector<float>>
should use at all. There is simply no way to modify its allocation strategy. What you can do is etiher use a vector<float>
instead to hold the matrix entries linearly indexed in a single vector or you can use a vector<vector<float, Alloc1>, Alloc2>
where Alloc1
and Alloc2
are some custom allocator types for which you somehow specify the allocation behavior so that the storage layout is closer to what you want (although I doubt that the latter can be done nicely here or is worth the effort over just using the linear representation).
Select a column from a list of matrices using a list of vectors
Because your list contains matrices that you don't want to keep at all we can first create an index vector that selects only list elements of listOfColumns
for which there is at least one TRUE
(idx <- sapply(listOfColumns, any))
# [1] FALSE FALSE TRUE
Next we use Map
to subset the remaining matrices
Map(function(x, cols) x[, cols], x = matrices[idx], cols = listOfColumns[idx])
#[[1]]
#[1] 7 8 9
Thanks to @thelatemail for the helpful comment.
Vector of Vectors to create matrix
As it is, both dimensions of your vector are 0.
Instead, initialize the vector as this:
vector<vector<int> > matrix(RR);
for ( int i = 0 ; i < RR ; i++ )
matrix[i].resize(CC);
This will give you a matrix of dimensions RR * CC
with all elements set to 0
.
Column size and row size of a 2D vector in C++
You have a vector of integer vectorsmyVector[0].size()
returns you the amount of elements in the first int vector in the 2d vector.
The structure of such vector looks like this:
myVector[
Vector[0, 4, 2, 5],
Vector[1, 4, 2]
];
When you call for myVector[1].size() it would return 3 and [0] would return 4.
For the amount of rows (int vectors) in the 2d vector, you can just use myVector.size()
You can run this to see it in actions
#include <iostream>
#include <vector>
int main(){
std::vector<std::vector<int>>MyVector;
std::vector<int>temp;
temp.push_back(1);
temp.push_back(2);
temp.push_back(3);
MyVector.push_back(temp);
std::cout << "Rows in the 2d vector: " << MyVector.size() <<
std::endl << "Collumns in the 1st row: " << MyVector[0].size() <<
std::endl;
system("pause");
return 0;
}
This is the output:
Rows in the 2d vector: 1
Collumns in the 1st row: 3
How to get the following matrix out of two vectors in pythonic way?
You can matrix-multiply a-transpose with b:
import numpy as np
a = np.matrix([1, 2, 3])
b = np.matrix([10, 20, 30])
a.T * b
With only arrays:
import numpy as np
a = np.array([1, 2, 3])
b = np.array([10, 20, 30])
np.multiply.outer(a, b) # thanks to @Divakar in the comments
computing column sums of matrix vector vector double with iterators?
Here's something I came up with, using for_each
and transform
:
std::vector<std::vector<double>> data { {1,2,3}, {1,2,3}, {1,2,3} };
std::vector<double> colsums( data[0].size() ); // initialize the size
// to number of columns
std::for_each(data.begin(), data.end(),
[&](const std::vector<double>& row)
{
// Use transform overload that takes two input ranges.
// Note that colsums is the second input range as well as the output range.
// We take each element of the row and add it to the corresponding
// element of colsums vector:
std::transform(row.begin(), row.end(), colsums.begin(), colsums.begin(),
[](double d1, double d2) { return d1 + d2; });
});
std::cout << "Column means: ";
std::transform(
colsums.begin(), colsums.end(),
std::ostream_iterator<double>(std::cout, " "),
[&data](double d) { return d / data.size(); });
LWS Demo
Related Topics
C++: Construction and Initialization Order Guarantees
What Are the Distinctions Between the Various Symbols (*,&, etc) Combined with Parameters
How to Identify Platform/Compiler from Preprocessor MACros
What Do Each Memory_Order Mean
What Does Flushing the Buffer Mean
C++ Qt Signal and Slot Not Firing
Intrinsics for Cpuid Like Informations
What Are the Issues with a Vector-Of-Vectors
Why Is This Cin Reading Jammed
Why Is This Code Trying to Call the Copy Constructor
How Does the Range-Based for Work for Plain Arrays
What Is the Simplest Way to Convert Array to Vector
Std::List<>::Sort()' - Why the Sudden Switch to Top-Down Strategy