I am using Armadillo library for the matrix calculation in C++.
And I have one question about finding an index of the maximum value of given 3d arrays.
I found on their website about index_max().
index_max( M, dim )
dim=0, return a row vector, with each column containing the index of the extremum value in the corresponding column of M
dim=1, return a column vector, with each row containing the index of the extremum value in the corresponding row of M
And it seems like, they return the index of the maximum value of each row and column.
But I need an index of the maximum value of the entire matrix.
Does anyone know any way to find an index of the max using Armadillo library?
Thanks in advance.
Instead of the standalone index_max() function, use the .index_max() member function of the matrix or cube. Example:
arma::mat X(100, 200, arma::fill::randu);
arma::uword index = X.index_max();
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 have a very big array of many value and store it in an row-major 1d array.
ex:
1 2 3
4 5 6
will be store in int* array = {1,2,3,4,5,6};
what I have to do is given the row1, row2, column1, column2, then print out the area's sum, and it will request to caulate different area for many times.
what I have think about it is first use nested loop to traverse the array and store each row's sum in sum_row and store each column's sum in sum_column and store the total element's sum im totalSum.
Then totalSum - the row and the columns that surrond it + the elemnts that has been minus twice.
But it seems fast enough, is there any algorithm that can do faster or some coding style tips that can make the factor little?
Thx in advance.
It seems to me that you have replaced one double iteration with another. The problem is in subtracting "the elemnts that has been minus twice"; unless I'm mistaken, this involves iterating over those elements to sum them.
Instead, just iterate over the rectangular area that you need to sum. I doubt it will be any slower.
A more efficient algorithm can be obtained by generating the matrix of summed upper-left matrices. (See the Wikipedia article on summed area table.) You can then compute any submatrix sum by looking up four area sums.
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!