Eigen equivalent of Matlab's sum(A)? - c++

How can I get the row vector, each value of which is the sum of each column of a 2D Array in Eigen?
I want the equivalent of the Matlab sum function, i.e.
>> x = [1,2,3;4,5,6]
x =
1.0000e+000 2.0000e+000 3.0000e+000
4.0000e+000 5.0000e+000 6.0000e+000
>> sum (x)
ans =
5.0000e+000 7.0000e+000 9.0000e+000
can I use colwise to do this somehow?

You can use m.colwise().sum().
See at Combining partial reductions with other operations section here.

Related

How to compute sum of first k binomial coefficients in O(n) without overflow?

I am trying to calculate this in O(N) without overflow (using C++)
To clarify, n, r are given beforehand, and I am trying to find the answer for one instance of (n,r) pair in O(N)
Here's my trial:
Use O(N) calculate ans = n!/(r!(n-r)!2^n)
Let c = ans, use O(N) to modify c: c /= (n-p); c*=(p+1) for p = r-1 to 0. Add c into ans for each step
Basically I use O(N) to calculate the last term first, then use something like a sliding window to find the second last term, then the next one...until the first term. Sum them up in the process.
While it seems to be correct, the actual run time is still slower than I expected. So I wonder is there any special known tricks on this formula which can boost the performance? If no then is there any way to cut down the constant factor maybe? (based on the following snippet)
Another big problem is I was facing a dilemma: which is I cannot compute 2^(-n) nor nCr alone for big n, or it will go underflow / overflow. That's why I tried to compute 2^(-n) * The last term in the summation and hope for the effect will cancel each other so that I won't get underflow / overflow in the whole process. Is there any method to 100% ensure that I won't get underflow / overflow?
(If possible, I would like to avoid using big integer library)
// c++ code snippet to demonstrate the idea
double ans = 1;
for(int p=n; p>=1; p--){
ans *= p;
ans /= 2;
if(p <= r) ans /= p;
if(p <= n-r) ans /= p;
}
// now ans = n!/(r!(n-r)!2^n)
// use O(N) more time to find the ultimate ans: summation (n!/(r!(n-r)!2^n)) for r >= 0
double c = ans;
for(int p = r-1; p >= 0; p--){
c /= (n-p);
c *= (p+1);
// Each new c is the next term: n!/((r-1)!(n-r+1)!2^n)
ans += c;
}
Calculate and store log(m!) for each m from 0 to n.
Calculate log(1/2**n).
Now p-th term of the sum is exp(log(n!)-log(p!)-log((n-p)!)+log(1/2**n)). Add these terms together.
Why don't you start the summation in the first loop? If the first loop would compute the binomial coefficients correctly, you can sum them up and also compute the denominator. At the moment you only compute ans=2^(-n), as the other operations cancel each other.
The sum written out is
1/2^n*(1+n+n*(n-1)/2+n*(n-1)*(n-2)/(2*3)+...)
Th quotient between two binomials is
nC[k+1]/nC[k] = (n-k) / (k+1)
Note also that the partial sums with upper index r and n-r-1 have the sum 1 by the binomial theorem.

Replacing all negative elements with zero eigen3 c++

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());

Do Loop for Matrix Multiplication in SAS

I have a 6*6 matrix called m1, and I want to use Do Loop in SAS to create matrices such that m2=m1*m1; m3=m2*m1; m4=m3*m1 ... mi=m(i-1)*m1.
Here is what I wrote:
proc iml;
use a;
read all into cat(m,1);
do i=2 to 10;
j=i-1;
cat(m,i)=cat(m,j)*cat(m,1);
print cat(m,i);
end;
quit;
And it won't work because cat(m,1) may not be correct. How can I use the Do Loop for this? Thank you very much for your time and help!
cat() is not going to work. It is a character function. It is not going to create a matrix named by the string output.
Why not just use the matrix power operator?
m2 = m1**2;
m3 = m1**3;
Unless you have big matrices, the time saved iterating the calculation instead of just using the power is next to 0.
For many iterative algorithms, you want to perform some computation on EACH matrix, but you don't need all matrices at the same time. For example, if you wanted to know the determinant of m, m##2, m##2, etc, you would write
result = j(10,1); /* store the 10 results */
m = I(nrow(a)); /* identity matrix */
do i = 1 to 10;
m = m*a; /* m is a##i during i_th iteration */
result[i] = det(m);
end;
print result;
If you actually need all 10 matrices at the same time in different matrices (this is rare), you can use the VALSET and VALUE functions as explained in this article: Indirect assignment: How to create and use matrices named x1, x2,..., xn
As an aside, you might also be interested in the trick of packing matries into an array by flattening them. It is sometimes a useful technique when you need to return k matrices from function module and k is a parameter to the module.

Eigen elements manipulation without loop

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)

How to auto-generate and assign variables corresponding to elements in a matrix?

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!