Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ARITH] Fix intersect of modular set #2726

Closed
wants to merge 2 commits into from

Conversation

merrymercy
Copy link
Member

fix todo in #2668

cc @tqchen

src/arithmetic/modular_set.cc Outdated Show resolved Hide resolved
@tqchen tqchen added the status: need update need update based on feedbacks label Mar 5, 2019
@merrymercy merrymercy force-pushed the modular-set branch 2 times, most recently from 592ac61 to c064d75 Compare March 19, 2019 03:05
@merrymercy merrymercy added status: need review and removed status: need update need update based on feedbacks labels Mar 19, 2019
@@ -32,10 +32,27 @@ TVM_STATIC_IR_FUNCTOR(IRPrinter, vtable)


// internal entry for const int bound
// This condition holds for all instances: coeff >= 0, base in [0, coeff]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

base in [0, coeff) for coeff != 0, for coeff=0 base can be any number that indicates constant

Entry(int64_t coeff, int64_t base) {
this->coeff = coeff;

if (coeff < 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if we want to support such smart conversion here, coeff<0 could be more likely an error, and we can do CHECK_GE(coeff, 0)

coeff = -coeff;
}

if (coeff != 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because this constructor is "too smart", I would recommend us to create a static function instead. C++ constructor also have a restriction of not throw exception, having a factory function and put checks there avoids the problem

Entry::make(coeff, base);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C++ constructor also have a restriction of not throw exception

As far as I know, throwing exceptions from constructors is absolutely OK. (Unless you want to avoid exceptions completely and return an error code or an optional, in which case you have to use a factory function.)

* \return The GCD of a and b.
*/
static int64_t ExtendedEuclidean(int64_t a, int64_t b, int64_t *x, int64_t *y) {
int64_t s = 0, old_s = 1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add invariance check CHECK_GE(a, 0);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making the algorithm work for negative arguments would be a better way in my opinion. GCD and Bezout coefficients are defined even for negative numbers, and requiring the arguments to be non-negative will make this function harder to use for some applications.

* \param y The solution of y.
* \return The GCD of a and b.
*/
static int64_t ExtendedEuclidean(int64_t a, int64_t b, int64_t *x, int64_t *y) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style int64_t* x

*/
static int64_t ExtendedEuclidean(int64_t a, int64_t b, int64_t *x, int64_t *y) {
int64_t s = 0, old_s = 1;
int64_t r = b, old_r = a;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think a bit more about how to make the code more readable: comment a bit on what is r and what is s, so it is easier for others to understand

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some useful comment that contains the derivation

// Extended Euclidean algorithm
// initial condition:
// a * 0 + b * 1 = a
// a * 1 + b * 0 = b
//
// Iteration (r2 < r1):
// a * x1 + b * y1 = r1
// a * x2 + b * y2 = r2
// The above two eqs can derive the following eq (q = r2 / r1)
// a * (x1 - x2 * q) + b * (y1 - y2 * q) = r2 - r1 * q = r3
// Because r3 < r2, the iteration can eventually terminate

return base;
static Entry Intersect(Entry x, Entry y) {
int64_t n, m;
int64_t a = x.coeff, b = x.base, c = y.coeff, d = y.base;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit more comment on the derivation

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let z be the integer, we know z satisfies

z = x * c1 + b1
z = y * c2 + b2

... derivation
z's general pattern

@tqchen tqchen added the status: need update need update based on feedbacks label Mar 19, 2019
@merrymercy
Copy link
Member Author

closed by #2904

@merrymercy merrymercy closed this Mar 27, 2019
@merrymercy merrymercy deleted the modular-set branch May 15, 2019 09:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: need review status: need update need update based on feedbacks
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants