Rounding, using modular arithmetic, etc. in find_fit?

asked 5 years ago

ctennenh gravatar image

updated 5 years ago

I'm learning how to use find_fit and it works great for polynomials, but I'd like to include expressions that require integers. My variables are all integers, and my coefficients are expected to be relatively simple rationals (i.e. small denominators). In particular, I'd like to use a model like:

model(x,y) = (a*x+b*y+c)%(d*x+e*y+f)

However, I get the expected error:

TypeError: unsupported operand parent(s) for %: 'Symbolic Ring' and 'Symbolic Ring'

If I try to convert (dx+ey+f) to an integer within the model using int(), ceiling(), etc. then it won't convert, since of course it's a symbolic expression. Is there a way to round within a symbolic expression? Or any suggestions for other workarounds? Thanks!

edit: I was able to get it to run, but it doesn't provide an acceptable solution. I imagine it's due to how find_fit works with user-defined functions but I don't know enough about the inner-workings to work that out. Here is my code:

data = [(i,(i%2) ) for i in range(30)]
var('a, b, c, d, x')

def f(x, a, b, c, d): 
    return int(a+b*x)%int(c*x+d)

fit = find_fit(data, f, parameters = [a, b, c, d], variables = [x], solution_dict = True)
print fit

and the output is

{d: 1.0, c: 1.0, b: 1.0, a: 1.0}

I would like it to return, say,

{d: 2.0, c: 0.0, b: 1.0, a: 0.0}

Is there a way to make this work a bit better for my needs?

Preview: (hide)

Comments

To avoid the immediate error one can introduce a true function like model = lambda x, y, a, b, c, d, e, f: int(a*x + b*y + c) % int(d*x + e*y + f), but then it makes not to much sense to start a numerically fitting function against the model function. Which is actually the real need?

dan_fulea gravatar imagedan_fulea ( 5 years ago )