1+ """
2+ .. _fourier_continuation :
3+
4+ Fourier Continuation
5+ ========================================================
6+ An example of usage of our Fourier continuation layer on 1d and 2d data.
7+ """
8+
9+ # %%
10+ # Import the library
11+ # ------------------
12+ # We first import our `neuralop` library and required dependencies.
13+ import torch
14+ import matplotlib .pyplot as plt
15+ from neuralop .layers .fourier_continuation import FCLegendre
16+
17+
18+ device = torch .device ("cuda" if torch .cuda .is_available () else "cpu" )
19+
20+ # %%
21+ # Creating an example of 1D curve
22+ # --------------------
23+ # Here we consider sin(16x) - cos(8x), which is not periodic on the interval [0,1]
24+
25+ length_signal = 101 # length of the original 1D signal
26+ add_pts = 40 # number of points to add
27+ batch_size = 3 # the Fourier continuation layer can be applied to batches of signals
28+
29+ x = torch .linspace (0 , 1 , length_signal ).repeat (batch_size ,1 )
30+ f = torch .sin (16 * x ) - torch .cos (8 * x )
31+
32+
33+
34+
35+ # %%
36+ # Extending the signal
37+ # -----------------------------------------
38+ # We use the Fourier continuation layer to extend the signal
39+ # We try both extending the signal on one side (right) and on both sides (left and right)
40+
41+ Extension = FCLegendre (n = 2 , d = add_pts )
42+ f_extend_one_side = Extension (f , dim = 1 , one_sided = True )
43+ f_extend_both_sides = Extension (f , dim = 1 , one_sided = False )
44+
45+
46+ # %%
47+ # Plot the results
48+ # ----------------------
49+
50+ # Define the extended coordinates
51+ x_extended_one_side = torch .linspace (0 , 1.4 , 141 )
52+ x_extended_both_sides = torch .linspace (- 0.2 , 1.2 , 141 )
53+
54+ # Add 0.5 and -0.5 to the extended functions for visualization purposes
55+ f_extend_one_side = f_extend_one_side + 0.5
56+ f_extend_both_sides = f_extend_both_sides - 0.5
57+
58+
59+ # Plot the results
60+ plt .figure (figsize = (10 , 6 ))
61+ plt .plot (x [0 ], f [0 ], 'k' , label = 'original' )
62+ plt .plot (x_extended_one_side , f_extend_one_side [0 ] , 'b' ,label = 'extended_one_side' )
63+ plt .plot (x_extended_both_sides , f_extend_both_sides [0 ] , 'g' , label = 'extended_both_sides' )
64+ plt .plot ([0 , 0 ], [- 2.5 , 2.5 ], '-' , color = 'gray' , lw = 1 )
65+ plt .plot ([1 , 1 ], [- 2.5 , 2.5 ], '-' , color = 'gray' , lw = 1 )
66+ plt .plot ([0 , 1.4 ], [f_extend_one_side [0 ,0 ],f_extend_one_side [0 ,0 ]], '--' , color = 'b' , lw = 0.5 )
67+ plt .plot ([- 0.2 , 1.2 ], [f_extend_both_sides [0 ,0 ],f_extend_both_sides [0 ,0 ]], '--' , color = 'g' , lw = 0.5 )
68+ plt .legend ()
69+ plt .tight_layout ()
70+ plt .show ()
71+
72+
73+ # %%
74+ # Creating an example of a 2D function
75+ # --------------------
76+ # Here we consider sin(12x) - cos(14y) + 3xy, which is not periodic on [0,1]x[0,1]
77+
78+ length_signal = 101 # length of the signal in each dimension
79+ add_pts = 40 # number of points to add in each dimension
80+ batch_size = 3 # the Fourier continuation layer can be applied to batches of signals
81+
82+
83+ x = torch .linspace (0 , 1 , length_signal ).view (1 , length_signal , 1 ).repeat (batch_size , 1 , length_signal )
84+ y = torch .linspace (0 , 1 , length_signal ).view (1 , 1 , length_signal ).repeat (batch_size , length_signal , 1 )
85+ f = torch .sin (12 * x ) - torch .cos (14 * y ) + 3 * x * y
86+
87+
88+ # %%
89+ # Extending the signal
90+ # -----------------------------------------
91+ # We use the Fourier continuation layer to extend the signal
92+ # We try both extending the signal on one side (right and bottom) and on both sides (left, right, top, and bottom)
93+
94+ Extension = FCLegendre (n = 3 , d = add_pts )
95+ f_extend_one_side = Extension (f , dim = 2 , one_sided = True )
96+ f_extend_both_sides = Extension (f , dim = 2 , one_sided = False )
97+
98+
99+
100+ # %%
101+ # Plot the results
102+ # ----------------------
103+ # We also add black lines to deliminate the original signal
104+
105+ fig , axs = plt .subplots (figsize = (12 ,4 ), nrows = 1 , ncols = 3 )
106+ axs [0 ].imshow (f [0 ])
107+ axs [0 ].set_title (r"Original" , fontsize = 17 )
108+ axs [1 ].imshow (f_extend_one_side [0 ])
109+ axs [1 ].plot ([length_signal , length_signal ], [0 , length_signal ], '-' , color = 'k' , lw = 3 )
110+ axs [1 ].plot ([0 , length_signal ], [length_signal , length_signal ], '-' , color = 'k' , lw = 3 )
111+ axs [1 ].set_title (r"Extended one side" , fontsize = 17 )
112+ axs [2 ].imshow (f_extend_both_sides [0 ])
113+ axs [2 ].set_title (r"Extended both sides" , fontsize = 17 )
114+ axs [2 ].plot ([add_pts // 2 , length_signal + add_pts // 2 ], [add_pts // 2 , add_pts // 2 ], '-' , color = 'k' , lw = 3 )
115+ axs [2 ].plot ([add_pts // 2 , add_pts // 2 ], [add_pts // 2 , length_signal + add_pts // 2 ], '-' , color = 'k' , lw = 3 )
116+ axs [2 ].plot ([add_pts // 2 , length_signal + add_pts // 2 ], [length_signal + add_pts // 2 , length_signal + add_pts // 2 ], '-' , color = 'k' , lw = 3 )
117+ axs [2 ].plot ([length_signal + add_pts // 2 , length_signal + add_pts // 2 ], [add_pts // 2 , length_signal + add_pts // 2 ], '-' , color = 'k' , lw = 3 )
118+ for ax in axs .flat :
119+ ax .set_xticks ([])
120+ ax .set_yticks ([])
121+ plt .tight_layout ()
122+ plt .show ()
0 commit comments