def ssfm(f: AbstractFieldEquation, waves: np.ndarray, z: float, h: float ) -> np.ndarray: r"""Split step Fourier method. Parameters ---------- f : The function to compute. waves : The value of the unknown (waves) at the considered space step. z : The current value of the space variable. h : The step size. Returns ------- : The one step euler computation results. Notes ----- Equations: .. math:: \begin{align} A_j^{N} &= \exp\Big(h\hat{\mathcal{N}}\big(A_1(z,T), \ldots, A_j(z,T), \ldots, A_K(z,T)\big)\Big)A_j(z,T) &\forall j=1,\ldots,K\\ A_j(z+h,T) &= \exp\big(h\mathcal{D}\big)A_j^{N} &\forall j=1,\ldots,K \end{align} Implementation: .. math:: \begin{align} A_j^{N} &= \exp\Big(h\hat{\mathcal{N}\big(A_1(z),\ldots, A_j(z), \ldots, A_K(z)\big)\Big) A_j(z) &\forall j=1,\ldots,K\\ A_j(z+h) &= \mathcal{F}^{-1}\Big\{\exp\Big(h \hat{\mathcal{D}}\Big)\mathcal{F} \{A_j^{N}(z)\}\Big\} &\forall j=1,\ldots,K \end{align} where :math:`K` is the number of channels. """ A_N = np.zeros_like(waves) for i in range(len(waves)): A_N[i] = f.exp_term_non_lin(waves, i, z, h, waves[i]) for i in range(len(waves)): waves[i] = f.exp_term_lin(A_N, i, z, h) return waves
def rk4ip(f: AbstractFieldEquation, waves: np.ndarray, z: float, h: float) -> np.ndarray: r"""Runge-Kutta interaction picture method. Parameters ---------- f : The function to compute. waves : The value of the unknown (waves) at the considered space step. z : The current value of the space variable. h : The step size. Returns ------- : The one step euler computation results. Notes ----- Equations: .. math:: \begin{align} A^L_j &=\exp\Big(\frac{h}{2}\mathcal{D}\Big)A_j(z,T) &\forall j=1,\ldots,K\\ k_{0,j} &=\exp\Big(\frac{h}{2}\mathcal{D}\Big) \Big(h \bar{\mathcal{N}}\big(A_1(z,T), \ldots, A_j(z,T), \ldots,A_K(z,T)\big)\Big) &\forall j=1,\ldots,K\\ k_{1,j} &=h \bar{\mathcal{N}}\Big(A^L_{1} + \frac{k_{0,1}}{2},\ldots, A^L_{j} + \frac{k_{0,j}}{2}, \ldots, A^L_{K} + \frac{k_{0,K}}{2}\Big) &\forall j=1,\ldots,K\\ k_{2,j} &=h \bar{\mathcal{N}}\Big(A^L_{1} + \frac{k_{1,1}}{2},\ldots, A^L_{j} + \frac{k_{1,j}}{2}, \ldots, A^L_{K} + \frac{k_{1,K}}{2}\Big) &\forall j=1,\ldots,K\\ k_{3,j} &=h \bar{\mathcal{N}}\Big(\exp\Big(\frac{h}{2} \mathcal{D}\Big)(A^L_{1} + k_{2,1}, \ldots, A^L_{j} + k_{2,j}, \ldots, A^L_{K} + k_{2,K})\Big) &\forall j=1,\ldots,K\\ A_j(z+h,T) &=\frac{k_{3,j}}{6}+\exp\Big(\frac{h}{2} \mathcal{D}\Big)\Big(A^L_{j}+\frac{k_{0,j}}{6} +\frac{k_{1,j}}{3}+\frac{k_{2,j}}{3}\Big) \quad &\forall j=1,\ldots,K \end{align} Implementation: .. math:: \begin{align} A^L_{j} &= \mathcal{F}^{-1}\Big\{\exp\Big(\frac{h}{2} \hat{\mathcal{D}}\Big)\mathcal{F}\{A_j(z)\}\Big\} &\forall j=1,\ldots,K \\ k_{0,j} &= \mathcal{F}^{-1}\Big\{\exp\Big(\frac{h}{2} \hat{\mathcal{D}}\Big)\mathcal{F}\big\{h \hat{\mathcal{N}}\big(A_1(z), \ldots, A_j(z), \ldots,A_K(z)\big)\big\}\Big\} &\forall j=1,\ldots,K\\ k_{1,j} &= h \hat{\mathcal{N}}\Big(A^L_{1} + \frac{k_{0,1}}{2}, \ldots, A^L_{j} + \frac{k_{0,j}}{2}, \ldots, A^L_{K} + \frac{k_{0,K}}{2} \Big) &\forall j=1,\ldots,K\\ k_{2,j} &= h \hat{\mathcal{N}}\Big(A^L_{1} + \frac{k_{1,1}}{2}, \ldots, A^L_{j} + \frac{k_{1,j}}{2}, \ldots, A^L_{K} + \frac{k_{1,K}}{2} \Big) &\forall j=1,\ldots,K\\ k_{3,j} &= h \hat{\mathcal{N}}\Big(\mathcal{F}^{-1} \Big\{\exp\Big(\frac{h}{2}\hat{\mathcal{D}}\Big) \mathcal{F}\{A^L_{1} + k_{2,1}\} \Big\} , \ldots, \nonumber \\ & \qquad \qquad \mathcal{F}^{-1}\Big\{\exp\Big( \frac{h}{2}\hat{\mathcal{D}}\Big)\mathcal{F} \{A^L_{j} + k_{2,j}\}\Big\} ,\ldots, \nonumber \\ & \qquad \qquad \mathcal{F}^{-1}\Big\{\exp\Big( \frac{h}{2}\hat{\mathcal{D}} \Big)\mathcal{F} \{A^L_{K} + k_{2,K}\}\Big\} \Big) &\forall j=1,\ldots,K\\ A_j(z+h) &= \frac{k_{3,j}}{6}+\mathcal{F}^{-1}\Big\{ \exp\Big(\frac{h}{2}\hat{\mathcal{D}}\Big) \mathcal{F}\big\{A^L_{j} +\frac{k_{0,j}}{6}+\frac{k_{1,j}}{3} +\frac{k_{2,j}}{3}\big\}\Big\} \quad &\forall j=1,\ldots,K \end{align} where :math:`K` is the number of channels. """ h_h = 0.5 * h A_L = np.zeros_like(waves) k_0 = np.zeros_like(waves) k_1 = np.zeros_like(waves) k_2 = np.zeros_like(waves) k_3 = np.zeros_like(waves) for i in range(len(waves)): A_L[i] = f.exp_term_lin(waves, i, z, h_h) for i in range(len(waves)): waves[i] = h * f.term_non_lin(waves, i, z) for i in range(len(waves)): k_0[i] = f.exp_term_lin(waves, i, z, h_h) for i in range(len(waves)): waves[i] = A_L[i] + 0.5*k_0[i] for i in range(len(waves)): k_1[i] = h * f.term_non_lin(waves, i, z) for i in range(len(waves)): waves[i] = A_L[i] + 0.5*k_1[i] for i in range(len(waves)): k_2[i] = h * f.term_non_lin(waves, i, z) for i in range(len(waves)): waves[i] = A_L[i] + k_2[i] waves[i] = f.exp_term_lin(waves, i, z, h_h) for i in range(len(waves)): k_3[i] = h * f.term_non_lin(waves, i, z) for i in range(len(waves)): waves[i] = A_L[i] + (k_0[i]/6.0) + ((k_1[i]+k_2[i])/3.0) waves[i] = (k_3[i]/6.0) + f.exp_term_lin(waves, i, z, h_h) return waves
def ssfm_opti_super_sym(f: AbstractFieldEquation, waves: np.ndarray, z: float, h: float) -> np.ndarray: r"""Optimized super symmetric split step Fourier method. Parameters ---------- f : The function to compute. waves : The value of the unknown (waves) at the considered space step. z : The current value of the space variable. h : The step size. Returns ------- : The one step euler computation results. Notes ----- Equations: .. math:: \begin{align} A_j^{L} &= \exp\Big(\frac{h}{2}\mathcal{D}\Big)A_j(z, T) &\forall j=1,\ldots,K\\ A_j^{N'} &= A_j^{L} +\frac{h}{2}\bar{\mathcal{N}}\big( A_1^{N'},\ldots, A_{j-1}^{N'}, A_{j}^{L}, \ldots, A_K^{L}\big) &\forall j=1,\ldots,K\\ A_j^{N} &= A_j^{N'} +\frac{h}{2}\bar{\mathcal{N}}\big( A_1^{N'},\ldots, A_{j}^{N'}, A_{j+1}^{N}, \ldots, A_K^{N}\big)&\forall j=K,\ldots,1\\ A_j(z+h, T) &= \exp\Big(\frac{h}{2}\mathcal{D}\Big) A_j^{N} &\forall j=1,\ldots,K \end{align} Implementation: .. math:: \begin{align} A_j^{L} &= \mathcal{F}^{-1}\Big\{\exp\Big(\frac{h}{2} \hat{\mathcal{D}}\Big)\mathcal{F}\{A_j(z)\}\Big\} &\forall j=1,\ldots,K\\ A_j^{N'} &= \exp\Big(\frac{h}{2}\hat{\mathcal{N}} \big(A_1^{N'},\ldots, A_{j-1}^{N'}, A_{j}^{L}, \ldots, A_K^{L}\big)\Big) A_j^{L} &\forall j=1,\ldots,K\\ A_j^{N} &= \exp\Big(\frac{h}{2}\hat{\mathcal{N}} \big(A_1^{N'},\ldots, A_{j}^{N'}, A_{j+1}^{N}, \ldots, A_K^{N}\big)\Big) A_j^{N'} &\forall j=K,\ldots,1 \\ A_j(z+h) &= \mathcal{F}^{-1}\Big\{\exp\Big(\frac{h}{2} \hat{\mathcal{D}}\Big)\mathcal{F}\{A_j^{N}\}\Big\} &\forall j=1,\ldots,K \end{align} where :math:`K` is the number of channels. """ h_h = 0.5 * h for i in range(len(waves)): waves[i] = f.exp_term_lin(waves, i, z, h_h) for i in range(len(waves)-1): waves[i] = f.exp_term_non_lin(waves, i, z, h_h, waves[i]) waves[-1] = f.exp_term_non_lin(waves, len(waves)-1, z, h, waves[-1]) for i in range(len(waves)-2, -1, -1): waves[i] = f.exp_term_non_lin(waves, i, z, h_h, waves[i]) for i in range(len(waves)): waves[i] = f.exp_term_lin(waves, i, z, h_h) return waves