# EFFICIENT SPECTRAL GRAPH DIFFUSION BASED ON SYMMETRIC NORMALIZED LAPLACIAN

In this repository, we implement the Graph Diffusion via SDEs in the modified spectral space of Normalized Laplacian (NLDM).

## Dependencies

ESGD is built in Python 3.9.0 and Pytorch 2.6.0. Please use the following command to install the requirements:

`pip install -r requirements.txt`

For molecules generation and evaluation, please first follow the additional commands:

`conda install -yq -c rdkit rdkit`

If you are using Ubuntu, please also install `sudo apt-get install libxrender1 libxext6` for RDKit. If there is issue in
installing `pomegranate==0.12.0`, please use command `pip install cython==0.29.14`.

## Preparations

we provide four generic graph datasets (Community_small, Ego_small, Enzymes, and Grid) amd two molecule datasets (QM9 
and ZINC250k).

For generic dataset generation, you can use command:

`python data/data_generators.py --dataset ${dataset_name}`

To preprocess the molecule datasets for training, please use command:

```shell
python data/preprocess.py --dataset ${dataset_name}
python data/preprocess_for_nspdk.py --dataset ${dataset_name}
```

For the evaluation of generic graph generation tasks, run the following command to compile the ORCA program 
(see http://www.biolab.si/supp/orca/orca.html):

```shell
cd evaluation/orca 
g++ -O2 -std=c++11 -o orca orca.cpp
```

## Configurations

The configurations are provided on the `config/` directory in `YAML` format.

## Pretrained Checkpoints

we provide pretrained checkpoints on the `checkpoints/` directory.

- `community_small/community_small.pth`
- `ego_small/ego_small.pth`
- `ENZYMES/enzymes.pth`
- `grid/grid.pth`
- `QM9/qm9.pth`
- `ZINC250k/zinc250k.pth`
- `cora/cora.pth`
- `planar/planar.pth`
- `tree/tree.pth`
- `pubmed/pubmed.pth`
- `sbm/sbm.pth`
- `citeseer/citeseer.pth`

## Running Experiments

### Training

We provide the commands for generic graph generation and molecule generation.

To train the score models, please run

`python main.py --type train --config ${dataset} --seed ${seed}`

Specifically,

```shell
python main.py --type train --config community_small --seed 42
python main.py --type train --config qm9 --seed 42
```

### Generation and Evaluation

To generate and evaluate the trained models, please run

`python main.py --type sample --config ${dataset} --checkpoint ${checkpoint_file}`

For example, 

```shell
python main.py --type sample --config community_small --checkpoint community_small
python main.py --type sample --config qm9 --checkpoint qm9
```

## Results

We provide part of results of our experiments here.

### Generic Graph Generation


<!-- Table 1: Generic Graph Generation Results -->
<table>
  <caption>Generic graph generation on Community-small, Enzymes, Grid, and Ego-small. <sup>*</sup> The results were obtained by executing the published source code. Other results are taken from the published papers. Hyphen (-) denotes that results are not provided and were not applicable due to memory issues. The best results are highlighted in <b>bold</b>, and the underline denotes the <u>second best</u>.</caption>
  <thead>
    <tr>
      <th rowspan="3">Method</th>
      <th colspan="4">Community-small</th>
      <th colspan="4">Enzymes</th>
      <th colspan="4">Grid</th>
      <th colspan="4">Ego-small</th>
    </tr>
    <tr>
      <th colspan="4">Synthetic, (12 ≤ V ≤ 20)</th>
      <th colspan="4">Real, (10 ≤ V ≤ 125)</th>
      <th colspan="4">Synthetic, (100 ≤ V ≤ 400)</th>
      <th colspan="4">Real, (4 ≤ V ≤ 18)</th>
    </tr>
    <tr>
      <th>Deg.↓</th>
      <th>Clus.↓</th>
      <th>Orbit↓</th>
      <th>Avg.↓</th>
      <th>Deg.↓</th>
      <th>Clus.↓</th>
      <th>Orbit↓</th>
      <th>Avg.↓</th>
      <th>Deg.↓</th>
      <th>Clus.↓</th>
      <th>Orbit↓</th>
      <th>Avg.↓</th>
      <th>Deg.↓</th>
      <th>Clus.↓</th>
      <th>Orbit↓</th>
      <th>Avg.↓</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>DeepGMG</td>
      <td>0.220</td>
      <td>0.950</td>
      <td>0.400</td>
      <td>0.053</td>
      <td>-</td>
      <td>-</td>
      <td>-</td>
      <td>-</td>
      <td>-</td>
      <td>-</td>
      <td>-</td>
      <td>-</td>
      <td>0.040</td>
      <td>0.100</td>
      <td>0.020</td>
      <td>0.053</td>
    </tr>
    <tr>
      <td>GraphRNN</td>
      <td>0.080</td>
      <td>0.120</td>
      <td>0.040</td>
      <td>0.080</td>
      <td>0.017</td>
      <td>0.062</td>
      <td>0.046</td>
      <td>0.042</td>
      <td>0.064</td>
      <td>0.043</td>
      <td>0.021</td>
      <td>0.043</td>
      <td>0.090</td>
      <td>0.220</td>
      <td>0.003</td>
      <td>0.104</td>
    </tr>
    <tr>
      <td>GraphAF</td>
      <td>0.180</td>
      <td>0.200</td>
      <td>0.020</td>
      <td>0.133</td>
      <td>1.669</td>
      <td>1.283</td>
      <td>0.266</td>
      <td>1.073</td>
      <td>-</td>
      <td>-</td>
      <td>-</td>
      <td>-</td>
      <td>0.030</td>
      <td>0.110</td>
      <td>0.001</td>
      <td>0.047</td>
    </tr>
    <tr>
      <td>GraphDF</td>
      <td>0.060</td>
      <td>0.120</td>
      <td>0.030</td>
      <td>0.070</td>
      <td>1.503</td>
      <td>1.061</td>
      <td>0.202</td>
      <td>0.922</td>
      <td>-</td>
      <td>-</td>
      <td>-</td>
      <td>-</td>
      <td>0.040</td>
      <td>0.130</td>
      <td>0.010</td>
      <td>0.010</td>
    </tr>
    <tr>
      <td>GraphVAE</td>
      <td>0.350</td>
      <td>0.980</td>
      <td>0.540</td>
      <td>0.623</td>
      <td>1.369</td>
      <td>0.629</td>
      <td>0.191</td>
      <td>0.730</td>
      <td>1.619</td>
      <td><b>0.0</b></td>
      <td>0.919</td>
      <td>0.846</td>
      <td>0.130</td>
      <td>0.170</td>
      <td>0.050</td>
      <td>0.117</td>
    </tr>
    <tr>
      <td>GNF</td>
      <td>0.200</td>
      <td>0.200</td>
      <td>0.110</td>
      <td>0.170</td>
      <td>-</td>
      <td>-</td>
      <td>-</td>
      <td>-</td>
      <td>-</td>
      <td>-</td>
      <td>-</td>
      <td>-</td>
      <td>0.030</td>
      <td>0.100</td>
      <td>0.001</td>
      <td>0.044</td>
    </tr>
    <tr>
      <td>EDP-GNN</td>
      <td>0.053</td>
      <td>0.144</td>
      <td>0.026</td>
      <td>0.074</td>
      <td>0.023</td>
      <td>0.268</td>
      <td>0.082</td>
      <td>0.124</td>
      <td>0.455</td>
      <td>0.238</td>
      <td>0.328</td>
      <td>0.340</td>
      <td>0.052</td>
      <td>0.093</td>
      <td>0.007</td>
      <td>0.051</td>
    </tr>
    <tr>
      <td>WSGM</td>
      <td>0.039</td>
      <td>0.084</td>
      <td>0.009</td>
      <td>0.044</td>
      <td>0.034</td>
      <td>0.097</td>
      <td>0.013</td>
      <td>0.048</td>
      <td>0.083</td>
      <td>0.006</td>
      <td>0.065</td>
      <td>0.051</td>
      <td>-</td>
      <td>-</td>
      <td>-</td>
      <td>-</td>
    </tr>
    <tr>
      <td>GDSS</td>
      <td>0.045</td>
      <td>0.086</td>
      <td>0.007</td>
      <td>0.046</td>
      <td><u>0.026</u></td>
      <td>0.102</td>
      <td><u>0.009</u></td>
      <td>0.046</td>
      <td>0.111</td>
      <td>0.005</td>
      <td>0.070</td>
      <td>0.062</td>
      <td>0.021</td>
      <td>0.024</td>
      <td>0.007</td>
      <td>0.017</td>
    </tr>
    <tr>
      <td>HGDM</td>
      <td><u>0.014</u></td>
      <td>0.050</td>
      <td>0.005</td>
      <td>0.024</td>
      <td>0.045</td>
      <td><b>0.049</b></td>
      <td><b>0.003</b></td>
      <td><u>0.032</u></td>
      <td>0.137</td>
      <td>0.004</td>
      <td>0.048</td>
      <td>0.063</td>
      <td><u>0.015</u></td>
      <td><u>0.023</u></td>
      <td><u>0.003</u></td>
      <td><u>0.014</u></td>
    </tr>
    <tr>
      <td>GSDM<sup>*</sup></td>
      <td>0.016</td>
      <td><u>0.027</u></td>
      <td><u>0.004</u></td>
      <td><u>0.020</u></td>
      <td>0.098</td>
      <td>0.091</td>
      <td>0.085</td>
      <td>0.091</td>
      <td><u>0.0007</u></td>
      <td><b>0.0</b></td>
      <td><u>0.0001</u></td>
      <td><u>0.0003</u></td>
      <td>0.027</td>
      <td>0.034</td>
      <td>0.004</td>
      <td>0.023</td>
    </tr>
    <tr>
      <td>ESGD (ours)</td>
      <td><b>0.007</b></td>
      <td><b>0.010</b></td>
      <td><b>0.001</b></td>
      <td><b>0.006</b></td>
      <td><b>0.007</b></td>
      <td><u>0.064</u></td>
      <td><u>0.009</u></td>
      <td><b>0.027</b></td>
      <td><b>0.00008</b></td>
      <td><b>0.0</b></td>
      <td><b>0.00008</b></td>
      <td><b>0.00005</b></td>
      <td><b>0.009</b></td>
      <td><b>0.022</b></td>
      <td><b>0.001</b></td>
      <td><b>0.011</b></td>
    </tr>
  </tbody>
</table>

### Molecule Generation


<!-- Table 2: Molecule Generation Results -->
<table>
  <caption>Results on the QM9 and ZINC250k. <sup>*</sup> The results were obtained by executing the open-source code. Other results were taken from the published papers. The best results are highlighted in <b>bold</b>, and the underline denotes the <u>second best</u>.</caption>
  <thead>
    <tr>
      <th rowspan="2">Method</th>
      <th colspan="5">QM9</th>
      <th colspan="5">ZINC250k</th>
    </tr>
    <tr>
      <th>Validity (%)↑</th>
      <th>Val. w/o (%)↑</th>
      <th>NSPDK↓</th>
      <th>FCD↓</th>
      <th>Time(s)↓</th>
      <th>Validity (%)↑</th>
      <th>Val. w/o (%)↑</th>
      <th>NSPDK↓</th>
      <th>FCD↓</th>
      <th>Time(s)↓</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>GraphAF</td>
      <td><b>100</b></td>
      <td>67</td>
      <td>0.020</td>
      <td>5.268</td>
      <td>2.28e³</td>
      <td><b>100</b></td>
      <td>68</td>
      <td>0.044</td>
      <td>16.289</td>
      <td>5.72e³</td>
    </tr>
    <tr>
      <td>GraphAF+FC</td>
      <td><b>100</b></td>
      <td>74.43</td>
      <td>0.021</td>
      <td>5.625</td>
      <td>2.32e³</td>
      <td><b>100</b></td>
      <td>68.47</td>
      <td>0.044</td>
      <td>16.023</td>
      <td>5.91e³</td>
    </tr>
    <tr>
      <td>GraphDF</td>
      <td><b>100</b></td>
      <td>82.67</td>
      <td>0.063</td>
      <td>10.816</td>
      <td>5.08e⁴</td>
      <td><b>100</b></td>
      <td>89.03</td>
      <td>0.176</td>
      <td>34.202</td>
      <td>5.87e⁴</td>
    </tr>
    <tr>
      <td>GraphDF+FC</td>
      <td><b>100</b></td>
      <td>93.88</td>
      <td>0.064</td>
      <td>10.928</td>
      <td>4.72e⁴</td>
      <td><b>100</b></td>
      <td>90.61</td>
      <td>0.177</td>
      <td>33.546</td>
      <td>5.79e⁴</td>
    </tr>
    <tr>
      <td>MoFlow</td>
      <td><b>100</b></td>
      <td>91.36</td>
      <td>0.017</td>
      <td>4.467</td>
      <td><b>4.58</b></td>
      <td><b>100</b></td>
      <td>63.11</td>
      <td>0.046</td>
      <td>20.931</td>
      <td><b>25.9</b></td>
    </tr>
    <tr>
      <td>EDP-GNN</td>
      <td><b>100</b></td>
      <td>47.52</td>
      <td>0.005</td>
      <td>2.680</td>
      <td>4.13e³</td>
      <td><b>100</b></td>
      <td>82.97</td>
      <td>0.049</td>
      <td>16.737</td>
      <td>8.41e³</td>
    </tr>
    <tr>
      <td>GDSS</td>
      <td><b>100</b></td>
      <td>95.72</td>
      <td><u>0.003</u></td>
      <td>2.900</td>
      <td>1.06e²</td>
      <td><b>100</b></td>
      <td><u>97.01</u></td>
      <td>0.019</td>
      <td>14.656</td>
      <td>2.11e³</td>
    </tr>
    <tr>
      <td>HGDM</td>
      <td><b>100</b></td>
      <td>98.04</td>
      <td><b>0.002</b></td>
      <td><u>2.131</u></td>
      <td>1.23e²</td>
      <td><b>100</b></td>
      <td>93.51</td>
      <td><u>0.016</u></td>
      <td>17.69</td>
      <td>2.23e³</td>
    </tr>
    <tr>
      <td>GSDM<sup>*</sup></td>
      <td><b>100</b></td>
      <td><b>99.81</b></td>
      <td>0.009</td>
      <td>3.191</td>
      <td>18.5</td>
      <td><b>100</b></td>
      <td>93.0</td>
      <td><u>0.016</u></td>
      <td><u>12.07</u></td>
      <td>86.3</td>
    </tr>
    <tr>
      <td>ESGD (ours)</td>
      <td><b>100</b></td>
      <td><u>99.20</u></td>
      <td><b>0.002</b></td>
      <td><b>1.425</b></td>
      <td><u>14.6</u></td>
      <td><b>100</b></td>
      <td><b>98.29</b></td>
      <td><b>0.010</b></td>
      <td><b>8.80</b></td>
      <td><u>72.1</u></td>
    </tr>
  </tbody>
</table>

## Others

Part of visualization programs are on directory `visualization`.