first value of a loop in c++ different for the others - c++

I need to put the first value of a loop = 0, and then use a range to start the loop.
In MatLab this is possible : x = [0 -range:range] (range is a integer)
This will give a value of [0, -range, -range+1, -range+2, .... , range-1, range]
The problem is I need to do this in C++, I tried to do by an array and then put in like the value on the loop without success.
//After loading 2 images, put it into matrix values and then trying to compare each one.
for r=1:bRows
for c=1:bCols
rb=r*blockSize;
cb=c*blockSize;
%%for each block search in the near position(1.5 block size)
search=blockSize*1.5;
for dr= [0 -search:search] //Here's the problem.
for dc= [0 -search:search]
%%check if it is inside the image
if(rb+dr-blockSize+1>0 && rb+dr<=rows && cb+dc-blockSize+1>0 && cb+dc<=cols)
%compute the error and check if it is lower then the previous or not
block=I1(rb+dr-blockSize+1:rb+dr,cb+dc-blockSize+1:cb+dc,1);
TE=sum( sum( abs( block - cell2mat(B2(r,c)) ) ) );
if(TE<E)
M(r,c,:)=[dr dc]; %store the motion vector
Err(r,c,:)=TE; %store th error
E=TE;
end
end
end
end
%reset the error for the next search
E=255*blockSize^2;
end
end

C++ doesn't natively support ranges of the kind you know from MatLab, although external solutions are available, if somewhat of an overkill for your use case. However, C++ allows you to implement them easily (and efficiently) using the primitives provided by the language, such as for loops and resizable arrays. For example:
// Return a vector consisting of
// {0, -limit, -limit+1, ..., limit-1, limit}.
std::vector<int> build_range0(int limit)
{
std::vector<int> ret{0};
for (auto i = -limit; i <= limit; i++)
ret.push_back(i);
return ret;
}
The resulting vector can be easily used for iteration:
for (int dr: build_range0(search)) {
for (int dc: build_range0(search)) {
if (rb + dr - blockSize + 1 > 0 && ...)
...
}
}
The above of course wastes some space to create a temporary vector, only to throw it away (which I suspect happens in your MatLab example as well). If you want to just iterate over the values, you will need to incorporate the loop such as the one in build_range0 directly in your function. This has the potential to reduce readability and introduce repetition. To keep the code maintainable, you can abstract the loop into a generic function that accepts a callback with the loop body:
// Call fn(0), fn(-limit), fn(-limit+1), ..., fn(limit-1), and fn(limit)
template<typename F>
void for_range0(int limit, F fn) {
fn(0);
for (auto i = -limit; i <= limit; i++)
fn(i);
}
The above function can be used to implement iteration by providing the loop body as an anonymous function:
for_range0(search, [&](int dr) {
for_range0(search, [&](int dc) {
if (rb + dr - blockSize + 1 > 0 && ...)
...
});
});
(Note that both anonymous functions capture enclosing variables by reference in order to be able to mutate them.)

Reading your comment, you could do something like this
for (int i = 0, bool zero = false; i < 5; i++)
{
cout << "hi" << endl;
if (zero)
{
i = 3;
zero = false;
}
}
This would start at it 0, then after doing what I want it to do, assign i the value 3, and then continue adding to it each iteration.

Related

Manipulating array's values in a certain way

