Efficient C++ way to shift a cv::Mat with OpenCV - c++

What is an efficient way to "shift" an OpenCV cv::Mat?
With shift I mean that if I have a row like this
0, 1, 2, 3, 4, 5, 6, 7, 8, 9
and I shift it by 3 positions, I will get a row like this
3, 4, 5, 6, 7, 8, 9, 0, 1, 2
Now I am using this function:
void shift( const cv::Mat& in, cv::Mat& out, int shift )
{
if ( shift < 0 || shift > in.cols ) return;
if ( shift == 0 || shift==in.cols ) {
out = in.clone();
} else {
cv::hconcat(in(cv::Rect(shift,0,in.cols-shift,in.rows)),in(cv::Rect(0,0,shift,in.rows)),out);
}
}
but I am looking for a more efficient way.

If size of your array is not so big and rows=1 then you can repeat your array like this
0,1,2,3,4,5,6,7,8,9, 0,1,2,3,4,5,6,7,8,9
Then for shifting it shift array's datapointer

Related

AVX512 - Left packing elements by index using mask

In short, I am trying to compress(left pack) 64-bit integers by index. Neither scatter nor compress intrinsics solves this problem directly.
Suppose you have eight 64-bit integers in a and want to left pack those elements at addresses starting at base_addr by the index subject to mask k.
int64_t* dst; // memory to store the result
__m512i a = _mm512_loadu_si512 ( arr ); // load data from memory into a
__mmask8 k = _mm512_cmpgt_epi64_mask ( a, _mm512_set1_epi64(6) ); // compare for greater-than
__m512i index = _mm512_set_epi64 ( 14, 12, 10, 8, 6, 4, 2, 0 ); // index vector
_mm512_mask_compressstoreu_epi64_by_index ( dst, k, index, a ); // How can I implement this function efficiently?
So, _mm512_mask_compressstoreu_epi64_by_index function should compress 64-bit integers from a into memory dst using index. The writemask k stores the element, which is active in a, to memory.
The result of this function will looks like:
dst = [10, 0, 7, 0, 9, 0, 0, 0 ...].
The elements 10, 7 and 9 are stored after an index 0, 2 and 4 accordingly.
I've tried _mm512_mask_compressstoreu_epi64 and _mm512_mask_i64scatter_epi64 intrinsics, but these instructions save the elements differently. They will give you following results:
_mm512_mask_compressstoreu_epi64( dst, k, a ) produces: dst = [ 10, 7, 9 , ... ]
_mm512_mask_i64scatter_epi64 ( dst, k, index, a, 8 ) produces: dst = [ 0, 10, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 9, ...]
What I want is _mm512_mask_compressstoreu_epi64_by_index( dst, k, index, a ) which results dst = [10, 0, 7, 0, 9, 0, 0, 0 ...]
How can I solve this problem?

How sparse matrix-indexing can be done for a matrix stored as "Compressed Sparse Row"?

I have my large sparse symmetric matrix stored as Compressed Sparse Row (CSR) using Intel MKL. For the sake of example, let's assume my symmetric sparse matrix is a 5x5:
A =
1 -1 0 -3 0
-1 5 0 0 0
0 0 4 6 4
-3 0 6 7 0
0 0 4 0 -5
values = {1, -1, -3, 5, 4, 6, 4, 7, -5}; // symmetric sparse matrix
columns = {0, 1, 3, 1, 2, 3, 4, 3, 4}; // zero-based
rowIndex = {0, 3, 4, 7, 8, 9}; // zero-based
I am trying to find a submatrix of A given the rows and columns, e.g., A(1:3, 2:4):
A(1:3,2:4) =
0 0 0
4 6 4
6 7 0
values = {4, 6, 4, 6, 7}; // General sparse matrix (sub-matrix is not necessarily symmetric)
columns = {0, 1, 2, 0, 1}; // zero-based
rowIndex = {0, 0, 3, 5}; // zero-based
I would be grateful to know how matrix-indexing can be done. One way I can think of is to convert CSR to coordinate format COO and apply matrix-indexing and then converting it back to CSR, which I don't think it is an efficient way.
Could someone let me know of an efficient or a common way of sparse matrix-indexing?
The trick is to look up values in the lower triangle by the output column (which is their row). You can keep an index into the data for each row, since you visit the entries in column order as you progress in row order for the output.
With the expositional type
struct CSR { // sometimes implicitly symmetric
std::vector<...> vals;
std::vector<int> cols,rowStart;
};
we have
// Return the [r0,r1) by [c0,c1) submatrix, never
// using any symmetry it might have.
CSR submatrix(const CSR &sym,int r0,int r1,int c0,int c1) {
const int m=r1-r0,n=c1-c0;
std::vector<int> finger(sym.rowStart.begin()+c0,sym.rowStart.begin()+c1);
CSR ret;
ret.rowStart.reserve(m+1);
ret.rowStart.push_back(0);
for(int r=0,rs=r0;r<m;++r,++rs) {
// (Strictly) lower triangle:
for(int cs=c0,c=0;cs<rs;++cs,++c)
for(int &f=finger[c],f1=sym.rowStart[cs+1];f<f1;++f) {
const int cf=sym.cols[f];
if(cf>rs) break;
if(cf==rs) {
ret.vals.push_back(sym.vals[f]);
ret.cols.push_back(c);
}
}
// Copy the relevant subsequence of the upper triangle:
for(int f=sym.rowStart[rs],f1=sym.rowStart[rs+1];f<f1;++f) {
const int c=sym.cols[f]-c0;
if(c<0) continue;
if(c>=n) break;
ret.vals.push_back(sym.vals[f]);
ret.cols.push_back(c);
}
ret.rowStart.push_back(ret.vals.size());
}
return ret;
}
For large matrices, the upper triangle loop could be optimized by using a binary search to find the relevant range of f.

