Extend/Pad matrix in Eigen - c++

Say I have
A = [1 2 3]
[4 5 6]
[7 8 9]
I want to pad it with the first row and first column or last row and last column as many times as needed to create A nxn. For example, A 4x4 would be
A = [1 1 2 3]
[1 1 2 3]
[4 4 5 6]
[7 7 8 9]
and A 5x5 would be
A = [1 1 2 3 3]
[1 1 2 3 3]
[4 4 5 6 6]
[7 7 8 9 9]
[7 7 8 9 9]
I'm aware that I could do A.conservativeResize(4,4) which gets me
A = [1 2 3 0]
[4 5 6 0]
[7 8 9 0]
[0 0 0 0]
then I could copy things around one by one, but is there a more efficient way to do this using Eigen?

You can workaround using a nullary-expression:
#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
using namespace std;
int main()
{
Matrix3i A;
A.reshaped() = VectorXi::LinSpaced(9,1,9);
cout << A << "\n\n";
int N = 5;
MatrixXi B(N,N);
B = MatrixXi::NullaryExpr(N, N, [&A,N] (Index i,Index j) {
return A( std::max<Index>(0,i-(N-A.rows())),
std::max<Index>(0,j-(N-A.cols())) ); } );
cout << B << "\n\n";
}
Another approach would be to create a clamped sequence of indices like [0 0 0 1 2]:
struct pad {
Index size() const { return m_out_size; }
Index operator[] (Index i) const { return std::max<Index>(0,i-(m_out_size-m_in_size)); }
Index m_in_size, m_out_size;
};
B = A(pad{3,N}, pad{3,N});
This version requires the head of Eigen.
You can easily build on those examples to make them even more general and/or wrap them within functions.

Just as a note, it's not true that A.conservativeResize(4,4) will get you a matrix with the added rows filled with zeros. The Eigen documentation says,
In case values need to be appended to the matrix they will be uninitialized.
The new rows and columns will be filled with garbage, and seeing zeros is only a coincidence (unless you are compiling with a special preprocessor directive to Eigen). But this means that no unnecessary time is wasted writing zeros that you will overwrite anyway.
Note: this code demonstrates how to get a matrix with your original matrix in the top left corner:
The best way to fill multiple values at once is to use Eigen's block operations and setConstant. For example, if A is a matrix of size old_sizexold_size:
A.conservativeResize(n, n);
for (int i = 0; i < n; ++i) {
// Fill the end of each row and column
A.row(i).tail(n - old_size).setConstant(A(i, old_size - 1));
A.col(i).tail(n - old_size).setConstant(A(old_size - 1, i));
}
// Fill the bottom right block
A.bottomRightCorner(n - old_size, n - old_size).setConstant(A(old_size - 1, old_size - 1));
More importantly than being "efficient", these functions express your intent as a programmer.
Edit: To get a padded matrix with your original matrix in the middle:
I just noticed your example pads around the original matrix in the middle, not in the top left. In this case, there is little point to using conservativeResize(), because the original values will only be copied to the top left corner. An outline of the solution is:
Construct a new nxn matrix B of the desired size
Copy your original matrix to the middle using
int start = (n - old_size + 1)/2;
B.block(start, start, old_size, old_size) = A;
Fill in the outside values using block operations similar to my example above.

Related

Matrix masking operation in OpenCV(C++) and in Matlab

I would like to do the following operation (which is at the current state in Matlab) using cv::Mat variables.
I have matrix mask:
mask =
1 0 0
1 0 1
then matrix M:
M =
1
2
3
4
5
6
3
and samples = M(mask,:)
samples =
1
2
6
My question is, how can I perform the same operation like, M(mask,:), with OpenCV?
With my knowledge the closet function to this thing is copyTo function in opencv that get matrix and mask for inputs. but this function hold original structure of your matrix you can test it.
I think there is no problem to use for loop in opencv(in c++) because it's fast. I propose to use for loop with below codes.
Mat M=(Mat_<uchar>(2,3)<<1,2,3,4,5,6); //Create M
cout<<M<<endl;
Mat mask=(Mat_<bool>(2,3)<<1,0,0,1,0,1); // Create mask
cout<<mask<<endl;
Mat samples;
///////////////////////////////
for(int i=0;i<M.total();i++)
{
if(mask.at<uchar>(i))
samples.push_back(M.at<uchar>(i));
}
cout<<samples<<endl;
above code result below outputs.
[ 1, 2, 3;
4, 5, 6]
[ 1, 0, 0;
1, 0, 1]
[ 1;
4;
6]
with using copyTo your output will be like below
[1 0 0
4 0 6];