So I was asked to write a function that changes array's values in a way that:
All of the values that are the smallest aren't changed
if, let's assume, the smallest number is 2 and there is no 3's and 4's then all 5's are changed for 3's etc.
for example, for an array = [2, 5, 7, 5] we would get [2, 3, 4, 3], which generalizes to getting a minimal value of an array which remains unchanged, and every other minimum (not including the first one) is changed depending on which minimum it is. On our example - 5 is the first minimum (besides 2), so it is 2 (first minimum) + 1 = 3, 7 is 2nd smallest after 2, so it is 2+2(as it is 2nd smallest).
I've come up with something like this:
int fillGaps(int arr[], size_t sz){
int min = *min_element(arr, arr+sz);
int w = 1;
for (int i = 0; i<sz; i++){
if (arr[i] == min) {continue;}
else{
int mini = *min_element(arr+i, arr+sz);
for (int j = 0; j<sz; j++){
if (arr[j] == mini){arr[j] = min+w;}
}
w++;}
}
return arr[sz-1];
}
However it works fine only for the 0th and 1st value, it doesnt affect any further items. Could anyone please help me with that?
I don't quite follow the logic of your function, so can't quite comment on that.
Here's how I interpret what needs to be done. Note that my example implementation is written to be as understandable as possible. There might be ways to make it faster.
Note that I'm also using an std::vector, to make things more readable and C++-like. You really shouldn't be passing raw pointers and sizes, that's super error prone. At the very least bundle them in a struct.
#include <algorithm>
#include <set>
#include <unordered_map>
#include <vector>
int fillGaps (std::vector<int> & data) {
// Make sure we don't have to worry about edge cases in the code below.
if (data.empty()) { return 0; }
/* The minimum number of times we need to loop over the data is two.
* First to check which values are in there, which lets us decide
* what each original value should be replaced with. Second to do the
* actual replacing.
*
* So let's trade some memory for speed and start by creating a lookup table.
* Each entry will map an existing value to its new value. Let's use the
* "define lambda and immediately invoke it" to make the scope of variables
* used to calculate all this as small as possible.
*/
auto const valueMapping = [&data] {
// Use an std::set so we get all unique values in sorted order.
std::set<int> values;
for (int e : data) { values.insert(e); }
std::unordered_map<int, int> result;
result.reserve(values.size());
// Map minimum value to itself, and increase replacement value by one for
// each subsequent value present in the data vector.
int replacement = *values.begin();
for (auto e : values) { result.emplace(e, replacement++); }
return result;
}();
// Now the actual algorithm is trivial: loop over the data and replace each
// element with its replacement value.
for (auto & e : data) { e = valueMapping.at(e); }
return data.back();
}

confused on uniqueness in permutation calculation

