titu1994 / tfdiffeq

Tensorflow implementation of Ordinary Differential Equation Solvers with full GPU support
MIT License
218 stars 52 forks source link

Introducing time-varying independent variables into the neural ordinary differential equation #14

Open zykhoo opened 2 years ago

zykhoo commented 2 years ago

Hello thank you for implementing this library!

I have a variable that depends on the time step, called aircon_power. It should take in the time step that the ode is currently at, and return the respective aircon_power.

def aircon_power(tstep):
    if tstep<0:
        return 0
    elif tstep>len(merged_dataset["temp_1"].values):
        return 544.9
    else:
        spl = interp1d(range(len(x)), x, kind = 'cubic')
        return spl(tstep)

I intend to then embed the aircon_power within the ordinary differential equations.

dT1 = - n_out[0, 0] * aircon_power(t) + (T1)*n_out[0, 1]

However, this returns an error because t is a symbolic Tensor.

NotImplementedError: Cannot convert a symbolic Tensor (tstep:0) to a numpy array.

Do you have any alternative method to introduce such a variable?

Thank you!

cschempp commented 5 months ago

I think the error comes from using interp1d, which expects numpy array. For example, this works:

def aircon_power(self,tstep):
    if tstep<0:
        return 0
    elif tstep>1.5:
        return 544.9
    else:
        return 42

then call it inside your model class:

@tf.function
def call(self, t, y):
    x1, x2 = tf.unstack(y)    # state  variables
    acp = self.aircon_power(t)

    # ODEs

    return tf.stack([dx1_dT, dx2_dT])

I hope this helps.