From cb117f8d02d7ac8e3e2f016f2431cd725704cf70 Mon Sep 17 00:00:00 2001 From: Zhaocheng Zhu Date: Fri, 3 Jun 2022 00:59:45 -0400 Subject: [PATCH] add some documentation --- asset/graph/correct_reference.png | Bin 0 -> 18646 bytes asset/graph/inverse_edge.png | Bin 0 -> 30825 bytes asset/graph/wrong_reference.png | Bin 0 -> 18562 bytes doc/source/api/layers.rst | 6 ++++ doc/source/api/metrics.rst | 18 ++++++++-- doc/source/notes/reference.rst | 33 ++----------------- doc/source/notes/variadic.rst | 1 + torchdrug/data/graph.py | 22 +++++++++++++ torchdrug/layers/functional/functional.py | 38 ++++++++++++++++++++++ torchdrug/transforms/transform.py | 1 + 10 files changed, 85 insertions(+), 34 deletions(-) create mode 100644 asset/graph/correct_reference.png create mode 100644 asset/graph/inverse_edge.png create mode 100644 asset/graph/wrong_reference.png diff --git a/asset/graph/correct_reference.png b/asset/graph/correct_reference.png new file mode 100644 index 0000000000000000000000000000000000000000..de7fe420e16f953052479ba0a0790d635fa54241 GIT binary patch literal 18646 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 VCu$ZA;m%))y>#m2Jyx@#{|ElCsEGgo literal 0 HcmV?d00001 diff --git a/asset/graph/wrong_reference.png b/asset/graph/wrong_reference.png new file mode 100644 index 0000000000000000000000000000000000000000..03b780711c757ee46fe4dcf58c8625dfc846a709 GIT binary patch literal 18562 zcmbuncQ}@R{62h32^kSGva=-=N!c?rY$;nZvm+xTdnTbsMcKPZiO4Jso02UhWfdhU z&v|{m$MYP&f1dq0KI^!<@9Vy<_xm-@^L(A}JNDEGEm~@JY7&V=drVv1fJ7n_C;p+N zz$=%6lYH@?qdppDK8EfNK7KY{=SatGd^}v;eO#Svc`lyw@^*5+a6m#vLek4lN}R{h z$H&84e*b>A|KmLp?q28jOMXv~!gZ)Tv`>4JNc1+uKV*eU1x_TA*0*EoDn|ad=0`7` zP5km_`%>58Y@HHWw{)GNQ~Guy5#LhxwM&mzCAqQEP_#(WwC`?_WVO3VYj>k9XuhR; zuWIMDGGSeFBb{uWtT~_ZaqhqJhUV2upZixYH`IR=|K*)MJAHZK^Rq=Qb@i?7tcGN^ zIXkQqsye5dY!ixT=)~J^bWZ%g{@>W{ZIbz&54_IB=)6?Dtw%>2%R1OD-`(?(yQHpp z{B(QqtiCM;9Ysfz5+9XRuPf8|g8J6GX(_Vxd-SBrUBs%T`gRq+ra0F6;gzJx;i_I& z@go8B8C*hY$Hi5{>NmKvb3ZH0>s4NeIAG51G-Q`YyL&r}UE0!zRo0-(d^FOBjaiK< z40pxzFvM2|m<85IKW|JAx;$|U_Fdr3{NijY{;Rq;u|P)BB+1N4 zR#Az;7G|f zV^>NOmWxN$DD9OfLscq{Nq#%9Er4_T^KVLDd3p|M3`aIFKN3mZmCo5Lg9pjcc{XVDQX@@wTfw;Haosp3ZEk@S{KgB+3&Zy{^3H{Esrmr(p*C4`j3s$ za$-f!$+7Msm#Hdz{rNj1f6j&eJ+^PI88ROf|Hj;9s(xI&dB2KOjiDodOIVv3+Xnx& z&g^HWu8KrvmfI9{4EQ86b(!8*KCu*X!{`Se2QLD_GWDjIn%*|@>AkPW`}=hjB(6Db z{Mq1Wy>HJiW@_@6k3)ob)2{4mk#T}TaeLX7RW28G#D^CPKNeLbN}==GO8*L&UnX(ZSf~)T>|!)u;ZR9dafF6*yY#^v;Xdud*Q8nTlQ1i?h}#& zk}eiv9X5H(ehF1WW*lGde*1bQvYPWL`ChH|`9|jC6mjmGzk+gXzK~)sKRm>xwzAn_ zW89+a%^H}Pl)tqsp_;+sZPU~IJo0MJK%V)j%P$`G@kmvx4=O0V=uNf$`LkY!^Ilq& z>|&NN?MRDlDUBsv{>UlZneff5BtbDM{vG_%tFXrPtP|9#e= z!;?gc#la>sHZB2&yPJcd@-CZqwkg=0@67sR%>1j8RZNZJfP(+5ckHuz`^0T?yL#at3LiQzAR|S~;F?aKRQ~9&r!iyGhYZB&n zq_!CmThlu@MMhVD$%=OQ?h(7RQ=hnF54YV-ePQt6f- z?>Ba7yJ`8^=U2AVTiY8w@r^2VMF?jCmIS`_LWbEDy2Pf&-5{rRc$$P@td-vV`2A9;a)`n`% zJF1>LY_Zz_(D0cos?R0bGjH<4o;^w)YRudrq}d;m)ZLEqco8TixB=Bch|H z|NZ^b-P_Apw>PgHi@bF&V{E0{2iexPHk;}8MAeLYD{_^ryKXczD6mMJjiKd`o%qsM zfS3E%u3wcBxO(#@m6n#4&%y|sRx%fJ-JZNQT;zIadAWqF`&fcqN7CfC_Yd**>c`P- zH?HyUt$cgG>*mdyk1zcYY_(lDS)bI%pCCe&q8;J;b#U_M{D-yi&3{5Zhjn6c?;QmF+gmXF;)UA0AOz#2HKwUwz@<#_xBv z?%cN(gQ?XJHLn<$kVJ-FcP_7seE;#I%BfEWU+r%yFS?A{F5}#$D*4&_$Jb19R^z_4}zrV((XI^EfX7ID3N*T3cTd!tkj~1S9 z{9&xxZuBC8YM00F@8^yNtWYw>s?U1OaT4Fl%N?>Im7AN(J}=uz>~!18m%i&a~-;F zC)U>=-B@a&SIsbR_wUY@V*dH>&tgkg7yZfGN5kss>bht84-@y&%pz_U`tF_C#_!K} z@ZSBzI>&weP`lq=noYv8Uf4&(Hwjx=^jO3&pNEHsl#-Hyw|z!b8hY|;CWPL;&2{EL?*bY$q`L!5*R$_PEEqSb|8M)-8@Am2%8k4x?>cAPynN(2J!i;pi;Cl?o!3k!wuu3fkr86JMEq==*>I=Ve_Ja~|B za(qzT)O7bft>pG+!GF4UY6TLvVl8;`b^^le?6aWLvj)yYBcx3zC=etg>U)rzzS!|5NS7Yx7Lrz@;ayrKa+xXm?jT8OEsd;hq_AGXQ9Ys{f}j?JA`O$*$D-zJZ8=p=H54G+csK(2`#zRc~bqb5ge-S`{EJY_zTTd@&`fL92EED>Henp~s&@fEm zt=hV}Y6b?^riN-4&d$xLo;*p9nlzWS9nO@|jtR#ujXIB4nX+tm_9tA=7PHky7`qGP%v8E?obDcK<;R3Kkk z??8Oi#-NC4bK?j7g|Yfr6pf>SKWY3HMxNi0vRmpqsiY#9s=_A{QYgQ7@752G+**iB zWV}kbb&JN%&Ms(mz;w3fo|eMpYn>=jdKwLiGk5RaB~4CF`hWjO6+_t)O<%F}m!9ir zXmT?B%F2r5#cyWSjy+p4Gc(^k_1kZ2XIJI7X!*FVPITa`I8h!#&v)HcL206(pdeA7 z{4sV=_wN;YMP&ezf9qfOW0ys_LVkZ2II5r^6};~A`sM+xqEEKV)fDYU@3N2hEdk6- zp?`OGcPj@3$mgHDlf-twp?DXVx|-G^RzehqHf$^J^S<`E$MDWMe@kV*^i$-*#cLr z{peEq`Xx0jnJ6za6BD6G9@~}K9)B!{dF_S79lIr(UcRJ40imR%RDODKzB70eb+V_z zO3B~fpV*bCsHn=y%Fvn`86*d>1jzh@Zo^Ct4i1tB4wQ79G?nE-tBzzYV-p{)QsGOP zz~_-HCWvysvt}4aR9IB>yt{iRX(tN{Zb9fJm4a_gJH5eN9|pW%Wi3DX}}grAk0$B2KMdrT&2AU zzt@{ki;4=dT&=CGO|7k4@vt#TNt%d)TeohBHWupc989Z&3D7VM*TJ-ag;nRW&acrtoVuzkA0z z9z*vlxQT7;-#XJ;o6TYr%unb96uyY>VEyrtZ@ z5hLq1Y~6eRSmmQf?N@o#Bt0gY*4J6n+OI4m$ecpBgl1)(i8Q5&Uu@+`eR=iH9eTiT zG*e}X41Q5j>asJn3U5nwy&w-HK#A^4Rl+Vz7K@v!o#f0YD=Y0mtyy+FVHmkyt0P<)0(c z@DZZe?Qh)J5*YZ$tD}mKk54ja%>!#^JJlL{L)MMmvLPUHbK|p8OmcDucBH4q#gt6( z^m|AjQq1Y-yZCbzD=TgQ{ufF4-aKCGuFY<(^s(7Qyag3 zfJ9sg3nRO@FhYLfS%Yw~`lPZlX zXZrN{^YqijXDwmm+X?DORHWmX2USW;$|_NDsawj&7=SF=+S_|kQ(ty=#?@V%*Fmr3 z=gYl+e=jv1UH<+1_YXa)y8Ji5d940$@N(PkxQ?l*DM!T2{fdf{RaI5KCLzWIw-%K+ zbZ9rR!P(gsHL~x2tgN(xBQX7G+I?qkCp$Ye3a_K1W54s80ps&wX=!3=Mmj9t?Y$he zTPtM;!;%E)Z%UaENxt;8qHzi>O;}hMm*NDNw$H1}a89-i;gw71_I+Pv+}V#6;k zKqCTP%N;plx^@{g_w{SN+1XiT3ky!t(p1}yHfBv--B8(kz{;j2$ zQ1&>OYqdj+#6#-ob=^amq`6r}c4Ns-(l+mXji-M*dl?Y%1~@eeLfdVHz{*QM99UUd zt^fR-XO(qj1<6=ymnDF+{yj}z9vGm|C+x0XA`l0Gg43wC54-Iuh zb6<|Z_BSl&7lY%X5}f)*PfvoN5YgDEgknfCs-IR1F76STq}$Y5n;U6i-(BSxs_@Cb zrpWV1f{f<+`a01;u=&jKH>RhiuHL>)M^8^b^2A$9>d@EY*Mn(Fh80S2m)F@$o>0-J z_;%4(*eN$?pE`9a)TSjWET%GG)p_U<);!-cLk+l+o(_h?RjPMM%5;$1&C@Nj!~b>$W9`EjGJjCS6C9f!L;ztN@U z#CN(HLNtXGBqwQniN#zxpBlICF+VJ`@^y$Fsk!#~P6$!9OifL1WM%EJuq-R~vR2S} zt&E6pzdY%}`136}$*jJyta<3~!@EM?^e%Oh+YRXV^~pUsOUD;(CT=p)pZmaXqKMwO z{G+u8O@FKLpQxP-)DQZ21_vvae4T9>E>p!7IUh@qaRx#Q3kyR5GL0}sF(G*KEqPyR zWt*MGQD)*%KvTJ#=cvW*vWLxZr>wLW?WlM~{WLT@foWDQz+|m%%i-snHU`GJwx#+z zXlPnP{{7$vi`QH>GdE`^qy>&c7mVt%O)D%XLpJ|#=j+|vg8hE?{{8cjkv-Y+zRk7c zm*cTvb;6B0#Xf102TY@Gh|(o|E@)Mqd%7d@4QI~u$gjkT_G_idWZ50%@OX!5KYOzK<3v?k>kS)bO-wvF8;=jA?bh9i&N0DBW}Q&PugtURsg=-7mAVP3YGE+|2((|FH)L2j_id zJn&N<1=w}Cx~SC-#Spc~IPZg8(3<4GwP|`nPXHQ>LZxoCt+J*0+VE=()peR6L6B^A z$j;>Ggry0Uj9ii=LGb2XPVV9jN!#{t*-AC{{Mj$RB&?PXn;&9^6hn^fi5njn7|=&h zqCC8?m&V_1L+2DsR(yd+LFswYbeJ1&AH5X*b*Ms3G>uO{An&z8Nt>;d-tpr$c6Q_( z930gbM(bLK_L*0o%4BOwW7xer`qP_Nw|8_Hol#LyNqj5%_O?R&SVQ165HQ8kVpNF6 z{FBFzn}CO^EcJzrsl{oJ%>;1leWliW$Aw2X@yh$BE;%*^HB>qGG}rGo%w(C~9Ae=U zWp)HUxeDT@t=-gDaFT(IEf&y6^rFXB>d)n%J!x!?fHr0Q8yV}@Zrw^iqq74ZTARI> zyyo*HtmsR~Esz~TRm0YUwiT`Y(qH)lV7r92C%QU3r<#^8V?Wb5Q9b7xSrEB*e^WgF z*Q>iOk>@W4QSAHh)>w>EdA2xA=PC1>64Q#EoSbEpRYM{B6(!&2ALn@dRkTcz(-ZTbuKPv~C_0jmZ_O@dNo z+ew5*#3Ae21Z5^CKR@c*H&<}Jd*@!Ivnm7}6g+WD*eBMQzSLN#*@H)}Zls8|i(W$G zf~(_`#ai=#;*rn&t$cd3&XL9~!=`zA^Mo>9Ew3%xMMOjhZxII%LpdN>J3CV!I&_H8 zJcHL)!lI+MAC!@CnP0h;|ZjEa?1z4j5}LkAIV7Q@vMPujcAs@i(`>@?r?)>RbHGo z4_g0HASo%?1nsy7PbT^+>hk&*A#e!)OP5r@`9U_{RoQKa@MrDfvID7-z;P(4MW=0k zxMl~KG7+6RM=kraq@|>u6C`VHjv9Jf8fQ!C;FG30hPPLZJTJY?(r)D|<n;j>XQ9uxJJl=>anojW%|56@Qz3BpLuR2RBLzg&IxZhW%F0BEXGU z_FK|G)7~p2H1u4^c2z)Hnh^lYSa0&!i4*MrAv+-%Lot~KwITo|m?fD}&>hutCS{ZV z(lv+86iOA+xt^H1M3%A*a$%z3Qq~Zqj3S~Cu%ZlpS-koWLxU}(^_4H=3JMA%PyOft z?#=4`rPB9X(b3Y<(y&UBAnddwT0wU<4cv%YGyEVXhEh&Wu7CDGRo&#&R5%EU^=x;J z|G$mH(6dYOsLY`Jw5vM&w948kX|o4lkc)P z-gbMzn61y?e@2rIW`T4i@*aPFx_z9Pc|JPI3CQv|WK$7BZ44Slj>Xf9aYOS^yg223 zPQ9ildLAYn1Sdf~3<7k$A$^V-^dth%{drrPMqzTRC?ScVEnrSi&^%N$_s%$ly^9oB z>n-L}EA#xpy{@3&={Q?2J0r-lOEbGm+w-va@Z*%!%t!1bM^e?Wlf z39@tv3u*)+0$;1gC181KTN3AyC~yZt-i8>umuTSC;Ba?B{v8I0_W1ts7<%y(+RGY1 z@AXennWgt}e@&R)I5|1R1u~>F>lN=YQQo(e<&<2$ueI|~$fE9=B$brNxsi-+GY-q2 z`K*g$)NfYzcHjO@(~+#y0>)P9`d(Vxtn#jUZCYA|^w%v24i$CK+RED6=*UQoSmwVF z3BuL+!XVA`_Vq2l+TYmp_AMPk->_a#SeO!kYIdmN&Q$*cxtn@|v#-yaycis03HNfF(;*=VQoL2sH5&e{%MOl$4afutb1@oo~_GEhW;(%L2;MsYb>1S$^JE22=(` z*PEN0V`7S#%rywf$jjF^55!CKUn#^0|7XIX^$iU#`}$I2V$h>RiKM zOiXMY+|YUL7;DKkGp}iey1d{1v`*Pt9r96)6uIj}iTrZk zhYwF%_ua*m0HO#3*o}~oP)wWc+WPv`V&i5zbOI6y5=ARP90~Q|*I3|V->)pPuJ1y@ ztAc*dWC#p@7EmfZL3uMBWkD!KTb(Z@hIAFMLqI@)>h!hVGu4g^hvnsap@--wn5OnU zsIERZH(VpOx-goB3hDU%!MXlijU5_`qVn>Y(8Z1!8m59P9S8PTSNB<&)yH$*d;C}q zxT*jnIOC@jCYzsL-&8|?-(8oWvumYM8H{Wv0}TyLrCkRdAyH#yRCHB9qy|D1#xs-i zwc}A)SsWzm=i%Gpf}h3*9Ne~ToAHIGPJQ`uo>N=RAGs2fC|*=LPft&?N3Lw4&1oB7 zzI-vmn2L{|-{!)FBzmQdoj`nqC@6j40EBo+_pzgT+440;e+G(T2NaZ)l-knljd^B8 za-jP@a(y3;g`$U$0ja$Gx`^S#!a@?hj_P!#LGf4Lu>Ab|H4JJ}?%YX+!pM)VH2TzU zI|)pSM@otTRCqh7?Hcdy-MfKVa!?USp@1sWO=0A5CDDZb-q$x>6Q>gsvy+1(9ugk4 zh0YAsXj|YYL?LZ8wJYToPX&EMbOZziqmCXuivFRPo3Y=Dk)a1e8EDt>nn`<(0W3u}OhI3hM7M}J%{wKb`*JkG_% z1^r2ikFPH9mjw7!Z)cjA$e}|SF)wXgD`s2ieG8%VYQ&W?9*_DB$r+$l!q&lyexb8fo%-(G*`Zn&lNZ$Th zcdKhJ?J@m(JUi>?<>y!M`^RTPsA>!h5Y&<&LmY>GqF*nesCb*e$;y`zTL&@b($Uo| zNs~usIrh-u4Ie5iyQDQKkyR=j^^U3Qj$&|T{)udm*cc4HjhspUut7ebUbFEPj~FG) z=?z(@{Ti|gVF)$wp1Xe2z|!x+`v(G-|I8mECZ-R&6fuQ;o>nW--O*9dU#AQT*5*ux z1jfi**{X5s$OY4M4CJ7F>(*4C`Qe|%Y4UEPW(k+N&2N!W9k5dxP+U;gpsvB1R~ z42a{7(7m#k-lG`Ain0d;oabQIx9RS8Eh8iP{{7~xFLCO8rzS&+YYddcM4%?1B!B{9 zhIeVpc85sW3nSX3*%vANsu_H8MMgT9bE>N!^qD>NeP!i77FP83NgW+Ngrj-Ae^suQ zjAJ)Xrktm3>_uB!Tc(HaU0Tr63vomJ&}!Sp`=F?Q!8k~Kbr|Te5Ahij(`oUh64DE? zhO`)-A@7~bPM8dTpLtaTOsSfoFQC&v>DrU4@%Z9AJ5;m?jHc4fwhz5Ca8E9IAE84dOI zOkWvZJ#}_;aEJon;{`|r3T(Nnas@;BN9JDz9)tiC6b>@0DnAJ{Q;(b$#LIcO1<~@P zs_#SFSb~$$U|zPgTp?CUT^-^O&-wG`*=3xWj^!Ef@pZmdrblDAIRR`)^z`KO8;w&6 zImk@{k)ch+JZ)*;3tye%EaUCyb7uWNPBJjr2nNmnO&% zEFi!r{<2jI<_ z`%c9qM$K)rJXbkk2688I<1oI8KM z4^eXrFC#uj6z9KFr<}MjI#Z`zv$Ft?r0)Bow21+l(z_5*i;@XoZhxeU+aNp#ge#XE< z(YYtgOibNCvyRAAq7pfSdNr&Lo>>7(5@k94aJUBg8i2pSlS@fD!D&mrkaMHyxizuO zlk@Y5h^gW+68Bx>K7Jddk}%aUtvY_{x^oheoVaf>GZ)thL;w^1 z1E&sAI_uydId|?{52g#pF?lRF;#mC$zHj0a9Z>-wx`INgFlJaEhwk>~hSU|92AnXKUjb@LJu5*VkCZD{uGlU$ z%y!!9=ukVkxby)aoshnn03xM9AizsMJ{h>ZvVY*b{r&kn!J3e+S1=bV8Ci=fhMFos zI(K19(KjRc${1=Pku7(@#bCS9AxejsY56IPS7CP|8sf|5=5R>A(a~YP>BUt2 z#ryZCtLTlTk+B7eHAIdp$A6f;U4xjQrss z$X)<=7y(ksEgMAP$|_rP8U^iioM;NG4*YeY%}&gu^lt4~KzvLLXd1#Odt`L<3%YOI z5L{7)RY_Ha3S8%n=m<1{k+TtMn#PwQMw4{h5d0$~Xbv=-@=TzjFl(h52fe)>8M%!} z0pw9GcKO|7PyU|^qdP#cNlkUWUnjseiBUAN1MEH~CWaUj?qp;P2jSER4EnHtGVlI< z9tjCLaJ8Lv*PWeCZH7a@CFVV>931yTHvh%M#Svd6#1hY35QI*t>ER*i@Fp`7ayK~% zP)E|biA30TDCy{;FgOEZs|1O#-dlIB=d0QzOGK(=2Wq9nM3z1c@XeA+g2O z;JB*a@|>!k9!<@K(ah4)(%Ju9Wqo(+6)h%5{l@dKW9$y*oo^v1ev_y5&f(Nmy;| zq1DB4E9^tra|#yy$u}IXuC8*`bMLUKsI+$oj7an;B5nmPFqp7;J-M}oocs%#X*JZ7 z2eq{Y@M2Xp{{p@5E7ZS7Nece{Qb_cJOW}SrvHJxDT12~oZ)TX?$C}|UhqF&)g+uPfBWBOk*FotI3gm}6R!F19o2ic8aNkx3D&JDyPZHj&C z+b4iHwuVYrJrnm485o=(kB<=+6^+AE9Il=_*5fn@1*HhE%V(~?NVFlja4D)3U_b5I zp>xX0q?=h;sR$|n*P=O%LtCtZSDC?ri&pNBQTV1+9yKvBdF(N{C5F<{(lRD7k-6?Z zMVaF(M(}MSQ!ZS%;2v~xIm`H#LLiIM#uB-_?_31J#dt0bb{ZkXy!H9>(NMJ}Fiw{F zvy-+P=p7Og8R#*xNHJ&ELq+D*YE0D23=So`Qi={YB^P=~{X}Fqy}lu3@9L@tI+>5k zlJ;lpJMy0(1z1xsxq6K^o2f7D?X9g(O{SR}cNcDnk0Bz;{@ghYG)^WC4l$p@iRN(Z z{KYK)AgmA%s;YR8966GC*jq4LG1#2p-~iPgP~1DgKiSCc9`^pUR8Ft%^L21v+GtMB zW6j-W>H=!lHLXx%ptoYzS#>#z1B5**;*plxf6rjnJ**TFIvJx@<* z3KSRWC)hN+9Uf-iEpb*EyNV=XdKhy0uat~T8*r%mvdzcF_w za*$X>42(5&baWDj4bOqVM-Y0=K_@;R5t&|L@*To7W%wk#Lb(_l!)IFGEg&P$9kfIS zUPH`ftuaMK`=*6E?z6c9F$tc4Ijtj^`yPsg|N4qk*`o^Tk6wqjY}wLXV!9t&P^HOX zraaj^mb-Zg+@RGoed`0jhWq*X#6XtNN1Xq*??P~>z>$LwqI`M6;9~A(^*%B(k{8ms z%2tzmds+gryG_&M%A>04(ym`u$NPEVo{%l+B!C{$tQr!R^hXpXjs=9ZTy zp)O2;TC`jf(3SLCINLT~HD?Y#n`SasBH--uzOp$pP#NOx5j})@_CI#cBFnS&{tUQ& z81@)0w_Dw@MXoFMb)9b(ppq3#?Z2%#OO zLKqQ%YWUt03`yrr{N!P^RW*r>K1kx}yzmIIoM#H!5@R)9=C2d|1I%{R;l$Zh|BAOCG)`@utv>%4L`{o+z zaseyCQS{tn){hF(DJ?>!A3l7jhTXtRbSF=qbRB=jdBEXy;c|o~iC80^j8~I0Gut3n z!s&~o=R|wDQdYJPbxiWYh+JE^waFnUJkS2EyO5f&M7)f#l3;0JCB>YmxgD6oEWJ52 z4vbmm#9DPGI<8zCaElg>hgMh}Q!r(|CkxMsCyZn$Csf!*3XpKRo^k}Ui#FtRzsVof24^^ZjXn#`f`oYjvbfm8#Ep%hHs&^XOq_?B z{|RKga#|R9vNiPCpM@i^9aaJD^nl<+O5B4*(zpk(vJXl|Y`uYfM!{a*!C!eK(>cawS)g$e0^Ji0|Er($A7{;#|FG$^w!?Xh=t!_p)=1YFJ+u| zR${;3wa;1U!`gWUZL-_|Ujm31s2Sx`zafWtd3xr6vlyU2Wy^VnfBW{$acyamkOkH! zqq$#nbVQ?%tJzlFAli8#cLIa{v7IO4HIg<$;Poc_?(G}14c}Q z$b#BetmiHOYK`LB1l9}t>rble8?^ey8N*DC3dR^o6BKW%Eneivk*tlsf8ijF{kb@P zQhoD;@aQ8qj#za*`M{s9v7?8r#;;c9=&>@z0a^evrlO>DChP(qyh=Lwg46dBO$kd| zN5?cS1@>x`pk@4tg1RkGm2g`CR|0NPVEP4H8$aAI7@&$T-v;(0Dl;pT1K7YlF~5HN z^r_v(+A`tG0fZpC`<(bb0^M=SZ-qud!*!JPKX>yAF$GbBPqiEJA_6E_Rmefj;Eb*t zM4ckmY5B_=a?luIKKKPa=ZIetA^(`S0yC;Zy2?eRGQ_C*@Ap^x;Yw8pNIsT0XT6C& z!iSCrR8rBmnkSQ%nyLmDHUU)d4KOR$?1e;yxs%Ec7V%Rf*Mi}H%satfT=)3!zI};= zCk0<82(=KRBU_DQPdEfm=8n~smAx>?628fE4i3=i0B2vmd6S4jDy*b*2a{9dAN22E zC|usS0cN8)TIXvxtT1&Fyn`f+WrXc|>z)1m*S@C@6Mh738Q-SvfnWHR zoaYvZaIM(cotOwhN)p|mUzXbXJlwWS-y|!i6nVrf&gI^!aWa9=-A~yZU|9( zH@C8P=f0!YgMP!_MBTx?rV|WyK35(IWqT@Y- z^)hVRMHE{UaW!;}7ehm}tu7!GIuJEi<_5(0MC(_dK74op>J5VG9z5jN;3~xUuYTC~ zpaT>yK@#*395~Pyt}8oz_UtY6MK-!p_TmMDETENM)NK(sUfX5#vSbr67CM0mTP|iZ zM0Dg{Yp4b5aUOrB@czSx)GJrWArsU*cbyZw4#kRrw7xoI6)6!J6GQM8NYgBJ2{6|i zs{v97ft;-4rI;9DV0QCrM-^ae*A06qu@ zE5WaWHs}wyU(H-kNztF`N)U$FyZ&=t7e2NX z41}N05r#n!_Tr7~?D2@93;p4p;x#?}{pyXE{}NXB`+0eU#7B5;&PqhXDN<3fpCFm& zA1KRWEDF1eUK?aV7_@~yjTGA5eJX)nh8h4{&S!R~W&&#%PDEe=VAC8y6-Si^aRse{ zIPn8*u2bOz&L@EphC&UghiC>HPwAK1G8K4ln=sdk#RJ+A$6;W=X&BGe6il6jVWvHB zv7z9*-^I)Pz}dW_?ufOtC&(fq?4c(kb@6Y|?whc$YhaWU69XgIEPV1lP;i}xh-RNF zbkO^g9=o(XB}1ALcWM1?L)=H%>4#D9t*D|Az#IAY&}-pO;BNQJ%8ny-N`8%f1`MYn zjXw6gXPGRvm9A9&C)DMXk`giW8P#Po$Xrg2j@{^h#6)NhC#MsPwQ-(8m`2ULe<+0N ztq%v+%l`iAVUAAb&B@5tEhTK_v#m;$*#F+1o}9+be^1R<586l5aq^L>0h4n=Eov<5~_v?&5 zj2whclXb|wJY$+FkzALA?!*(TPAn0j5#l(Kx{*J1ZP0J8YubAW8i-Dj53LG%&cdTv z2N-m3`hblxx|s<2#OeO8LgeM=9_#th7A44%g^6J0_3!IcTdKnPT>K-qgs*P#ORl_w7ME;B-)0>tMd6` z0MYntLqJWd6u?4EVKbrFFuSGKwpYRM3gaDso|>bhu*2&cVZ`Z%&6Y!3UB95{^pH5)1k^>nsL$0CZrLt>KQ2kVAK4LbJT_z4nV#%nb-46icog{gT8nUY! zVOW62K|dixmST^Y4o0{!IB}qbFcd(;goV>2;UuVNPqA^y3uJm#qMm;D@!Lmly1Kc& z?CD9tX#yvh)Mcnkpv)k`>;AJ1(TtH%fK zLAM*wd0HG!u1ke}kcs1Jr_Y?}1JRqsi4Y;s+1d-EeA~BgZ<`40*(@dE5^0G?Jo3_B z8hgfs>`J>dqb-8aKpme)#@3dkssB{X2*uJ)SIc~Dt-%9YKK=_mwYeoSUFC2hiOl{X;N z<;i-AaTytBuRz)}hhUQrB7NN~w`J@b$}>@nflc#Z)>?;l{c>!~($n|x15i{-Qf!;; z7Mv{zAQX6c?sukwd(1@nczMI%q$Y+odvklkyaBS<4?6CIS*x&h%@julAhh&giuvNz zt9ZrVA5+;AFV!n%ha10zMngp+gkh4AOGfn7t2^5Q$$%U9Nc|7az0&laNv~imro=Rz zsKH?KBx-lHGlET~oa)}5Rf3E0ujOSoLCsaI4MU1~nd@PP3*KK2Jlq&iEr6wM!tg~}-qYV!J z%NXK^A$8oC$vNgl4eZ&skte&xFaOzxM0P1NIoGkNV|>F*yd9=i22RdI80Yxq#fn;VLeOX+j2hInO&j>vF(*fRV zV$=>sK~I8nFBC%*oT;9Grxa(?ck;i{T;|qc2sP0hUhXVQh6!n<7Ef7-8k^D8 zcglh=V?vvgU3?$ibuwzYciO%%Rzvt|#^$uyN_{~#6^?0Z>fT!)6+Xr0VJ+iv=8@}j ztnTFOYz$835hoKs7Aw9#)`I>TL)rLmUF_oGSYqrhAzM@xUnAe?|LdP6C=8OTWG8!a zHVICrDYW<5z5;pzvY^-C2(2i^Y>6$*^zRx155aFuCni=RU-)?P!{jEVRd&g+aq|Ol zcI)KBmTt~Dd;?8k1234En3Rtnrv)2q_8Sk5CJxsuO+06QCIlu0Tf^*N83$YR zZP>3RZ|BPY#cA2NSu@{}=2d$;1ys}MtgH_lFOaXi({jXndN(^p9OLC(mC!->ANxW|eY>afh#AmQD>}h9;co#<>R5 zTr4I11ByjPafqpw@o{cK3nfmV@$=s^m?t<2;pBnK4%Pu$K2`MOZVcE~=0EHPJ-Pya z(7pMv<1oF4rHITVoyM;Od^f#$s!vA!LNou-@y3Zn1#z6oA2sKgZt5@hHGb4P@gb;6 zx@8&_?UbphR*6Yu0Xrmuwm4?7r7opSWzn>B>XO`xp!Ag>1|(&SfB>K;KY!ki-bA$N z|J~3?*gVl}QQIo3s+^X1e+o;H;|DBE*Vt3kIi2gGjGb$hPdr|cV@pnzwmxqjARDCC z9M;xJ%$fK_M5xelBT)WOnyj6isPOclFFG|gIKu+RJz)hU5hu(h+Y>op=~U6yri6c< zI2TAJOw*dXBuXv4eS0)T%|{rrUvm^l7-eLdMOcN~RyyNn1>Dcv^sugyCQduytW_)F zu(E&2h+;YgEE)Oekt_&@ewi%%I$@X-HFb1oEx$vz_e6;#juqm#7a^OWr)|0G;ot|1 zIPvXU0t#abLIIk)<7k}>aJ5mn)+g>1BO%x#e?HjY7PMhzzi7S8%2Lt|;O+q_2WQ~; zkdH2dr7D~M{(i0g4COrzN{*N+1{E~Kk))E)Oc?ldRH=p`iSXjvT zl$WsQH8*d;unI?mqQFRQHpbmPaPVM6e!fHY02j-hr03&jFaOvPU*v2})@0=!c(>tP zOT#hkmPA{VlDKB-ofneQa4H@^4lSnX5Ej?AA=oIz9|i-v zv9hrd2LW;L1sxH8$5mKu{$1_B&cbz{3`S`BA53se#JE)m56Z}nwm!c*WYikmO z1Y%Fq(y1f{TYjmi^;Q;`cv)9zYQa$e-;tz@Oj)g+15C_DZBnJhjAS^pQq;mviDP+H z0eA0-sEF~qshiqruD{9>f+0LITu+3=^Lbh3g*5eN_b-hyOjCmAq7B6C<|z~==y2T3 z#2r7~;>jboo@mHnNx`l0{MFvJI}f=jw$PK4k?Q6fI%$YRv;4U_WXD8pg`ah}ee{3M z82AqUQ`!+AyLNMdHZUSdN}#u0j~>5~acbAlg0ac}{9XpFVkrrSD(40WmutV5^)bTZ zI(fFlO;n6{Sznjmt+ae*^|DJ;jr+k50yte}(ls_eLLE=>Zb;`${C2s6nQ#7(xO~p* zNy?1&1>;vW5=H;J;#Ov{H|;P*u9Y87!!L5&U_3RFv1G$&YtZ?4e@>Nb{kP*%V-3dl z98p%dzhoPLq|GKZI;W!S9Xd6#tsaoiIJuuCEmq|%;;wXqtq;S~A*=l@*} aVF@~Zr_nj)IerX?bWG!fdbz4~`2PmxG{Ug} literal 0 HcmV?d00001 diff --git a/doc/source/api/layers.rst b/doc/source/api/layers.rst index f09fa456..269a6ccb 100644 --- a/doc/source/api/layers.rst +++ b/doc/source/api/layers.rst @@ -214,6 +214,12 @@ Variadic .. autofunction:: variadic_sample +.. autofunction:: variadic_meshgrid + +.. autofunction:: variadic_to_padded + +.. autofunction:: padded_to_variadic + Tensor Reduction ^^^^^^^^^^^^^^^^ .. autofunction:: masked_mean diff --git a/doc/source/api/metrics.rst b/doc/source/api/metrics.rst index 446022ba..bee8d738 100644 --- a/doc/source/api/metrics.rst +++ b/doc/source/api/metrics.rst @@ -26,9 +26,21 @@ R2 ^^ .. autofunction:: r2 -Variadic Accuracy -^^^^^^^^^^^^^^^^^ -.. autofunction:: variadic_accuracy +Accuracy +^^^^^^^^ +.. autofunction:: accuracy + +Matthews Correlation Coefficient +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. autofuction:: matthews_corrcoef + +Pearson Correlation Coefficient +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. autofunction:: pearsonr + +Spearman Correlation Coefficient +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. autofunction:: spearmanr Chemical Metrics diff --git a/doc/source/notes/reference.rst b/doc/source/notes/reference.rst index 86277aed..e35538e2 100644 --- a/doc/source/notes/reference.rst +++ b/doc/source/notes/reference.rst @@ -30,6 +30,7 @@ the result is not desired. The edges are masked out correctly, but the values of inverse indexes are wrong. .. code:: python + with graph.edge(): graph.inv_edge_index = torch.tensor(inv_edge_index) g1 = graph.edge_mask([0, 2, 3]) @@ -55,34 +56,4 @@ since the corresponding inverse edge has been masked out. :width: 33% We can use ``graph.node_reference()`` and ``graph.graph_reference()`` for references -to nodes and graphs respectively. - -Use Cases in Proteins ---------------------- - -In :class:`data.Protein`, the mapping ``atom2residue`` is implemented as -references. The intuition is that references enable flexible indexing on either atoms -or residues, while maintaining the correspondence between two views. - -The following example shows how to track a specific residue with ``atom2residue`` in -the atom view. For a protein, we first create a mask for atoms in a glutamine (GLN). - -.. code:: python - - protein = data.Protein.from_sequence("KALKQMLDMG") - is_glutamine = protein.residue_type[protein.atom2residue] == protein.residue2id["GLN"] - with protein.node(): - protein.is_glutamine = is_glutamine - -We then apply a mask to the protein residue sequence. In the output protein, -``atom2residue`` is able to map the masked atoms back to the glutamine residue. - -.. code:: python - - p1 = protein[3:6] - residue_type = p1.residue_type[p1.atom2residue[p1.is_glutamine]] - print([p1.id2residue[r] for r in residue_type.tolist()]) - -.. code:: bash - - ['GLN', 'GLN', 'GLN', 'GLN', 'GLN', 'GLN', 'GLN', 'GLN', 'GLN'] \ No newline at end of file +to nodes and graphs respectively. \ No newline at end of file diff --git a/doc/source/notes/variadic.rst b/doc/source/notes/variadic.rst index 2eedcc96..e0c671f0 100644 --- a/doc/source/notes/variadic.rst +++ b/doc/source/notes/variadic.rst @@ -113,6 +113,7 @@ Naturally, the prediction over nodes also forms a variadic tensor with ``num_nod :func:`variadic_topk `, :func:`variadic_randperm `, :func:`variadic_sample `, + :func:`variadic_meshgrid `, :func:`variadic_log_softmax `, :func:`variadic_cross_entropy `, diff --git a/torchdrug/data/graph.py b/torchdrug/data/graph.py index 07d1c60d..dbedfdc9 100644 --- a/torchdrug/data/graph.py +++ b/torchdrug/data/graph.py @@ -699,6 +699,17 @@ def edge_mask(self, index): num_relation=self.num_relation, meta_dict=meta_dict, **data_dict) def line_graph(self): + """ + Construct a line graph of this graph. + The node feature of the line graph is inherited from the edge feature of the original graph. + + In the line graph, each node corresponds to an edge in the original graph. + For a pair of edges (a, b) and (b, c) that share the same intermediate node in the original graph, + there is a directed edge (a, b) -> (b, c) in the line graph. + + Returns: + Graph + """ node_in, node_out = self.edge_list.t()[:2] edge_index = torch.arange(self.num_edge, device=self.device) edge_in = edge_index[node_out.argsort()] @@ -1627,6 +1638,17 @@ def subbatch(self, index): return self.graph_mask(index, compact=True) def line_graph(self): + """ + Construct a packed line graph of this packed graph. + The node features of the line graphs are inherited from the edge features of the original graphs. + + In the line graph, each node corresponds to an edge in the original graph. + For a pair of edges (a, b) and (b, c) that share the same intermediate node in the original graph, + there is a directed edge (a, b) -> (b, c) in the line graph. + + Returns: + PackedGraph + """ node_in, node_out = self.edge_list.t()[:2] edge_index = torch.arange(self.num_edge, device=self.device) edge_in = edge_index[node_out.argsort()] diff --git a/torchdrug/layers/functional/functional.py b/torchdrug/layers/functional/functional.py index 19dbe0ec..acb7d771 100644 --- a/torchdrug/layers/functional/functional.py +++ b/torchdrug/layers/functional/functional.py @@ -375,6 +375,9 @@ def variadic_sort(input, size, descending=False): input (Tensor): input of shape :math:`(B, ...)` size (LongTensor): size of sets of shape :math:`(N,)` descending (bool, optional): return ascending or descending order + + Returns + (Tensor, LongTensor): sorted values and indexes """ index2sample = _size_to_index(size) index2sample = index2sample.view([-1] + [1] * (input.ndim - 1)) @@ -445,6 +448,21 @@ def variadic_sample(input, size, num_sample): def variadic_meshgrid(input1, size1, input2, size2): + """ + Compute the Cartesian product for two batches of sets with variadic sizes. + + Suppose there are :math:`N` sets in each input, + and the sizes of all sets are summed to :math:`B_1` and :math:`B_2` respectively. + + Parameters: + input1 (Tensor): input of shape :math:`(B_1, ...)` + size1 (LongTensor): size of :attr:`input1` of shape :math:`(N,)` + input2 (Tensor): input of shape :math:`(B_2, ...)` + size2 (LongTensor): size of :attr:`input2` of shape :math:`(N,)` + + Returns + (Tensor, Tensor): the first and the second elements in the Cartesian product + """ grid_size = size1 * size2 local_index = variadic_arange(grid_size) local_inner_size = size2.repeat_interleave(grid_size) @@ -456,6 +474,19 @@ def variadic_meshgrid(input1, size1, input2, size2): def variadic_to_padded(input, size, value=0): + """ + Convert a variadic tensor to a padded tensor. + + Suppose there are :math:`N` sets, and the sizes of all sets are summed to :math:`B`. + + Parameters: + input (Tensor): input of shape :math:`(B, ...)` + size (LongTensor): size of sets of shape :math:`(N,)` + value (scalar): fill value for padding + + Returns: + (Tensor, BoolTensor): padded tensor and mask + """ num_sample = len(size) max_size = size.max() starts = torch.arange(num_sample, device=size.device) * max_size @@ -469,6 +500,13 @@ def variadic_to_padded(input, size, value=0): def padded_to_variadic(padded, size): + """ + Convert a padded tensor to a variadic tensor. + + Parameters: + padded (Tensor): padded tensor of shape :math:`(N, ...)` + size (LongTensor): size of sets of shape :math:`(N,)` + """ num_sample, max_size = padded.shape[:2] starts = torch.arange(num_sample, device=size.device) * max_size ends = starts + size diff --git a/torchdrug/transforms/transform.py b/torchdrug/transforms/transform.py index bc86d129..3245ca98 100644 --- a/torchdrug/transforms/transform.py +++ b/torchdrug/transforms/transform.py @@ -11,6 +11,7 @@ class TargetNormalize(object): """ Normalize the target values in a sample. + Parameters: mean (dict of float): mean of targets std (dict of float): standard deviation of targets