dwavesystems / dwave-optimization

Enables the formulation of nonlinear models for industrial optimization problems.
https://docs.ocean.dwavesys.com/en/stable/docs_optimization/index.html#index-optimization
Apache License 2.0
7 stars 18 forks source link

Consider "promoting" arrays/scalars to constants #109

Open arcondello opened 1 month ago

arcondello commented 1 month ago

Currently, in order to use a scalar/array, you need to cast it to a Constant symbol. E.g.

model = Model()

x = model.list(5)

a = model.constant([0, 1, 2, 3, 4])  # this step is required

x * a

with https://github.com/dwavesystems/dwave-optimization/issues/38 it should be possible to simply do

model = Model()

x = model.list(5)

a = [0, 1, 2, 3, 4]

x * a

by promoting a to a Constant in x's __mul__().

The main problem is that, in addition to #38, we would probably need some sort of caching. Consider

model = Model()

x = model.binary(100)

out = 0
for i in range(100):
    out += x[i] * 2

if each time we see 2 we create a new constant, we end up with 100 identical Constant symbols, each encoding the same value of 2. Whereas

model = Model()

x = model.binary(100)
two = model.constant(2)

out = 0
for i in range(100):
    out += x[i] * two

only creates one.

arcondello commented 1 month ago

One limitation to promotion is that it won't work for all operations. So

model = Model()

x = model.list(5)

a = [0, 1, 2, 3, 4]

x * a  # this will work because we're calling x's __mul__() method
a * x  # this will work because first a's __mul__() will fail, so Python will try x's __mul__()
x[a]  # this will work because we're calling x's __getitem__() method
a[x]  # this will not work

which might be a bit mysterious for users.