Working on below problem as an algorithm puzzle. Referred a few similar solutions (and post one of them below), tried and they worked. The question is, for the line "swap(num[i], num[k]);", how do we ensure we could always swap to a number which never tried before (e.g. suppose we swap 1 with 2 in current iteration of the for loop, then it is possible later we swap 2 back with 1 in next iterations of the same for loop of the same level/layer of recursive call)? I have the confusion since we pass num by reference, and it is very possible later (lower level/layer) recursive calls modify content of num, which cause numbers we already evaluated swap back. However, I tried and it works for all of my test cases. Wondering if below solution is 100% correct, or happened to pass my test cases? :)
Here are detailed problem statement and code I am debugging,
Given a collection of numbers that might contain duplicates, return all possible unique permutations.
For example,
[1,1,2] have the following unique permutations:
[1,1,2], [1,2,1], and [2,1,1]
class Solution {
public:
void recursion(vector<int> num, int i, int j, vector<vector<int> > &res) {
if (i == j-1) {
res.push_back(num);
return;
}
for (int k = i; k < j; k++) {
if (i != k && num[i] == num[k]) continue;
swap(num[i], num[k]);
recursion(num, i+1, j, res);
}
}
vector<vector<int> > permuteUnique(vector<int> &num) {
sort(num.begin(), num.end());
vector<vector<int> >res;
recursion(num, 0, num.size(), res);
return res;
}
};
thanks in advance,
Lin
As #notmyfriend said in the comments, num is actually copied each function call.
So now it boils down to:
Of all array values, select one to be the first one and place it there.
That in a loop for each value one time, and then recursively:
Of all values after the first one, select one to be the first and place it there...
...and so on, combined with a check to filter out swaps where nothing changes, ie. filter out duplicates.
If num were a real reference, it won't work anymore (at least not without additional steps).
Eg. 1 1 2 is an easy conterexample, it would give the results:
112, 121, 211, 112, 121
ie. there are duplicates despite the check (and probably there
are examples where some permutations are not generated at all, too).
About the comment:
Per default, every normal function parameter in C++ is copied
(normal = without explicit reference symbol '&' etc.).
Maybe you're thinking of C-style arrays: Essentially, what is passed there is a pointer (to the first value). The pointer is copied, but both original and copied pointer point to the same memory location.
While the purpose of std::vector is (too) to contain an array, the vector itself is a single class object (which contains a pointer to the values somewhere). A class can define itself how it should be copied (with a copy constructor).
Technically, the vector class could implement copying as pointer copying, then it would have the same effect as passing the whole vector as reference; but the C++ creators wanted to keep the copy semantics, ie. that copying a container class should make a real copy with all values duplicated.
For non-copying, there are references already...
Below you can find a solution written in Java. Sorry for not providing a solution in C++, I'm not using it for a long time. But the syntax would be similar.
Solution is using Backtracking (https://en.wikipedia.org/wiki/Backtracking)
Also I'm using hashset to check uniqueness, may be there is a solution which does not use any hashset type data structure, becase my solution is using extra memory in order to provide unique solutions.
Sample input and output;
input : [1, 1, 2]
output : [1, 1, 2]
[1, 2, 1]
[2, 1, 1]
And the solution is;
public class permutation {
public static void main(String[] args) {
permutation p = new permutation();
p.permute(new int[] { 1, 1, 2 });
}
HashSet<String> set = new HashSet<String>();
private void permute(int[] arr) {
set.clear();
this.permute(arr, 0, arr.length - 1);
}
private void permute(int[] arr, int l, int r) {
if (l == r) {
String key = Arrays.toString(arr);
if (set.contains(key))
return;
set.add(key);
System.out.println(key);
} else {
for (int i = l; i <= r; i++) {
swap(arr, l, i);
permute(arr, l + 1, r);
swap(arr, i, l);
}
}
}
private void swap(int[] arr, int l, int r) {
int tmp = arr[l];
arr[l] = arr[r];
arr[r] = tmp;
}
}

Initializing An Array with a Variable Size

I am almost done with my code except I need help on two thing. Here is my code: Code. For the function below, I am trying to make it so that I can use the input of "n" to initialize my array, myBits, instead of a constant, which is currently 5.
My Other question is right below that. I am trying to switch all of the right most bits to "true". I wrote the for loop in "/* .....*/" but it doesn't seem to be working. Right above it, I do it long ways for C(5,4) ....(myBit[0] = myBit[1]....etc...... (I am using this to find r-combinations of strings).... and it seems to work. Any help would be appreciated!!
void nCombination(const vector<string> &Vect, int n, int r){
bool myBits[5] = { false }; // everything is false now
myBits[1] = myBits[2] = myBits[3] = myBits[4] = true;
/* for(int b = n - r - 1; b = n - 1; b++){
myBits[b] = true; // I am trying to set the r rightmost bits to true
}
*/
do // start combination generator
{
printVector(Vect, myBits, n);
} while (next_permutation(myBits, myBits + n)); // change the bit pattern
}
These are called variable length arrays (or VLAs for short) and they are not a feature of standard C++. This is because we already have arrays that can change their length how ever they want: std::vector. Use that instead of an array and it will work.
Use std::vector<bool>:
std::vector<bool> myBits(n, false);
Then you have to change your while statement:
while (next_permutation(myBits.begin(), myBits.end()));
You will also have to change your printVector function to take a vector<bool>& as the second argument (you won't need the last argument, n, since a vector knows its own size by utilizing the vector::size() function).
As to your program: If you're attempting to get the combination of n things taken r at a time, you will need to write a loop that initializes the last right r bools to true instead of hard-coding the rightmost 4 entries.
int count = 1;
for (size_t i = n-1; i >= 0 && count <= r; --i, ++count)
myBits[i] = true;
Also, you should return immediately from the function if r is 0.

Optimizing a comparison over array elements with two conditions; C++ abstraction mechanisms?

My question is a follow-up to How to make this code faster (learning best practices)?, which has been put on hold (bummer). The problem is to optimize a loop over an array with floats which are tested for whether they lie within a given interval. Indices of matching elements in the array are to be stored in a provided result array.
The test includes two conditions (smaller than the upper threshold and bigger than the lower one). The obvious code for the test is if( elem <= upper && elem >= lower ) .... I observed that branching (including the implicit branch involved in the short-circuiting operator&&) is much more expensive than the second comparison. What I came up with is below. It is about 20%-40% faster than a naive implementation, more than I expected. It uses the fact that bool is an integer type. The condition test result is used as an index into two result arrays. Only one of them will contain the desired data, the other one can be discarded. This replaces program structure with data structure and computation.
I am interested in more ideas for optimization. "Technical hacks" (of the kind provided here) are welcome. I'm also interested in whether modern C++ could provide means to be faster, e.g. by enabling the compiler to create parallel running code. Think visitor pattern/functor. Computations on the single srcArr elements are almost independent, except that the order of indices in the result array depends on the order of testing the source array elements. I would loosen the requirements a little so that the order of the matching indices reported in the result array is irrelevant. Can anybody come up with a fast way?
Here is the source code of the function. A supporting main is below. gcc needs -std=c++11 because of chrono. VS 2013 express was able to compile this too (and created 40% faster code than gcc -O3).
#include <cstdlib>
#include <iostream>
#include <chrono>
using namespace std;
using namespace std::chrono;
/// Check all elements in srcArr whether they lie in
/// the interval [lower, upper]. Store the indices of
/// such elements in the array pointed to by destArr[1]
/// and return the number of matching elements found.
/// This has been highly optimized, mainly to avoid branches.
int findElemsInInterval( const float srcArr[], // contains candidates
int **const destArr, // two arrays to be filled with indices
const int arrLen, // length of each array
const float lower, const float upper // interval
)
{
// Instead of branching, use the condition
// as an index into two distinct arrays. We need to keep
// separate indices for both those arrays.
int destIndices[2];
destIndices[0] = destIndices[1] = 0;
for( int srcInd=0; srcInd<arrLen; ++srcInd )
{
// If the element is inside the interval, both conditions
// are true and therefore equal. In all other cases
// exactly one condition is true so that they are not equal.
// Matching elements' indices are therefore stored in destArr[1].
// destArr[0] is a kind of a dummy (it will incidentally contain
// indices of non-matching elements).
// This used to be (with a simple int *destArr)
// if( srcArr[srcInd] <= upper && srcArr[srcInd] >= lower) destArr[destIndex++] = srcInd;
int isInInterval = (srcArr[srcInd] <= upper) == (srcArr[srcInd] >= lower);
destArr[isInInterval][destIndices[isInInterval]++] = srcInd;
}
return destIndices[1]; // the number of elements in the results array
}
int main(int argc, char *argv[])
{
int arrLen = 1000*1000*100;
if( argc > 1 ) arrLen = atol(argv[1]);
// destArr[1] will hold the indices of elements which
// are within the interval.
int *destArr[2];
// we don't check destination boundaries, so make them
// the same length as the source.
destArr[0] = new int[arrLen];
destArr[1] = new int[arrLen];
float *srcArr = new float[arrLen];
// Create always the same numbers for comparison (don't srand).
for( int srcInd=0; srcInd<arrLen; ++srcInd ) srcArr[srcInd] = rand();
// Create an interval in the middle of the rand() spectrum
float lowerLimit = RAND_MAX/3;
float upperLimit = lowerLimit*2;
cout << "lower = " << lowerLimit << ", upper = " << upperLimit << endl;
int numInterval;
auto t1 = high_resolution_clock::now(); // measure clock time as an approximation
// Call the function a few times to get a longer run time
for( int srcInd=0; srcInd<10; ++srcInd )
numInterval = findElemsInInterval( srcArr, destArr, arrLen, lowerLimit, upperLimit );
auto t2 = high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>( t2 - t1 ).count();
cout << numInterval << " elements found in " << duration << " milliseconds. " << endl;
return 0;
}
Thinking of the integer range check optimization of turning a <= x && x < b into ((unsigned)(x-a)) < b-a, a floating point variant comes to mind:
You could try something like
const float radius = (b-a)/2;
if( fabs( x-(a+radius) ) < radius )
...
to reduce the check to one conditional.
I see about a 10% speedup from this:
int destIndex = 0; // replace destIndices
int isInInterval = (srcArr[srcInd] <= upper) == (srcArr[srcInd] >= lower);
destArr[1][destIndex] = srcInd;
destIndex += isInInterval;
Eliminate the pair of output arrays. Instead only advance the 'number written' by 1 if you want to keep the result, otherwise just keep overwriting the 'one past the end' index.
Ie, retval[destIndex]=curIndex; destIndex+= isInArray; -- better coherancy and less wasted memory.
Write two versions: one that supports a fixed array length (of say 1024 or whatever) and another that supports a runtime parameter. Use a template argumemt to remove code duplication. Assume the length is less than that constant.
Have the function return size and a RVO'd std::array<unsigned, 1024>.
Write a wrapper function that merges results (create all results, then merge them). Then throw the parrallel patterns library at the problem (so the results get computed in parrallel).
If you allow yourself vectorization using the SSE (or better, AVX) instruction set, you can perform 4/8 comparisons in a go, do this twice, 'and' the results, and retrieve the 4 results (-1 or 0). At the same time, this unrolls the loop.
// Preload the bounds
__m128 lo= _mm_set_ps(lower);
__m128 up= _mm_set_ps(upper);
int srcIndex, dstIndex= 0;
for (srcInd= 0; srcInd + 3 < arrLen; )
{
__m128 src= _mm_load_ps(&srcArr[srcInd]); // Load 4 values
__m128 tst= _mm_and_ps(_mm_cmple_ps(src, lo), _mm_cmpge_ps(src, up)); // Test
// Copy the 4 indexes with conditional incrementation
dstArr[dstIndex]= srcInd++; destIndex-= tst.m128i_i32[0];
dstArr[dstIndex]= srcInd++; destIndex-= tst.m128i_i32[1];
dstArr[dstIndex]= srcInd++; destIndex-= tst.m128i_i32[2];
dstArr[dstIndex]= srcInd++; destIndex-= tst.m128i_i32[3];
}
CAUTION: unchecked code.

Shifting elements in an array C++

I've developed a method called "rotate" to my stack object class. What I did was that if the stack contains elements: {0,2,3,4,5,6,7} I would needed to rotate the elements forwards and backwards.
Where if i need to rotate forwards by 2 elements, then we would have, {3,4,5,6,7,0,2} in the array. And if I need to rotate backwards, or -3 elements, then, looking at the original array it would be, {5,6,7,0,2,3,4}
So the method that I have developed works fine. Its just terribly ineffecient IMO. I was wondering if I could wrap the array around by using the mod operator? Or if their is useless code hangin' around that I havent realized yet, and so on.
I guess my question is, How can i simplify this method? e.g. using less code. :-)
void stack::rotate(int r)
{
int i = 0;
while ( r > 0 ) // rotate postively.
{
front.n = items[top+1].n;
for ( int j = 0; j < bottom; j++ )
{
items[j] = items[j+1];
}
items[count-1].n = front.n;
r--;
}
while ( r < 0 ) // rotate negatively.
{
if ( i == top+1 )
{
front.n = items[top+1].n;
items[top+1].n = items[count-1].n; // switch last with first
}
back.n = items[++i].n; // second element is the new back
items[i].n = front.n;
if ( i == bottom )
{
items[count-1].n = front.n; // last is first
i = 0;
r++;
continue;
}
else
{
front.n = items[++i].n;
items[i].n = back.n;
if ( i == bottom )
{
i = 0;
r++;
continue;
}
}
}
}
Instead of moving all the items in your stack, you could change the definition of 'beginning'. Have an index that represents the first item in the stack, 0 at the start, which you add to and subtract from using modular arithmetic whenever you want to rotate your stack.
Note that if you take this approach you shouldn't give users of your class access to the underlying array (not that you really should anyway...).
Well, as this is an abstraction around an array, you can store the "zero" index as a member of the abstraction, and index into the array based on this abstract notion of the first element. Roughly...
class WrappedArray
{
int length;
int first;
T *array;
T get(int index)
{
return array[(first + index) % length];
}
int rotateForwards()
{
first++;
if (first == length)
first = 0;
}
}
You've gotten a couple of reasonable answers, already, but perhaps one more won't hurt. My first reaction would be to make your stack a wrapper around an std::deque, in which case moving an element from one end to the other is cheap (O(1)).
What you are after here is a circular list.
If you insist on storing items in an array just use top offset and size for access. This approach makes inserting elements after you reached allocated size expensive though (re-allocation, copying). This can be solved by using doubly-linked list (ala std::list) and an iterator, but arbitrary access into the stack will be O(n).
The function rotate below is based on reminders (do you mean this under the 'mod' operation?)
It is also quite efficient.
// Helper function.
// Finds GCD.
// See http://en.wikipedia.org/wiki/Euclidean_algorithm#Implementations
int gcd(int a, int b) {return b == 0 ? a : gcd(b, a % b);}
// Number of assignments of elements in algo is
// equal to (items.size() + gcd(items.size(),r)).
void rotate(std::vector<int>& items, int r) {
int size = (int)items.size();
if (size <= 1) return; // nothing to do
r = (r % size + size) % size; // fits r into [0..size)
int num_cycles = gcd(size, r);
for (int first_index = 0; first_index < num_cycles; ++first_index) {
int mem = items[first_index]; // assignment of items elements
int index = (first_index + r) % size, index_prev = first_index;
while (index != first_index) {
items[index_prev] = items[index]; // assignment of items elements
index_prev = index;
index = (index + r) % size;
};
items[index_prev] = mem; // assignment of items elements
}
}
Of course if it is appropriate for you to change data structure as described in other answers, you can obtain more efficient solution.
And now, the usual "it's already in Boost" answer: There is a Boost.CircularBuffer
If for some reason you'd prefer to perform actual physical rotation of array elements, you might find several alternative solutions in "Programming Pearls" by Jon Bentley (Column 2, 2.3 The Power of Primitives). Actually a Web search for Rotating Algorithms 'Programming Pearls' will tell you everything. The literal approach you are using now has very little practical value.
If you'd prefer to try to solve it yourself, it might help to try looking at the problem differently. You see, "rotating an array" is really the same thing as "swapping two unequal parts of an array". Thinking about this problem in the latter terms might lead you to new solutions :)
For example,
Reversal Approach. Reverse the order of the elements in the entire array. Then reverse the two parts independently. You are done.
For example, let's say we want to rotate abcdefg right by 2
abcdefg -> reverse the whole -> gfedcba -> reverse the two parts -> fgabcde
P.S. Slides for that chapter of "Programming Pearls". Note that in Bentley's experiments the above algorithm proves to be quite efficient (among the three tested).
I don't understand what the variables front and back mean, and why you need .n. Anyway, this is the shortest code I know to rotate the elements of an array, which can also be found in Bentley's book.
#include <algorithm>
std::reverse(array , array + r );
std::reverse(array + r, array + size);
std::reverse(array , array + size);