As said I want to replace all < 0 elements in a eigen3 matrix in C++ with zero in most efficient manner.
I check that there are negative elements using:
(result.array() < 0).any()
A nicer and more efficient way than your proposed method would be to use the select method.
result = (result.array() < 0).select(0, result);
I found a way:
Create a matrix of zeros of same shape,
zero_matrix.setZero();
And find coeff wise maximum between zero matrix and your matrix.
result = result.array().max(zero_matrix.array());
Related
Is there an efficient approach to only retain rows of an Armadillo sparse matrix that sum up to at least some level of total count across columns of the matrix? For instance, I would want to retain the ith row, if the sum of its values is >=C, where C is some chosen value. Armadillo's documentation says that only contiguous submatrix views are allowed with sparse matrices. So I am guessing this is not easily obtainable by sub-setting. Is there an alternative to plainly looping through elements and creating a new sparse matrix with new locations, values and colPtr settings that match the desired condition? Thanks!
It may well be that the fastest executing solution is the one you propose. If you want to take advantage of high-level armadillo functionality (i.e. faster to code but perhaps slower to run) you can build a std::vector of "bad" rows ids and then use shed_row(id). Take care with the indexing when shedding rows. This is accomplished here by always shedding from the bottom of the matrix.
auto mat = arma::sp_mat(rowind, colptr, values, n_rows, n_cols)
auto threshold_value = 0.01 * arma::accu(sp_mat); // Sum of all elements
std::vector<arma::uword> bad_ids; // The rows that we want to shed
auto row_sums = arma::sum(mat); // Row sums
// Iterate over rows in reverse order.
for (const arma::uword row_id = mat.nrows; i-- > 0; ) {
if (row_sum(row_id) < threshold_value) {
bad_ids.push_back(row_id);
}
}
// Shed the bad rows from the bottom of the matrix and up.
for (const auto &bad_id : bad_ids) {
matrix.shed_row(bad_id);
}
I do not use any matrix library, but instead plain std::vector for my matrix data.
To fill it with 2D data I use this code:
data[iy + dataPointsY * ix] = value;
I would like to know is this is correct or if it must be the other way (ix first).
To my understanding fftw needs 'Row-major Format'. Since I use it the formula should be according to row-major format.
Assuming you want row major format for fftw, what you want is:
data[ix + iy*dataPointsY]
The point of row-major is, when the combined index increased by 1, the corresponding row index would be same (assuming not overflowing to the next row).
double m[4][4];
mp = (double*)m;
mp[1+2*3] == m[2][1]; //true
mp[2+2*3] == m[2][2]; //true
mp[2+2*3] == m[3][1]; //false
In general, there's no "right" way to store a matrix. Row major format is also called "C-style" matrix, while column major is called "fortran-style" matrix. The naming is due to different multidimensional array indexing scheme between the two language.
I want to check if the elements of my matrix are smaller than zero then I want to assign zero to them, in matlab it was done using this:
ind = find(floatFrame < 0);
floatFrame(ind) = 0;
Is there any equivalent for Eigen matrices?
You can use the select function, which is similar to the ternary ?: operator in C. For your example:
floatFrame = (floatFrame < 0).select(0, floatFrame)
I am working on a binary linear program problem.
I am not really familiar with any computer language(just learned Java and C++ for a few months), but I may have to use computer anyway since the problem is quite complicated.
The first step is to declare variables m_ij for every entry in (at least 8 X 8) a matrix M.
Then I assign corresponding values of each element of a matrix to each of these variables.
The next is to generate other sets of variables, x_ij1, x_ij2, x_ij3, x_ij4, and x_ij5, whenever the value of m_ij is not 0.
The value of x_ijk variable is either 0 or 1, and I do not have to assign values for x_ijk variables.
Probably the simplest way to do it is to declare and assign a value to each variable, e.g.
int* m_11 = 5, int* m_12 = 2, int* m_13 = 0, ... int* m_1n = 1
int* m_21 = 3, int* m_12 = 1, int* m_13 = 2, ... int* m_2n = 3
and then pick variables, the value of which is not 0, and declare x_ij1 ~ x_ij5 accordingly.
But this might be too much work, especially since I am going to consider many different matrices for this problem.
Is there any way to do this automatically?
I know a little bit of Java and C++, and I am considering using lp_solve package in C++(to solve binary integer linear program problem), but I am willing to use any other language or program if I could do this easily.
I am sure there must be some way to do this(probably using loops, I guess?), and this is a very simple task, but I just don't know about it because I do not have much programming language.
One of my cohort wrote a program for generating a random matrix satisfying some condition we need, so if I could use that matrix as my input, it might be ideal, but just any way to do this would be okay as of now.
Say, if there is a way to do it with MS excel, like putting matrix entries to the cells in an excel file, and import it to C++ and automatically generate variables and assign values to them, then this would simplify the task by a great deal!
Matlab indeed seems very suitable for the task. Though the example offered by #Dr_Sam will indeed create the matrices on the fly, I would recommend you to initialize them before you assign the values. This way your code still ends up with the right variable if something with the same name already existed in the workspace and also your variable will always have the expected size.
Assuming you want to define a square 8x8 matrix:
m = zeros(8)
Now in general, if you want to initialize a three dimensional matrixh of size imax,jmax,kmax:
imax = 8;
jmax = 8;
kmax = 5;
x = zeros(imax,jmax,kmax);
Now assigning to or reading from these matrices is very easy, note that length and with of m have been chosen the same as the first dimensions of x:
m(3,4) = 4; %Assign a value
myvalue = m(3,4) %read the value
m(:,1) = 1:8 *Assign the values 1 through 8 to the first column
x(2,4,5) = 12; %Assign a single value to the three dimensional matrix
x(:,:,2) = m+1; Assign the entire matrix plus one to one of the planes in x.
In C++ you could use a std::vector of vectors, like
std::vector<std::vector<int>> matrix;
You don't need to use separate variables for the matrix values, why would you when you have the matrix?
I don't understand the reason you need to get all values where you evaluate true or false. Instead just put directly into a std::vector the coordinates where your condition evaluates to true:
std::vector<std::pair<int, int> true_values;
for (int i = 0; i < matrix.size(); i++)
{
for (int j = 0; j < matrix[i].size(); j++)
{
if (some_condition_for_this_matrix_value(matrix[i][j], i, j) == true)
true_values.emplace_back(std::make_pair(i, j));
}
}
Now you have a vector of all matrix coordinates where your condition is true.
If you really want to have both true and false values, you could use a std::unordered_map with a std::pair containing the matrix coordinates as key and bool as value:
// Create a type alias, as this type will be used multiple times
typedef std::map<std::pair<int, int>, bool> bool_map_type;
bool_map_type bool_map;
Insert into this map all values from the matrix, with the coordinates of the matrix as the key, and the map value as true or false depending on whatever condition you have.
To get a list of all entries from the bool_map you can remove any false entries with std::remove_if:
std::remove_if(bool_map.begin(), bool_map.end(),
[](const bool_map_type::value_type& value) {
return value.second == false;
};
Now you have a map containing only entries with their value as true. Iterate over this map to get the coordinates to the matrix
Of course, I may totally have misunderstood your problem, in which case you of course are free to disregard this answer. :)
I know both C++ and Matlab (not Python) and in your case, I would really go for Matlab because it's way easier to use when you start programming (but don't forget to come back to C++ when you will find the limitations to Matlab).
In Matlab, you can define matrices very easily: just type the name of the matrix and the index you want to set:
m(1,1) = 1
m(2,2) = 1
gives you a 2x2 identity matrix (indices start with 1 in Matlab and entries are 0 by default). You can also define 3d matrices the same way:
x(1,2,3) = 2
For the import from Excel, it is possible if you save your excel file in CSV format, you can use the function dlmread to read it in Matlab. You could also try later to implement your algorithm directly in Matlab.
Finally, if you want to solve your binary integer programm, there is already a built-in function in Matlab, called bintprog which can solve it for you.
Hope it helps!
I'm using boost sparse matrices holding bool's and trying to write a comparison function for storing them in a map. It is a very simple comparison function. Basically, the idea is to look at the matrix as a binary number (after being flattened into a vector) and sorting based on the value of that number. This can be accomplished in this way:
for(unsigned int j = 0; j < maxJ; j++)
{
for(unsigned int i = 0; i < maxI; i++)
{
if(matrix1(i,j) < matrix2(i,j) return true;
else if(matrix1(i,j) > matrix2(i,j) return false;
}
}
return false;
However, this is inefficient because of the sparseness of the matrices and I'd like to use iterators for the same result. The algorithm using iterators seems straightforward, i.e.
1) grab the first nonzero cell in each matrix, 2) compare j*maxJ+i for both, 3) if equal, grab the next nonzero cells in each matrix and repeat. Unfortunately, in code this is extremely tedious and I'm worried about errors.
What I'm wondering is (a) is there a better way to do this and (b) is there a simple way to get the "next nonzero cell" for both matrices? Obviously, I can't use nested for loops like one would to iterate through one sparse matrix.
Thanks for your help.
--
Since it seems that the algorithm I proposed above may be the best solution in my particular application, I figured I should post the code I developed for the tricky part, getting the next nonzero cells in the two sparse matrices. This code is not ideal and not very clear, but I'm not sure how to improve it. If anyone spots a bug or knows how to improve it, I would appreciate some comments. Otherwise, I hope this is useful to someone else.
typedef boost::numeric::ublas::mapped_matrix<bool>::const_iterator1 iter1;
typedef boost::numeric::ublas::mapped_matrix<bool>::const_iterator2 iter2;
// Grabs the next nonzero cell in a sparse matrix after the cell pointed to by i1, i2.
std::pair<iter1, iter2> next_cell(iter1 i1, iter2 i2, iter1 end) const
{
if(i2 == i1.end())
{
if (i1 == end)
return std::pair<iter1, iter2>(i1, i2);
++i1;
i2 = i1.begin();
}
else
{
++i2;
}
for(; i1 != end;)
{
for(; i2 != i1.end(); ++i2)
{
return std::pair<iter1, iter2>(i1,i2);
}
++i1;
if(i1 != end) i2 = i1.begin();
}
return std::pair<iter1, iter2>(i1, i2);
}
I like this question, by the way.
Let me pseudocode out what I think you're asking
declare list of sparse matrices ListA
declare map MatMAp with a sparse Matrix type mapping to a double, along with a
`StrictWeakMatrixOrderer` function which takes two sparse matrices.
Insert ListA into MatMap.
The Question: How do I write a StrictWeakMatrixOrderer efficiently?
This is an approach. I'm inventing this on the fly....
Define a function flatten() and precompute the flattened matrices, storing the flattened vectors in a vector(or another container with a random indexing upper bound). flatten() could be as simple as concatenating each row(or column) with the previous one(which can be done in linear time if you have a constant-time function to grab a row/column).
This yields a set of vectors with size on the order of 10^6. This is a tradeoff - saving this information instead of on-the-fly computing it. This is useful if you're going to be doing a lot of compares as you go along.
Remember, zeros contain information - dropping them will possibly yield two vectors equal to each other, whereas their generating matrix may not be equal.
Then, we have transformed the algorithm question from "order matrices" into "order vectors".
I've never heard of a distance metric for matrices, but I've heard of distance metrics for vectors.
You could use a "sum of differences" ordering aka Hamming distance. (foreach element that's different, add 1). That will be a O(n) algorithm:
for i = 0 to max.
if(a[i] != b[i])
distance++
return distance
The Hamming distance satisfies these conditions
d(a,b) = d(b,a)
d(a,a) = 0
d(x, z) <= d(x, y) + d(y, z)
Now to do some off-the-cuff analysis....
10^6 elements in a matrix(or its corrosponding vector).
O(n) distance metric.
But it's O(n) compares. If each array access has O(m) time, then you would have an O(n*(n+n)) = O(n^2) metric. So you have to have < O(n) access. It turns out that std::vector [] operator provides "amortized constant time access to arbitrary elements" according to SGI's STL site.
Providing you have sufficient memory to store k*2*10^6, where k is the number of matrices you are managing, this is a working solution that uses lots of memory in exchange for being linear.
(a) I don't fully understand what you're trying to accomplish, but if you want to compare if both matrices have the same value at the same index it's sufficient to use elementwise matrix multiplication (which should be implemented for sparse as well):
matrix3 = element_prod (matrix1, matrix2);
That way you'll get for each index:
0 (false) * 1 (true) = 0 (false)
0*0 = 0
1*1 = 1
So resulting matrix3 will have your solution in one line :)
It seems to me we're talking about implementing bitwise,elementwise operators on boost::sparse_matrix, since comparing if one vector (or matrix) is smaller than another without using any standard vector norms demands special operators (or special mappings/norms).
To my knowledge boost does not provide special operators for binary matrices (not to speak of sparse binary matrices). There are unlikely any straightforward solutions to this using BLAS level matrix/vector algebra. Binary matrices have an own place in the linear algebra field, so there are tricks and theorems but i doubt those are easier than your solution.
Your question could be reformulated as: How do i sort efficiently astronomically large numbers represented by a 2d-bitmap (n=100 so 100x100 elements would give you a number like 2^10000).
Good question !