I am trying to do something that logically should be possible to do. However, I am not sure how to do this within the realm of linear programming. I am using ZMPL/SCIP, but this should be readable to most.
set I := {1,2,3,4,5};
param u[I] := <1> 10, <2> 20, <3> 30, <4> 40, <5> 50;
var a;
var b;
subto bval:
b == 2;
subto works:
a == u[2];
#subto does_not_work:
# a == u[b];
I am trying to make sure that the variable a is equal to the value at the index b in u. So for example, I ensure that b == 2 and then I try to set the constraint that a == u[b], but that does not work. It complains that I am trying to index with a variable. I am able to just do a == u[2] however, which makes a equal to 20.
Is there a way to easily access u at an index specified by a variable? Thanks for any help/guidance.
EDIT: I think the consensus is that this is not possible because it no longer becomes an LP. In that case, can anyone think of another way to write this so that, depending on the value of b, I can get an associated value from the set u? This would have to avoid directly indexing it.
SOLUTION: Based on the response from Ram, I was able to try it out and found that it was definitely a viable and linear solution. Thanks, Ram! Here is sample solution code in ZMPL:
set I := {1,2,3,4,5};
param u[I] := <1> 10, <2> 20, <3> 30, <4> 40, <5> 50;
var a;
var b;
var y[I] binary;
subto bval:
b == 4;
subto only_one:
sum <i> in I : y[i] == 1;
subto trick:
b == (sum <i> in I : y[i] * i);
subto aval:
(sum <i> in I : u[i]*y[i]) == a;
Yes, you can rewrite and linearize your constraints, by introducing a few extra 0/1 variables (indicator variables). These kinds of tricks are not uncommon in Integer Programming.
Constraints In English
b can take on values from 1 through 5. b = {1..5}
and depending on b's value, the variable a should become u[b]
Indicator Variables
Let's introduce 5 Y variables - Y1..Y5 (one for each possible value of b)
Only one of them can be true at any given time.
Y1 + Y2 + Y3 + Y4 + Y5 = 1
All Y's are binary {0,1}
Here's the trick. We introduce one linear constraint to ensure that the corresponding Y variable will take on value 1, only when b is that value.
b - 1xY1 - 2xY2 - 3xY3 - 4xY4 - 5xY5 = 0
(For example, if b is 3, the constraint above will force Y3 to be 1.)
Now, we want a to take on the value u[b].
a = u[1]xY1 + u[2]xY2 + u[3]xY3 + u[4]xY4 + u[5]xY5
Since u[ 1] ...u[5] are constants known beforehand, the constraint above is also linear.
Here is one reference on these kinds of IF-THEN conditions in Integer Programming. Many of these tricks involve the Big-M, though we didn't need it in this case.
Hope that helps you move forward.
Related
I got the js code below from an archive of hackers delight (view the source)
The code takes in a value (such as 7) and spits out a magic number to multiply with. Then you bitshift to get the results. I don't remember assembly or any math so I'm sure I'm wrong but I can't find the reason why I'm wrong
From my understanding you could get a magic number by writing ceil(1/divide * 1<<32) (or <<64 for 64bit values, but you'd need bigger ints). If you multiple an integer with imul you'd get the result in one register and the remainder in another. The result register is magically the correct result of a division with this magic number from my formula
I wrote some C++ code to show what I mean. However I only tested with the values below. It seems correct. The JS code has a loop and more and I was wondering, why? Am I missing something? What values can I use to get an incorrect result that the JS code would get correctly? I'm not very good at math so I didn't understand any of the comments
#include <cstdio>
#include <cassert>
int main(int argc, char *argv[])
{
auto test_divisor = 7;
auto test_value = 43;
auto a = test_value*test_divisor;
auto b = a-1; //One less test
auto magic = (1ULL<<32)/test_divisor;
if (((1ULL<<32)%test_divisor) != 0) {
magic++; //Round up
}
auto answer1 = (a*magic) >> 32;
auto answer2 = (b*magic) >> 32;
assert(answer1 == test_value);
assert(answer2 == test_value-1);
printf("%lld %lld\n", answer1, answer2);
}
JS code from hackers delight
var two31 = 0x80000000
var two32 = 0x100000000
function magic_signed(d) { with(Math) {
if (d >= two31) d = d - two32// Treat large positive as short for negative.
var ad = abs(d)
var t = two31 + (d >>> 31)
var anc = t - 1 - t%ad // Absolute value of nc.
var p = 31 // Init p.
var q1 = floor(two31/anc) // Init q1 = 2**p/|nc|.
var r1 = two31 - q1*anc // Init r1 = rem(2**p, |nc|).
var q2 = floor(two31/ad) // Init q2 = 2**p/|d|.
var r2 = two31 - q2*ad // Init r2 = rem(2**p, |d|).
do {
p = p + 1;
q1 = 2*q1; // Update q1 = 2**p/|nc|.
r1 = 2*r1; // Update r1 = rem(2**p, |nc|.
if (r1 >= anc) { // (Must be an unsigned
q1 = q1 + 1; // comparison here).
r1 = r1 - anc;}
q2 = 2*q2; // Update q2 = 2**p/|d|.
r2 = 2*r2; // Update r2 = rem(2**p, |d|.
if (r2 >= ad) { // (Must be an unsigned
q2 = q2 + 1; // comparison here).
r2 = r2 - ad;}
var delta = ad - r2;
} while (q1 < delta || (q1 == delta && r1 == 0))
var mag = q2 + 1
if (d < 0) mag = two32 - mag // Magic number and
shift = p - 32 // shift amount to return.
return mag
}}
In the C CODE:
auto magic = (1ULL<<32)/test_divisor;
We get Integer Value in magic because both (1ULL<<32) & test_divisor are Integers.
The Algorithms requires incrementing magic on certain conditions, which is the next conditional statement.
Now, multiplication also gives Integers:
auto answer1 = (a*magic) >> 32;
auto answer2 = (b*magic) >> 32;
C CODE is DONE !
In the JS CODE:
All Variables are var ; no Data types !
No Integer Division ; No Integer Multiplication !
Bitwise Operations are not easy and not suitable to use in this Algorithm.
Numeric Data is via Number & BigInt which are not like "C Int" or "C Unsigned Long Long".
Hence the Algorithm is using loops to Iteratively add and compare whether "Division & Multiplication" has occurred to within the nearest Integer.
Both versions try to Implement the same Algorithm ; Both "should" give same answer, but JS Version is "buggy" & non-standard.
While there are many Issues with the JS version, I will highlight only 3:
(1) In the loop, while trying to get the best Power of 2, we have these two statements :
p = p + 1;
q1 = 2*q1; // Update q1 = 2**p/|nc|.
It is basically incrementing a counter & multiplying a number by 2, which is a left shift in C++.
The C++ version will not require this rigmarole.
(2) The while Condition has 2 Equality comparisons on RHS of || :
while (q1 < delta || (q1 == delta && r1 == 0))
But both these will be false in floating Point Calculations [[ eg check "Math.sqrt(2)*Math.sqrt(0.5) == 1" : even though this must be true, it will almost always be false ]] hence the while Condition is basically the LHS of || , because RHS will always be false.
(3) The JS version returns only one variable mag but user is supposed to get (& use) even variable shift which is given by global variable access. Inconsistent & BAD !
Comparing , we see that the C Version is more Standard, but Point is to not use auto but use int64_t with known number of bits.
First I think ceil(1/divide * 1<<32) can, depending on the divide, have cases where the result is off by one. So you don't need a loop but sometimes you need a corrective factor.
Secondly the JS code seems to allow for other shifts than 32: shift = p - 32 // shift amount to return. But then it never returns that. So not sure what is going on there.
Why not implement the JS code in C++ as well and then run a loop over all int32_t and see if they give the same result? That shouldn't take too long.
And when you find a d where they differ you can then test a / d for all int32_t a using both magic numbers and compare a / d, a * m_ceil and a * m_js.
I'm trying to use Z3 (with C++ API) to check if lots of variable configurations satisfy my constraints, but I'm having big performance issues.
I'm looking for advice about which logic or parameter setting I might be able to use to improve the runtime, or hints about how I could try and feed the problem to Z3 in a different way.
Short description of what I'm doing and how I'm doing it:
//_______________Pseudocode and example_______________
context ctx()
solver s(ctx)
// All my variables are finite domain, maybe some 20 values at most, but usually less.
// They can only be ints, bools, or enums.
// There are not that many variables, maybe 10 or 20 for now.
//
// Since I need to be able to solve constraints of the type (e == f), where
// e and f are two different enum variables, all my
// enum types are actually contained in only one enumeration_sort(), populated
// with all the different values.
sort enum_sort = {"green", "red", "yellow", "blue", "null"}
expr x = ctx.int_const("x")
expr y = ctx.int_const("y")
expr b = ctx.bool_const("b")
expr e = ctx.constant("e", enum_sort)
expr f = ctx.constant("f", enum_sort)
// now I assert the finite domains, for each variable
// enum_value(s) is a helper function, that returns the matching enum expression
//
// Let's say that these are the domains:
//
// int x is from {1, 3, 4, 7, 8}
// int y is from {1, 2, 3, 4}
// bool b is from {0, 1}
// enum e is from {"green", "red", "yellow"}
// enum f is from {"red", "blue", "null"}
s.add(x == 1 || x == 3 || x == 3 || x == 7 || x == 8)
s.add(y == 1 || y == 2 || y == 3 || y == 4)
s.add(b == 0 || b == 1)
s.add(e == enum_value("green") || e == enum_value("red") || enum_value("yellow"))
s.add(f == enum_value("red") || f == enum_value("blue") || enum_value("null"))
// now I add in my constraints. There are also about 10 or 20 of them,
// and each one is pretty short
s.add(b => (x + y >= 5))
s.add((x > 1) => (e != f))
s.add((y == 4 && x == 1) || b)
// setup of the solver is now done. Here I start to query different combinations
// of values, and ask the solver if they are "sat" or "unsat"
// some values are left empty, because I don't care about them
expr_vector vec1 = {x == 1, y == 3, b == 1, e == "red"}
print(s.check(vec1))
expr_vector vec2 = {x == 4, e == "green", f == "null"}
print(s.check(vec2))
....
// I want to answer many such queries.
Of course, in my case this isn't hardcoded, but I read and parse the constraints, variables and their domains from files, then feed the info to Z3.
But it's slow.
Even for something like ten thousand queries, my program is already running over 10s. All of this is inside s.check(). Is it possible to make it run faster?
Hopefully it is, because what I'm asking of the solver doesn't look like it's overly difficult.
No quantifiers, finite domain, no functions, everything is a whole number or an enum, domains are small, the values of the numbers are small, there's only simple arithmetic, constraints are short, etc.
If I try to use parameters for parallel processing, or set the logic to "QF_FD", the runtime doesn't change at all.
Thanks in advance for any advice.
Is it always slow? Or does it get progressively slower as you query for more and more configurations using the same solver?
If it's the former, then your problem is just too hard and this is the price to pay. I don't see anything obviously wrong in what you've shown; though you should never use booleans as integers. (Just looking at your b variable in there. Stick to booleans as booleans, and integers as integers, and unless you really have to, don't mix the two together. See this answer for some further elaboration on this point: Why is Z3 slow for tiny search space?)
If it's the latter, you might want to create a solver from scratch for each query to clean-up all the extra stuff the solver created. While additional lemmas always help, they could also hurt performance if the solver cannot make good use of them in subsequent queries. And if you follow this path, then you can simply "parallelize" the problem yourself in your C++ program; i.e., create many threads and call the solver separately for each problem, taking advantage of many-cores your computer no doubt has and OS-level multi-tasking.
Admittedly, this is very general advice and may not apply directly to your situation. But, without a particular "running" example that we can see and inspect, it's hard to be any more specific than this.
Some Ideas:
1. Replace x == 1 || x == 3 || x == 3 || x == 7 || x == 8 with (1 <= x && x <= 8) && (x <= 1 || (3 <= x) && (x <= 4 || 7 <= x). Similar change with y.
rationale: the solver for linear arithmetic now knows that x is always confined in the interval [1,8], this can be useful information for other linear equalities/inequalities; it may be useful to also learn the trivial mutual exclusion constraints not(x <= 1) || not(3 <= x) and not(x <= 4) || not(7 <= x); there are now exactly 3 boolean assignments that cover your original 5 cases, this makes the reasoning of the linear arithmetic solver more cost-efficient because each invocation deals with a larger chunk of the search space. (Furthermore, it is more likely that clauses learned from conflicts are going to be useful with subsequent calls to the solver)
(Your queries may also contain set of values rather than specific assignments of values; this may allow one to prune some unsatisfiable ranges of values with fewer queries)
2. Just like #alias mentioned, Boolean variables ought to be Booleans and not 0/1 Integer variables. The example you provided is a bit confusing, b is declared as a bool const but then you state b == 0 || b == 1
3. I am not familiar with the enum_sort of z3, meaning that I don't know how it is internally encoded and what solving techniques are applied to deal with it. Therefore, I am not sure whether the solver may try to generate trivially inconsistent truth-assignments in which e == enum_value("green") e e == enum_value("red") are both assigned to true at the same time. This might be worth a bit of investigation. For instance, another possibility could be to declare e and f as Int and give them an appropriate interval domain (as contiguous as possible) with the same approach shown in 1., that will be interpreted by your software as a list of enum values. This should remove a number of Boolean assignments from the search space, make conflict clauses more effective and possibly speed-up the search.
4. Given the small number of problem variables, values and constraints, I would suggest you to try to encode everything using just the Bit-Vector theory and nothing else (using small-but-big-enough domains). If you then configure the solver to encode Bit-Vectors eagerly, then everything is bit-blasted into SAT, and z3 should only use Boolean Constraint Propagation for satisfiability, which is the cheapest technique.
This might be an X Y problem, why are you performing thousands of queries, what are you trying to achieve? Are you trying to explore all possible combination of values? Are you trying to perform model counting?
Consider two vectors, A and B, of size n, 7 <= n <= 23. Both A and B consists of -1s, 0s and 1s only.
I need a fast algorithm which computes the inner product of A and B.
So far I've thought of storing the signs and values in separate uint32_ts using the following encoding:
sign 0, value 0 → 0
sign 0, value 1 → 1
sign 1, value 1 → -1.
The C++ implementation I've thought of looks like the following:
struct ternary_vector {
uint32_t sign, value;
};
int inner_product(const ternary_vector & a, const ternary_vector & b) {
uint32_t psign = a.sign ^ b.sign;
uint32_t pvalue = a.value & b.value;
psign &= pvalue;
pvalue ^= psign;
return __builtin_popcount(pvalue) - __builtin_popcount(psign);
}
This works reasonably well, but I'm not sure whether it is possible to do it better. Any comment on the matter is highly appreciated.
I like having the 2 uint32_t, but I think your actual calculation is a bit wasteful
Just a few minor points:
I'm not sure about the reference (getting a and b by const &) - this adds a level of indirection compared to putting them on the stack. When the code is this small (a couple of clocks maybe) this is significant. Try passing by value and see what you get
__builtin_popcount can be, unfortunately, very inefficient. I've used it myself, but found that even a very basic implementation I wrote was far faster than this. However - this is dependent on the platform.
Basically, if the platform has a hardware popcount implementation, __builtin_popcount uses it. If not - it uses a very inefficient replacement.
The one serious problem here is the reuse of the psign and pvalue variables for the positive and negative vectors. You are doing neither your compiler nor yourself any favors by obfuscating your code in this way.
Would it be possible for you to encode your ternary state in a std::bitset<2> and define the product in terms of and? For example, if your ternary types are:
1 = P = (1, 1)
0 = Z = (0, 0)
-1 = M = (1, 0) or (0, 1)
I believe you could define their product as:
1 * 1 = 1 => P * P = P => (1, 1) & (1, 1) = (1, 1) = P
1 * 0 = 0 => P * Z = Z => (1, 1) & (0, 0) = (0, 0) = Z
1 * -1 = -1 => P * M = M => (1, 1) & (1, 0) = (1, 0) = M
Then the inner product could start by taking the and of the bits of the elements and... I am working on how to add them together.
Edit:
My foolish suggestion did not consider that (-1)(-1) = 1, which cannot be handled by the representation I proposed. Thanks to #user92382 for bringing this up.
Depending on your architecture, you may want to optimize away the temporary bit vectors -- e.g. if your code is going to be compiled to FPGA, or laid out to an ASIC, then a sequence of logical operations will be better in terms of speed/energy/area than storing and reading/writing to two big buffers.
In this case, you can do:
int inner_product(const ternary_vector & a, const ternary_vector & b) {
return __builtin_popcount( a.value & b.value & ~(a.sign ^ b.sign))
- __builtin_popcount( a.value & b.value & (a.sign ^ b.sign));
}
This will lay out very well -- the (a.value & b.value & ... ) can enable/disable an XOR gate, whose output splits into two signed accumulators, with the first pathway NOTed before accumulation.
I have the following function:
int mult(int y, int z)
{
if (z == 0)
return 0;
else if (z % 2 == 1)
return mult(2 * y, z / 2) + y;
else
return mult(2 * y, z / 2);
}
What I need to do is prove its correctness by induction. Now the trouble I'm having is that even though I know it works since I ran it I can't follow each individual step.
What is confusing me is that y only shows up as an argument and in no place does it show up in a return except in the recursive part, and yet the function actually returns y as the answer.
How does this happen? I need to be able to follow everything that happens so that I can do the iterations of it for the proof.
Since this is obviously a homework question, I recommend you do what the assinment was likely meant fot you to do. Trace through the code.
1) give a starting value for y and z.
2) either on paper or in a debugger, trace what happens when you call the function.
3) repeat step 2 with your current y/z values until program completion.
#include <iostream>
using namespace std;
int mult(int y, int z)
{
if(z==0) {
cout<<"z is null! - y:"<<y<<" z: "<<z<<endl;
return 0;
}
else if (z%2==1)
{
cout<<"z is odd! - y:"<<y<<" z: "<<z<<endl;
// make z even
return mult(2*y,z/2)+y;
}
else
{
cout<<"z is even! - y:"<<y<<" z: "<<z<<endl;
return mult(2*y,z/2);
}
}
int main() {
cout<<"result: "<<mult(3,13)<<endl;
}
Output:
z is odd! - y:3 z: 13
z is even! - y:6 z: 6
z is odd! - y:12 z: 3
z is odd! - y:24 z: 1
z is null! - y:48 z: 0
result: 39
How it works for 3 and 13:
There's a switch for even and odd numbers (see comment in code).
When z is null, the recursion "starts to return to the initial call". If the number z is odd it adds y to the returned value of the recursive call, if it's even it justs returns the value from the recursive call.
odd: return 0 + 24
odd: return 24 + 12
even: return 36
odd: return 36 + 3
step-by-step analisis
final result: 100
mult(10, 10)
{
makes 100
mult(20, 5)
{
makes 100
mult(40, 2) + 20
{
makes 80
mult(80, 1)
{
makes 80
mult(160, 0) + 80
{
return 0;
}
}
}
}
}
Note: If this is homework, tag it as such.
So, we basically got three recursive cases. To make it all clearer, I'd rewrite the C-code into some functional pseudo-code. Replace mult with an intuitive operator sign and figure out descriptive explanations of low-level expressions like (z%2==1).
You'll come up with something like
a ** b =
| b is 0 -> 0
| b is even -> 2a ** (b/2)
| b is odd -> 2a ** (b/2) + a
Do you get the point now?
One approach would be to translate each line into "English". My translation would be something like this:
if z is zero, return zero
if z is odd, return mult(y*2, z/2) + y
if z is even, return mult(y*2, z/2)
The general pattern is to recursively call mult with the first parameter doubling, and the second parameter halving.
Note that here you're calling mult with z/2, but its arguments are integers, so if your function continues to recurse, the 2nd parameter will halve each time until it gets down to 1, and then finally 1/2 which rounds down to 0 - at which point recursion will stop because z==0.
With those clues, you should be able to understand how this algorithm works.
Demonstrations by induction are based on proving that the result is valid for the first value, and that if the principle is correct for a generic value N, it is provable that it holds for N+1.
To simplify, you can start by proving that it works for z in { 0, 1, 2 } which should be trivial with a manual test. Then to demonstrate the induction step, you start with a generic z=N, and prove that if mult( y, N ) is a valid result, then mult( y, N+1 ) is also a valid result in terms of the previous one. Since there are different branches for even and odd numbers, you will have to prove the induction step for both even and odd N numbers.
ya = ya
a = an even number
b = the next odd number (in other words a + 1)
So, if you want the equation above in terms of only even numbers (an 'a') when given an odd number (a 'b') you can do the following:
yb = y(a+1) = y*a + y
Now confuse everyone by writing 'a' as 2*(z/2).
y*a becomes (2*y)*(z/2)
y*b becomes ((2*y)*(z/2))+y
Since 'z' appears in the formula for both even and odd numbers, we want to think that the code is telling us that (2*y)*(z/2) = (2*y)*(z/2) + y which is obviously MADNESS!
The reason is that we have snuck in the fact that z/2 is an integer and so z can never be odd. The compiler will not let us assign z/2 to an integer when z is odd. If we try to make 'z' odd, the integer we will really be using is (z-1)/2 instead of z/2.
To get around this, we have to test to see if z/2 is odd and pick our formula based on that (eg. either ya or yb in terms of 'a').
In mult(y,z) both 'y' and 'z' are both integers. Using the symbols above mult(2*y,b/2) becomes mult(2*y,a/2) because b/2 will be truncated to a/2 by the compiler.
Since we are always going to get an 'a' as a parameter to 'mult', even when we send a 'b', we have to make sure we are only using formulas that require 'a'. So, instead of yb we use ya+1 as described above.
b/2 = a/2 + 1/2 but 1/2 cannot be represented as part of an int.
Not really an answer, but more of a suggestion.
You may want to reduce the recursion call from 2 to one:
int mult(int y, int z)
{
int result = 0;
if (z == 0)
return result;
result = mult(2 * y, z / 2); // Common between "then" and "else"
if ((z % 2) == 1)
{
result += y;
}
return result;
}
This could be simplified once more by observing the rule "one exit point only":
int mult(int y, int z)
{
int result = 0;
if (z != 0)
{
result = mult(2 * y, z / 2); // Common between "then" and "else"
if ((z % 2) == 1)
{
result += y;
}
}
return result;
}
Although many compilers will perform this simplification automatically, debugging is usually easier when the code is simplified. The debugger will match the code when single-stepping.
Sometimes simplifying will add clarity. Also, adding comments will help you figure out what you are doing as well as the next person who reads the code.
I have two simple while loops in my program that I feel ought to be math equations, but I'm struggling to convert them:
float a = someValue;
int b = someOtherValue;
int c = 0;
while (a <= -b / 2) {
c--;
a += b;
}
while (a >= b / 2) {
c++;
a -= b;
}
This code works as-is, but I feel it could be simplified into math equations. The idea here being that this code is taking an offset (someValue) and adjusting a coordinate (c) to minimize the distance from the center of a tile (of size someOtherValue). Any help would be appreciated.
It can be proved that the following is correct:
c = floor((a+b/2)/b)
a = a - c*b
Note that floor means round down, towards negative infinity: not towards 0. (E.g. floor(-3.1)=-4. The floor() library functions will do this; just be sure not to just cast to int, which will usually round towards 0 instead.)
Presumably b is strictly positive, because otherwise neither loop will never terminate: adding b will not make a larger and subtracting b will not make a smaller. With that assumption, we can prove that the above code works. (And paranoidgeek's code is also almost correct, except that it uses a cast to int instead of floor.)
Clever way of proving it:
The code adds or subtracts multiples of b from a until a is in [-b/2,b/2), which you can view as adding or subtracting integers from a/b until a/b is in [-1/2,1/2), i.e. until (a/b+1/2) (call it x) is in [0,1). As you are only changing it by integers, the value of x does not change mod 1, i.e. it goes to its remainder mod 1, which is x-floor(x). So the effective number of subtractions you make (which is c) is floor(x).
Tedious way of proving it:
At the end of the first loop, the value of c is the negative of the number of times the loop runs, i.e.:
0 if: a > -b/2 <=> a+b/2 > 0
-1 if: -b/2 ≥ a > -3b/2 <=> 0 ≥ a+b/2 > -b <=> 0 ≥ x > -1
-2 if: -3b/2 ≥ a > -5b/2 <=> -b ≥ a+b/2 > -2b <=> -1 ≥ x > -2 etc.,
where x = (a+b/2)/b, so c is: 0 if x>0 and "ceiling(x)-1" otherwise. If the first loop ran at all, then it was ≤ -b/2 just before the last time the loop was executed, so it is ≤ -b/2+b now, i.e. ≤ b/2. According as whether it is exactly b/2 or not (i.e., whether x when you started was exactly a non-positive integer or not), the second loop runs exactly 1 time or 0, and c is either ceiling(x) or ceiling(x)-1. So that solves it for the case when the first loop did run.
If the first loop didn't run, then the value of c at the end of the second loop is:
0 if: a < b/2 <=> a-b/2 < 0
1 if: b/2 ≤ a < 3b/2 <=> 0 ≤ a-b/2 < b <=> 0 ≤ y < 1
2 if: 3b/2 ≤ a < 5b/2 <=> b ≤ a-b/2 < 2b <=> 1 ≤ y < 2, etc.,
where y = (a-b/2)/b, so c is: 0 if y<0 and 1+floor(y) otherwise. [And a now is certainly < b/2 and ≥ -b/2.]
So you can write an expression for c as:
x = (a+b/2)/b
y = (a-b/2)/b
c = (x≤0)*(ceiling(x) - 1 + (x is integer))
+(y≥0)*(1 + floor(y))
Of course, next you notice that (ceiling(x)-1+(x is integer)) is same as floor(x+1)-1 which is floor(x), and that y is actually x-1, so (1+floor(y))=floor(x), and as for the conditionals:
when x≤0, it cannot be that (y≥0), so c is just the first term which is floor(x),
when 0 < x < 1, neither of the conditions holds, so c is 0,
when 1 ≤ x, then only 0≤y, so c is just the second term which is floor(x) again.
So c = floor(x) in all cases.
c = (int)((a - (b / 2)) / b + 1);
a -= c * b;
Test case at http://pastebin.com/m1034e639
I think you want something like this:
c = ((int) a + b / 2 * sign(a)) / b
That should match your loops except for certain cases where b is odd because the range from -b/2 to b/2 is smaller than b when b is odd.
Assuming b is positive, abs(c) = floor((abs(a) - b/2) / b). Then, apply sign of a to c.