How to return the index where values change in a c++ vector?

Sorry for the vague title, I'm not sure how to word it.
Say I have a vector:
vector<int> vec{{
1, 2, 3, 4, 5, 7, 8, 9, 10, 12, 13, 14
}};
and a corresponding positions vector which occurs after a number is missed (like 5 to 7).
vector<int> positions{{
1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1
}};
How would I return a 2D vector running from each 1, up to but not including the next one: e.g.
1 2 3 4 5
7 8 9 10
12 13 14
Thanks in advance, I'd post my attempts, but they all led down blind avenues. I know it's an odd structure...
There are a few ways to solve this, but I believe this should work:
std::vector<std::vector<int>> vec2D;
int index = -1;
// Identify the indices of the position vector and use that to identify the
// correct indices of the vec.
for (int i = 0; i != position.size(); ++i)
{
// if the value at i of the position vector is 0,
// push_back the value at i of the vec vector into
// the correct vector of vector.
if (0 == position[i])
{
vec2D[index].push_back(vec[i])
}
else if (1 == position[i])
{
++index; //increment to the next vector
std::vector<int> temp;
vec2D.push_back(temp);
vec2D[index].push_back(vec[i])
}
}

Max subarray with start and end index

I'm trying to find the maximum contiguous subarray with start and end index. The method I've adopted is divide-and-conquer, with O(nlogn) time complexity.
I have tested with several test cases, and the start and end index always work correctly. However, I found that if the array contains an odd-numbered of elements, the maximum sum is sometimes correct, sometimes incorrect(seemingly random). But for even cases, it is always correct. Here is my code:
int maxSubSeq(int A[], int n, int &s, int &e)
{
// s and e stands for start and end index respectively,
// and both are passed by reference
if(n == 1){
return A[0];
}
int sum = 0;
int midIndex = n / 2;
int maxLeftIndex = midIndex - 1;
int maxRightIndex = midIndex;
int leftMaxSubSeq = A[maxLeftIndex];
int rightMaxSubSeq = A[maxRightIndex];
int left = maxSubSeq(A, midIndex, s, e);
int right = maxSubSeq(A + midIndex, n - midIndex, s, e);
for(int i = midIndex - 1; i >= 0; i--){
sum += A[i];
if(sum > leftMaxSubSeq){
leftMaxSubSeq = sum;
s = i;
}
}
sum = 0;
for(int i = midIndex; i < n; i++){
sum += A[i];
if(sum > rightMaxSubSeq){
rightMaxSubSeq = sum;
e = i;
}
}
return max(max(leftMaxSubSeq + rightMaxSubSeq, left),right);
}
Below is two of the test cases I was working with, one has odd-numbered elements, one has even-numbered elements.
Array with 11 elements:
1, 3, -7, 9, 6, 3, -2, 4, -1, -9,
2,
Array with 20 elements:
1, 3, 2, -2, 4, 5, -9, -4, -8, 6,
5, 9, 7, -1, 5, -2, 6, 4, -3, -1,
Edit: The following are the 2 kinds of outputs:
// TEST 1
Test file : T2-Data-1.txt
Array with 11 elements:
1, 3, -7, 9, 6, 3, -2, 4, -1, -9,
2,
maxSubSeq : A[3..7] = 32769 // Index is correct, but sum should be 20
Test file : T2-Data-2.txt
Array with 20 elements:
1, 3, 2, -2, 4, 5, -9, -4, -8, 6,
5, 9, 7, -1, 5, -2, 6, 4, -3, -1,
maxSubSeq : A[9..17] = 39 // correct
// TEST 2
Test file : T2-Data-1.txt
Array with 11 elements:
1, 3, -7, 9, 6, 3, -2, 4, -1, -9,
2,
maxSubSeq : A[3..7] = 20
Test file : T2-Data-2.txt
Array with 20 elements:
1, 3, 2, -2, 4, 5, -9, -4, -8, 6,
5, 9, 7, -1, 5, -2, 6, 4, -3, -1,
maxSubSeq : A[9..17] = 39
Can anyone point out why this is occurring? Thanks in advance!
Assuming that n is the correct size of your array (we see it being passed in as a parameter and later used to initialize midIndexbut we do not see its actual invocation and so must assume you're doing it correctly), the issue lies here:
int midIndex = n / 2;
In the case that your array has an odd number of elements, which we can represented as
n = 2k + 1
we can find that your middle index will always equate to
(2k + 1) / 2 = k + (1/2)
which means that for every integer, k, you'll always have half of an integer number added to k.
C++ doesn't round integers that receive floating-point numbers; it truncates. So while you'd expect k + 0.5 to round to k+1, you actually get k after truncation.
This means that, for example, when your array size is 11, midIndex is defined to be 5. Therefore, you need to adjust your code accordingly.

Generate Regex Digit Ranges from Sorted List of Digits

Suppose I have some sorted lists of integers and I want to convert them to their respective regex digit ranges, like so:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] => [0-9]
[0, 1, 2, 3, 4, 6, 7, 8, 9] => [0-46-9]
[0, 1, 3, 4, 5, 8, 9] => [013-589]
[0, 2, 4, 6, 8] => [02468]
I am not trying to regex match anything here. I am trying to generate a regex range from a set of digits.
I am really just looking to see if there is already some de facto algorithm for doing something like this.
Edit: Based on #Jerry_Coffin's answer, a Java-based algorithm:
List<Integer> digits = Arrays.asList(0, 1, 3, 4, 5, 8, 9);
StringBuilder digitRange = new StringBuilder().append('[');
int consecutive = 0;
for (int i = 0; i < digits.size(); i++) {
if (i == digits.size() - 1 || digits.get(i) + 1 != digits.get(i + 1)) {
if (consecutive > 1) {
digitRange.append('-');
}
digitRange.append(digits.get(i));
consecutive = 0;
} else {
if (consecutive == 0) {
digitRange.append(digits.get(i));
}
consecutive++;
}
}
digitRange.append(']');
System.out.println(digitRange.toString());
Output: [013-589]
Feel free to find improvements or problems.
Presumably you're starting from sorted input (if not, you almost certainly want to start by sorting the input).
From there, start from the first (unprocessed) item, write it out. Walk through the numbers as long as they're consecutive. Assuming you get more than two consecutive, write out a dash then the last of the consecutive numbers. If you got two or fewer consecutive, just write them to output as-is.
Repeat until you reach the end of the input.
I can propose a different approach.
Iterate through the list identifying intervals. We keep two variables left and right (interval bounds) and each time we have two not consecutive values we write the interval to a StringBuilder.
int[] list = new[] { 0, 1, 3, 4, 5, 8, 9 };
int left = 0;
int right = 0;
for (int i = 0; i < list.Length; i++)
{
if (i == 0) // first case
{
left = right = list[i];
continue;
}
if (list[i] - list[i - 1] > 1) // not consecutive
{
builder.AppendFormat(Write(left, right));
left = list[i];
}
right = list[i];
}
builder.AppendFormat(Write(left, right));// last case
builder.Append("]");
The write method:
private static string Write(int left, int right)
{
return
left == right
? left.ToString()
: right - left == 1
? string.Format("{0}{1}", left, right)
: string.Format("{0}-{1}", left, right);
}