Explanation for template signum - c++

I came across this template of C++
template <typename T> int sgn(T val) {
return (T(0) < val) - (val < T(0));
}
And I have to admit I don't really get it.
If I try to do a numeric application, let's say -1:
(0<(-1))-(-1 < 0) => False - True I get a subtraction of Bool.
Is that how it should work? Can someone explain the different steps the compiler will do?

It will return-1 if negative +1 if possitive 0 if 0
lets say -1:
(T(0) < val) - (val < T(0))
0<-1 false or 0
-
-1 < 0 true or 1
0 - 1 = -1
lets say 0
(T(0) < val) - (val < T(0))
0<0 false or 0
-
0 < 0 false or 0
0 - 0 = 0
lets say 1:
(T(0) < val) - (val < T(0))
0<1 true or 1
-
1 < 0 false or 0
1 - 0 = 1

There are implicit conversions happening there: True=>1 and False=>0.
You need to check both conditions to see if the value could be equal to zero - that's how signum is defined. If your interested in checking only greater or lower than 0, you could get away with a single comparison.
Nevertheless, having your example with -1 and the posted template, in result you get:
return False - True; => return 0 - 1; => return -1;

false and true would be converted to 0 and 1. So depending if one or both expressions evaluate to false, you get -1, 0, 1 results. That's a canon definition of signum function.
PS.Thats not an effective template, for better work there should be three specializations.
This question features answer that explains those:
Is there a standard sign function (signum, sgn) in C/C++?

Related

Determine if an adjacency matrix has a cycle and then output that cycle

so I have 2 functions :
UPDATED
unordered_map<int, bool> visited2;
vector<vector<int>> elements2D;
bool DFSDetectCycle(int vertex){
s.push(vertex);
while(!s.empty()){
int np_vertex = s.top();
s.pop();
if (visited2[np_vertex] == true){
return true;
}
visited2[np_vertex] = true;
for (int i = 0; i<elements2D.size(); i++){
if(elements2D[np_vertex][i] != 0){
if(DFSDetectCycle(i)){
return true;
}
}
}
}
return false;
}
bool hasCycle(vector<vector<int>> v){
if (v.empty()){
return false;
}
for (int i = 0; i<v.size(); i++){
if (!visited2[i]){
if(DFSDetectCycle(i)){
return true;
}
}
}
return false;
}
And in my main function I call it like this:
if (hasCycle(elements2D)){
for (int i = 0; i<elements2D.size(); i++){
if (!visited2[i]){
DFSDetectCycle(i);
}
}
}else{
cout << "No cycles." << endl;
}
So basically, the input is going to look like this:
g++ -o GraphProcessor.o GraphProcessor.cpp -std=c++11
./GraphProcessor.o graph1.txt
And the output should look like this:
Connected components:
{0,1,2,4,7}
{3}
{5,6}
A cycle: 0 1 4 2
But my output looks like this:
Connected components:
{0,1,4,2,7}
{3}
{5,6}
No cycles.
graph1.txt looks like this:
0 2 6 0 0 0 0 3
2 0 0 0 4 0 0 1
6 0 0 0 3 0 0 2
0 0 0 0 0 0 0 0
0 4 3 0 0 0 0 0
0 0 0 0 0 0 7 0
0 0 0 0 0 7 0 0
3 1 2 0 0 0 0 0
Do not worry about the connected components part, that is not my problem right now. My problem is that my code is not properly detecting cycles in the graph and is not outputting them properly either. It seems as if my hasCycle() function is constantly giving a false statement, but I am not really sure why. elements2D is my matrix I am using, since it was read from a file, I needed somewhere to store it. For my visited2 function, I use an unordered_map in order to keep boolean values on whether or not I have visited the vertices or not. I know that if I have visited a vertex again, then I have a cycle. But I am not sure how to modify my algorithm in order to obtain a result like that.
Thanks again for any help.
You are calling DFSDetectCycle recursively without using it's return value. I suggest you check if recursive call return true, and return it is so.
You are specifically skipping the cycles because you filter the recursive calls with if(elements2D[np_vertex][i] != 0 && !visited2[i]) - which means you will not go into already visit vertexes, skipping the cycles.
In addition, there are no prints in the code that would yield the required output...
You should remove visited[i] checking from if(elements2D[np_vertex][i] != 0 && !visited2[i]), because if you already visited i, then removing this checking can detect it. And if it finds cycle, you should return it immediately.
if(elements2D[np_vertex][i] != 0){
if (DFSDetectCycle(i)) return true;
}
Another issue is if there exist edges 0->1 and 1->0, then they make a cycle. You need more work to find largest cycle.

