PhIMaL/DeePyMoD

Dictionary entries

Closed this issue · 2 comments

I have a question regarding the order of the entries in the dictionary for the KS example.

https://github.com/PhIMaL/DeePyMoD/blob/master/examples/PDE_keller_segel.ipynb

The library is defined as follows

library = Library1D(poly_order=1, diff_order=2)

Looking into model/library.py I can see

  • terms 1 to 4 correspond to theta_uv (1, u, v, u * v)
  • terms 5 to 12 correspond to theta_dudv (u_z, u_zz, v_z, u_z * v_z, u_zz * v_z, v_zz, u_z * v_zz, u_zz * v_zz)
  • terms 13 to 20 are mixed terms. So we have any combinations out of u, v, u_z, u_zz, v_z, v_zz. However i could not find out the order of which of the terms come one. Can you clarify this?

Thank you in advance!

Hi,

It's been a while since I wrote this so I don't remember exactly, but we calculate the library as a crossproduct of polynomial terms [1, u, v, uv] and derivative terms [1, u_z, u_zz, v_z, v_zz]. You should be able to reconstruct the terms from this!

Thank you very much for your answer!

I spend some time debugging this case and now want to clarify for anyone interested.

Polynomials

  • $\theta_{uv}$ is the Cartesian product from the two poly lists, which, for poly=1, are:
    poly_u: [1, u]
    poly_v: [1, v]
    Here we get:
    $\theta_{uv}$: [1*1, 1*T, X*1, X*T]

Derivatives

  • $\theta_{dudv}$ is the Cartesian product from the two derivative lists, which, for deriv=2, are
    poly_du: [1, u_x, u_xx]
    poly_dv: [1, v_x, v_xx]
    Here we get:
    $\theta_{uv}$ (with first element): [1*1, 1*v_x, 1*v_xx, u_x*1, u_x*u_v, u_x*v_xx, u_xx*1, u_xx*u_v, u_xx*v_xx]
    but get rid of the first entry so we have
    $\theta_{uv}$: [1*v_x, 1*v_xx, u_x*1, u_x*u_v, u_x*v_xx, u_xx*1, u_xx*u_v, u_xx*v_xx]

Mixed Terms

$\theta_{mixed}$ is made up of a total of 4 terms, namely $\theta_{udu}, \theta_{vdv}, \theta_{udv}, \theta_{vdv}$.
Bildschirmfoto von 2024-05-03 08-15-41
However, in your implementation, we are only having two of the terms, which are repeated twice, namely $\theta_{udv}$ (for the entries 1+2 and 3+4) and $\theta_{vdv}$ (for the entries 4+5 and 6+7).

I have a rather hard coded workaround and replace lines 164-175 in library.py with:

          # Access the first elements in poly_list and deriv_list
          u = poly_list[0]
          du = deriv_list[0]
          # Access the second elements in poly_list and deriv_list
          v = poly_list[1]
          dv = deriv_list[1]

          # Perform the operations for the first elements u
          theta_udu = torch.matmul(u[:, 1:, None], du[:, None, 1:]).view(
              samples,
              (poly_list[0].shape[1] - 1) * (deriv_list[0].shape[1] - 1),
          )

          # Perform the operations for the second elements v
          theta_vdv = torch.matmul(v[:, 1:, None], dv[:, None, 1:]).view(
              samples,
              (poly_list[1].shape[1] - 1) * (deriv_list[1].shape[1] - 1),
          )

          # Calculate the mixed terms
          theta_udv = torch.matmul(u[:, 1:, None], dv[:, None, 1:]).view(
              samples,
              (poly_list[0].shape[1] - 1) * (deriv_list[1].shape[1] - 1),
          )
          theta_vdu = torch.matmul(v[:, 1:, None], du[:, None, 1:]).view(
              samples,
              (poly_list[1].shape[1] - 1) * (deriv_list[0].shape[1] - 1),
          )

          # Concatenate all the results
          theta_mixed = torch.cat([theta_udu, theta_vdv, theta_udv, theta_vdu], 1)
          theta = torch.cat([theta_uv, theta_dudv, theta_mixed], dim=1)

So, for poly=1 and deriv=2, we get the following lists (we always start with the second element):
poly_u: [u]
poly_v: [v]
poly_du: [u_x, u_xx]
poly_dv: [v_x, v_xx]

$\theta_{udu}$: [u*u_x, u*u_xx]
$\theta_{vdv}$: [v*v_x, v*v_xx]
$\theta_{udv}$: [u*v_x, u*v_xx]
$\theta_{vdv}$: [v*u_x, v*u_xx]