Bubble sort not working as expected C++

I wrote a simple bubble sorting algorithm, however it is returning strange results when ran...
I am attempting to sort parallel vectors (not sure if that is correct terminology, I'm taking the concept of parallel arrays and applying it to vectors so I can modify the size at runtime) that make up a contact list.
The code pertaining to the vectors and bubble sort:
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
using namespace std;
int main(int argc, char** argv) {
vector <long long int> numbers;
vector <string> names;
names.push_back("jack");
numbers.push_back(6515551234);
names.push_back("jill");
numbers.push_back(6515554321);
names.push_back("bob");
numbers.push_back(6515557777);
names.push_back("aaron");
numbers.push_back(6665559999);
names.push_back("fred");
numbers.push_back(1115552222);
int index = -1;
long int temp = -1;
int pass = -1;
string tempName;
int sortChoice;
for (pass = 0; pass < names.size(); pass++) {
for (index = 0; index < names.size() - pass; index++) {
if ( names[index] > names[index + 1] ) {
temp = numbers[index];
numbers[index] = numbers[index + 1];
numbers[index + 1] = temp;
tempName = names[index];
names[index] = names[index + 1];
names[index + 1] = tempName;
}
}
}
for(int i = 0; i < numbers.size(); i++) {
cout << names[i] << ": " << numbers[i] << endl;
}
return 0;
}
And the output:
: 465675315720
aaron: 6665559999
bob: 6515557777
fred: 1115552222
jack: 6515551234
And it seems that no matter how I change the vectors themselves, the last one is always cut off, and put at the beginning with no name and a (seemingly) random number. Has anyone seen this before?
The only thing I can think of is that while the sort is processing, something goes awry in memory, causing pointing to incorrect memory locations?... And the fact that it is always the last element makes me think the issue pertains to the last iteration of the loop.
Also, I made a version of this to sort by numbers rather than names, and it works perfectly every time. It's the same code but using numbers[index] in place of names[index] in the algorithm loop.
P.S. - I'm still rather new to StackOverflow and coding in general, so if I made any mistakes in formatting this post let me know and I will change them. And I hope I provided enough information.
Thank you in advance!
for each loop, you should compare each neighborhood, from the first to the end.
your error:
for (index = 0; index < names.size() - pass; index++) {
should be
for (index = 0; index < names.size() - 1; index++) {
here is a sample
start: 5 4 3 2 1
loop: 0
index: 0 : [5 4] 3 2 1 => [4 5] 3 2 1
index: 1 :4 [5 3] 2 1 => 4 [3 5] 2 1
index: 2 :4 3 [5 2] 1 => 4 3 [2 5] 1
index: 3 :4 3 2 [5 1] => 4 3 2 [1 5]
loop: 1
index: 0 : [4 3] 2 1 5 => [3 4] 2 1 5
index: 1 :3 [4 2] 1 5 => 3 [2 4] 1 5
index: 2 :3 2 [4 1] 5 => 3 2 [1 4] 5
index: 3 :3 2 1 [4 5] => 3 2 1 [4 5]
loop: 2
index: 0 : [3 2] 1 4 5 => [2 3] 1 4 5
index: 1 :2 [3 1] 4 5 => 2 [1 3] 4 5
index: 2 :2 1 [3 4] 5 => 2 1 [3 4] 5
index: 3 :2 1 3 [4 5] => 2 1 3 [4 5]
loop: 3
index: 0 : [2 1] 3 4 5 => [1 2] 3 4 5
index: 1 :1 [2 3] 4 5 => 1 [2 3] 4 5
index: 2 :1 2 [3 4] 5 => 1 2 [3 4] 5
index: 3 :1 2 3 [4 5] => 1 2 3 [4 5]
loop: 4
index: 0 : [1 2] 3 4 5 => [1 2] 3 4 5
index: 1 :1 [2 3] 4 5 => 1 [2 3] 4 5
index: 2 :1 2 [3 4] 5 => 1 2 [3 4] 5
index: 3 :1 2 3 [4 5] => 1 2 3 [4 5]
final result: 1 2 3 4 5
the code that you have written above is not bubble sort !
however , try this instead , this is bubble sort:
for (pass = 0; pass < names.size(); pass++) {
for (index = pass+1; index < names.size(); index++) {
if ( names[pass] > names[index] ) {
temp = numbers[index];
numbers[index] = numbers[pass];
numbers[pass] = temp;
tempName = names[index];
names[index] = names[pass];
names[pass] = tempName;
}
}
}
i offer you use a pair instead of two vectors

Mathematically rotate an array of ordered numbers

Suppose you have a set of numbers in a given domain, for example: [-4,4]
Also suppose that this set of numbers is in an array, and in numerical order, like so:
[-4, -3 -2, -1, 0, 1, 2, 3, 4]
Now suppose I would like to create a new zero-point for this set of numbers, like so: (I select -2 to be my new axis, and all elements are shifted accordingly)
Original: [-4, -3 -2, -1, 0, 1, 2, 3, 4]
Zeroed: [-2, -1 0, 1, 2, 3, 4, -4, -3]
With the new zeroed array, lets say I have a function called:
"int getElementRelativeToZeroPosition(int zeroPos, int valueFromOriginalArray, int startDomain, int endDomain) {...}"
with example usage:
I am given 3 of the original array, and would like to see where it mapped to on the zeroed array, with the zero on -2.
getElementRelativeToZeroPosition(-2, 3, -4, 4) = -4
Without having to create any arrays and move elements around for this mapping, how would I mathematically produce the desired result of the function above?
I would proceed this way:
Get index of original zero position
Get index of new zero position (ie. index of -2 in you example)
Get index of searched position (index of 3)
Compute move vector between new and original zero position
Apply move vector to searched position modulo the array size to perform the rotation
Provided your array is zero-based:
index(0) => 4
index(-2) => 2
index(3) => 7
array_size => 9
move_vector => index(0) - index(-2)
=> 4 - 2 => +2
new_pos(3) => (index(3) + move_vector) modulo array_size
=> (7 + 2) mod 9 => 0
value_at(0) => -4
That's it
Mathematically speaking, if you have an implicit set of integers given by an inclusive range [start, stop], the choice of choosing a new zero point is really a choosing of an index to start at. After you compute this index, you can compute the index of your query point (in the original domain), and find the difference between them to get the offset:
For example:
Given: range [-4, 4], assume zero-indexed array (0,...,8) corresponding to values in the range
length(range) = 4 - (-4) + 1= 9
Choose new 'zero point' of -2.
Index of -2 is -2 - (-4) = -2 + 4 = 2
Query for position of 3:
Index in original range: 3 - (-4) = 3 + 4 = 7
Find offset of 3 in zeroed array:
This is the difference between the indices in the original array
7 - 2 = 5, so the element 3 is five hops away from element -2. Equivalently, it's 5-len(range) = 5 - 9 = -4 hops away. You can take the min(abs(5), abs(-4)) to see which one you'd prefer to take.
you can write a doubled linked list, with a head-node which points to the beginning
struct nodeItem
{
nodeItem* pev = nullptr;
nodeItem* next = nullptr;
int value = 0;
}
class Node
{
private:
nodeItem* head;
public:
void SetHeadToValue(int value);
...
}
The last value should point with next to the first one, so you have a circular list.
To figur out, if you are at the end of the list, you have to check if the item is equal to the head node

Extended polynomials in library NTL

There is code is written using NTL library:
int main()
{
ZZ_p::init(ZZ(5)); // define GF(5)
ZZ_pX P;
BuildIrred(P, 4); // generate an irreducible polynomial P
// of degree 4 over GF(5)
ZZ_pE::init(P); // define GF(5^4)
ZZ_pEX f, g, h; // declare polynomials over GF(5^4)
random(f, 3); // f is a random, monic polynomial of degree 3
SetCoeff(f, 3);
cout << f << endl<< endl;
}
The output is:
[[3 1 1 4] [2 1 3 2] [1 0 3 1] [1]]
For example, [1 2 3] is mean 3x² + 2x + 1.
What the form of notation polynomial over GF in this case?
Your question is a little bit difficult to understand. If I understand you right, the question is how to interpret the NTL representation [[3 1 1 4] [2 1 3 2] [1 0 3 1] [1]] of a polynomial over the finite field with 5⁴ elements.
First: The elements in the finite field with 5⁴ elements (called GF(5⁴)) are represented as the polynomials GF(5)[X] mod f, where f is an irreducible polynomial of degree 4.
This means a polynomial over GF(5⁴) is a Polynomial where the coefficients are polynomials in GF(5)[X] mod f.
So [[3 1 1 4] [2 1 3 2] [1 0 3 1] [1]] can be interpreted as
Y³ + (X³ + 3X² + 1)⋅Y² + (2X³ + 3X² + X + 2)⋅Y + (4X³ + X² + X + 3)
Notice: The comment in
random(f, 3); // f is a random, monic polynomial of degree 3
SetCoeff(f, 3);
is a little bit misleading. random(f,3) sets f to a random polynomial of degree less than 3. SetCoeff(f, 3) sets the coefficient of Y³ to 1 and after that it is a polynomial of degree 3.

How to detect all possible subsets from a given vector?

I'm writing a function which should detect all possible subsets from a main vector and push them to another vector. The elements in the subsets are also added to each other before being pushed into the new vector(s1).
At the moment what my code does is the following..
For example, lets say myvec = {1,2,3}, then v1 = {1,3,6,2,5,3}. It only sums consecutive numbers. However I also want it to sum up combinations like 1 & 3 which would add a 4 to the vector v1. At the moment, I have not been able to modify my algorithm in a way that I can achieve that. Any help will be appreciated!
for (k=0; k<myvec.size(); k++) {
total = 0;
for (m=k; m<int_vec.size(); m++) {
total += myvec[m];
v1.push_back(total);
}
}
One way to think about the power set of a given (ordered) set is to think of its elements (the subsets) as bit vectors where the n-th bit is set to 1 if and only if the n-th element from the set was chosen for this subset.
So in your example, you'd have a 3 bit vector that could be represented as an unsigned integer. You'd “count the bit vector” up from 0 (the empty set) to 7 (the entire set). Then, in each iteration, you pick those elements for which the respective bit is set.
As can be readily seen, the power set explodes rapidly which will make it impractical to compute explicitly for any set with more than a dozen or so elements.
Casting these thoughts into C++, we get the following.
#include <climits> // CHAR_BIT
#include <iostream> // std::cout, std::endl
#include <stdexcept> // std::invalid_argument
#include <type_traits> // std::is_arithmetic
#include <vector> // std::vector
template<typename T>
std::vector<T>
get_subset_sums(const std::vector<T>& elements)
{
static_assert(std::is_arithmetic<T>::value, "T must be arithmetic");
if (elements.size() > CHAR_BIT * sizeof(unsigned long))
throw std::invalid_argument {"too many elements"};
const std::size_t power_size {1UL << elements.size()};
std::vector<T> subset_sums {};
subset_sums.reserve(power_size);
for (unsigned long mask = 0UL; mask < power_size; ++mask)
{
T sum {};
for (std::size_t i = 0; i < elements.size(); ++i)
{
if (mask & (1UL << i))
sum += elements.at(i);
}
subset_sums.push_back(sum);
}
return subset_sums;
}
int
main()
{
std::vector<int> elements {1, 2, 3};
for (const int sum : get_subset_sums(elements))
std::cout << sum << std::endl;
return 0;
}
You might want to use a std::unordered_set for the subset-sums instead of a std::vector to save the space (and redundant further processing) for duplicates.
The program outputs the numbers 0 (the empty sum), 1 (= 1), 2 (= 2), 3 (= 1 + 2), 3 (= 3), 4 (= 1 + 3), 5 (= 2 + 3) and 6 (= 1 + 2 + 3). We can make this more visual.
mask mask
(decimal) (binary) subset sum
–––––––––––––––––––––––––––––––––––––––––––––––––
0 000 {} 0
1 001 {1} 1
2 010 {2} 2
3 011 {1, 2} 3
4 100 {3} 3
5 101 {1, 3} 4
6 110 {2, 3} 5
7 111 {1, 2, 3} 6