Constraints - linear programming- CPLEX

How do I write such constraints in CPLEX (linear-programming) ?
forall(p in P, x in X, y in Y)
if ((remx[p,x] <= 0) OR (remy[p,y] <= 0)) then
pbl[p,x,y] == 0 // MUST be 0
else
pbl[p,x,y] == 1 OR == 0 // can be 0 or 1
where pbl is a decision variable (matrix), remx and remy is a normal matrix variable and p,x,y are indices.
I can not use if-then
Thanks,
I believe this cannot be done using (continuous) linear programming, but using mixed-integer programming we can use binary variables.
One way to attack this is using a bunch of inequalities, something like:
remx[p,x] <= 0 + bx[p,x]*M
remx[p,x] >= 0 - (1-bx[p,x])*M
remy[p,y] <= 0 + by[p,y]*M
remy[p,y] >= 0 - (1-by[p,y])*M
pbl[p,x,y] >= bx[p,x]+by[p,y]-1
pbl[p,x,y] <= bx[p,x]
pbl[p,x,y] <= bx[p,x]
bx[p,x],bx[p,x] in {0,1}
where M is indicating a sufficiently large number (they form a bound on remx and remy). Alternatively you can use the indicator constraints in Cplex to model implications:
bx[p,x]=0 => remx[p,x] <= 0
bx[p,x]=1 => remx[p,x] >= 0
by[p,y]=0 => remy[p,y] <= 0
by[p,y]=1 => remy[p,y] >= 0
pbl[p,x,y] = 1 => bx[p,x]+by[p,y] = 2
pbl[p,x,y] = 0 => bx[p,x]+by[p,y] <= 1
(Note: the question has changed, so these fragments are no longer 100% correct).

conway game error with 2d array manipulation

So I'm working on the life game, and so far I have come up with this http://ideone.com/QG4tsS I'm not sure exactly if I am on the right track or not. Basically I have a function putting out random values to try and test my code. But nothing seems to happen. I suspect my problem lies with the following code
int sum = 0;
for (int k = (i - 1); k <= (i + 1); k++) {
for (int l = (j - 1); l <= (j + 1); l++) {
sum += currentGen[k][l];
}
}
return sum;
So my result gives me a 2d array with all 0's but shouldn't I start to see some changes and patterns starting to form? I get one 1 and the rest are 0.
Output
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 1
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
I provide this answer based on the code you posted at http://ideone.com/QG4tsS . You really should consider adding that code to your original question, so that future folks who find this on StackOverflow have the full context.
Your RandomCells function only sets cells to 1 if they meet the RANDOM threshold. It doesn't clear them to 0 otherwise. Once you fix that, you'll be all set. ie.
void RandomCells(int currentGen[][CELLY]) {
for (int i = 0; i < CELLX; i++) {
for (int j = 0; j < CELLY; j++) {
if (rand() % 100 + 1 < RANDOM) {
currentGen[i][j] = 1;
} else
{
currentGen[i][j] = 0;
}
}
}
}
Without that else clause, I was seeing initial generations that looked like this:
0 0 4196155 1
1813657216 1 4197653 0
-870503576 1 4197584 1
Clearly, most of those cells were non-zero, and so Conway's Life algorithm would map them to 0 in the next generation because of "crowding".
The reason currentGen was filled with such 'random' values is that it was allocated as an automatic variable to main. Automatic variables do not get initialized to any particular value. You need to initialize them yourself. You can do that by modifying your algorithm (as I did above), or by adding an explicit bit of code to initialize the structure.
This differs from file-scope variables, which C and C++ define as initialized-to-zero on program start if they don't have initializers or default constructors. (Pedants will point out that even that has caveats.)
Once you make the required fixes, to truly see Conway's Life, you'll need to set CELLX and CELLY to larger values...

Partitioning arrays by index

I am fairly new to C++, and am struggling through a problem that seems to have a solid solution but I just can't seem to find it. I have a contiguous array of ints starting at zero:
int i[6] = { 0, 1, 2, 3, 4, 5 }; // this is actually from an iterator
I would like to partition the array into groups of three. The design is to have two methods, j and k, such that given an i they will return the other two elements from the same group of three. For example:
i j(i) k(i)
0 1 2
1 0 2
2 0 1
3 4 5
4 3 5
5 3 4
The solution seems to involve summing the i with its value mod three and either plus or minus one, but I can't quite seem to work out the logic.
This should work:
int d = i % 3;
int j = i - d + ( d == 0 );
int k = i - d + 2 - ( d == 2 );
or following statement for k could be more readable:
int k = i - d + ( d == 2 ? 1 : 2 );
This should do it:
int j(int i)
{
int div = i / 3;
if (i%3 != 0)
return 3*div;
else
return 3*div+1;
}
int k(int i)
{
int div = i / 3;
if (i%3 != 2)
return 3*div+2;
else
return 3*div+1;
}
Test.
If you want shorter functions:
int j(int i)
{
return i/3*3 + (i%3 ? 0 : 1);
}
int k(int i)
{
return i/3*3 + (i%3-2 ? 2 : 1);
}
Well, first, notice that
j(i) == j(3+i) == j(6+i) == j(9+i) == ...
k(i) == k(3+i) == k(6+i) == k(9+i) == ...
In other words, you only need to find a formula for
j(i), i = 0, 1, 2
k(i), i = 0, 1, 2
and then for the rest of the cases simply plug in i mod 3.
From there, you'll have trouble finding a simple formula because your "rotation" isn't standard. Instead of
i j(i) k(i)
0 1 2
1 2 0
2 0 1
for which the formula would have been
j(i) = (i + 1) % 3
k(i) = (i + 2) % 3
you have
i j(i) k(i)
0 1 2
1 0 1
2 0 2
for which the only formula I can think of at the moment is
j(i) = (i == 0 ? 1 : 0)
k(i) = (i == 1 ? 1 : 2)
If the values of your array (let's call it arr, not i in order to avoid confusion with the index i) do not coincide with their respective index, you have to perform a reverse lookup to figure out their index first. I propose using an std::map<int,size_t> or an std::unordered_map<int,size_t>.
That structure reflects the inverse of arr and you can extra the index for a particular value with its subscript operator or the at member function. From then, you can operate purely on the indices, and use modulo (%) to access the previous and the next element as suggested in the other answers.

Bitwise operation to get 1 if both are 0

I'd need to perform a bitwise operation (or a serie) so that:
0 1 = 0
1 1 = 1
1 0 = 0
so far AND (&) works fine but I also need that
0 0 = 1
and here AND (&) is not the correct one.
I'm using it in a jquery grep function that reads:
jQuery.grep(json, function (e, index) {
return (e.value & (onoff << 3)) != 0;
});
where onoff could be either 1 or 0 and e.value is a representation of a 4 bits string (i.e. could be "1001"). In this above example I'm testing first bit on the left (<< 3).
Can this be done with a serie of AND, OR, XOR?
This is just XNOR(a, b), which is equal to NOT(XOR(a, b)), i.e. exclusive OR with the output inverted. In C and C-like languages this would be:
!(a ^ b)
or in your specific case:
return !((e.value >> 3) ^ onoff);
Having said that, you could just test for equality:
return (e.value >> 3) == onoff;
This looks roughly like XOR which has the following results table:
0 0 = 0
0 1 = 1
1 0 = 1
1 1 = 0
Now you want to have the opposite, meaning that you want 1 if both inputs are the same value. And this leads us to NOT XOR
0 0 = 1
0 1 = 0
1 0 = 0
1 1 = 1