motulator_gradnet
=================

.. py:module:: motulator_gradnet

.. autoapi-nested-parse::

   
   Training of gradient networks (GradNets) for the magnetic models of motulator.

   GradNets model the current and flux linkage maps of synchronous machines, including
   spatial harmonics, learned from measured or finite-element data [#Li2026]_. A GradNet
   is the gradient of a scalar state function, the magnetic energy or co-energy, so the
   map is a conservative vector field by construction [#Cha2025]_, and the monotonicity of
   the flux-linkage--current map is also ensured. The networks are defined and trained
   with PyTorch (`GradNet`, `train_gradnet`). A trained network is saved as the numpy
   function `motulator.drive.gradnet.GradNetFunction`, which the magnetic maps of
   motulator (e.g., `motulator.drive.gradnet.FluxMap`) evaluate without PyTorch. The
   trained maps are compared with the data using the plotting and error functions.

   .. rubric:: References

   .. [#Li2026] Li, Foissner, Martin, Piippo, Hinkkanen, "Gradient networks for universal
      magnetic modeling of synchronous machines," 2026, https://arxiv.org/abs/2602.14947

   .. [#Cha2025] Chaudhari, Pranav, Moura, "Gradient networks," IEEE Trans. Signal
      Process., 2025, https://doi.org/10.1109/TSP.2024.3496692















   ..
       !! processed by numpydoc !!


Classes
-------

.. autoapisummary::

   motulator_gradnet.AlgebraicSigmoid
   motulator_gradnet.GradNet
   motulator_gradnet.PNormGradient
   motulator_gradnet.PlotOptions
   motulator_gradnet.Softmax
   motulator_gradnet.Squareplus


Functions
---------

.. autoapisummary::

   motulator_gradnet.get_training_data
   motulator_gradnet.plot_output_vs_angle
   motulator_gradnet.plot_surface_vs_current_and_angle
   motulator_gradnet.print_current_map_errors_meas
   motulator_gradnet.print_flux_map_errors_meas
   motulator_gradnet.to_function
   motulator_gradnet.train_gradnet


Package Contents
----------------

.. py:class:: AlgebraicSigmoid(beta_log0 = -3.0)

   Bases: :py:obj:`torch.nn.Module`


   
   Sigmoid-type activation function with one learnable parameter.
















   ..
       !! processed by numpydoc !!

.. py:class:: GradNet(in_dim = 2, mu_dim = 2, num_modules = 1, embed_dim = 12, activation = Softmax, mu_log0 = 1.0, psi_base = 1.0, i_base = 1.0)

   Bases: :py:obj:`torch.nn.Module`


   
   Modular and monotone gradient network.

   :param in_dim: Input dimension, defaults to 2.
   :type in_dim: int, optional
   :param mu_dim: Dimension of the linear term, defaults to 2.
   :type mu_dim: int, optional
   :param num_modules: Number of GradNet modules, defaults to 1.
   :type num_modules: int, optional
   :param embed_dim: Embedding dimension for the GradNet modules, defaults to 12.
   :type embed_dim: int, optional
   :param activation: Activation factory used by GradNet modules, defaults to Softmax.
   :type activation: Callable[[], nn.Module], optional
   :param mu_log0: Initial value for the linear term coefficients in log-domain, defaults to 1.0.
   :type mu_log0: float, optional
   :param psi_base: Base value of the flux linkage (Vs), defaults to 1.0. The network operates in
                    per-unit quantities. The base values are stored in the model and used by the
                    maps of motulator (e.g., `~motulator.drive.gradnet.CurrentMap`) to convert
                    between SI units and per-unit quantities.
   :type psi_base: float, optional
   :param i_base: Base value of the current (A), defaults to 1.0.
   :type i_base: float, optional















   ..
       !! processed by numpydoc !!

.. py:class:: PNormGradient(dim = -1, p = 8, beta_log0 = 0.0, freeze_beta = False)

   Bases: :py:obj:`torch.nn.Module`


   
   p-norm gradient activation function.

   Defined as the gradient of S(z) = (1 + sum((beta*z_n)**p))**(1/p)/beta, where p is a
   positive even integer. This potential function corresponds to a smooth p-norm, which
   is convex, thus guaranteeing monotonicity.















   ..
       !! processed by numpydoc !!

.. py:class:: PlotOptions

   
   Options for plotting functions.

   :param base: Base values for per-unit conversion. If None, SI values are used.
   :type base: ~motulator.drive.utils.BaseValues | None, optional
   :param lims: Axis limits as {'x': (xmin, xmax), 'y': (ymin, ymax)}.
   :type lims: dict[str, tuple[float, float]] | None, optional
   :param ticks: Axis ticks as {'x': [x1, x2, ...], 'y': [y1, y2, ...]}.
   :type ticks: dict[str, list[float]] | None, optional
   :param surface_cmap: Colormap for the surface plot, defaults to "viridis".
   :type surface_cmap: str, optional
   :param latex: Use LaTeX fonts if True, defaults to False.
   :type latex: bool, optional
   :param save_path: Path to save the figure. If None, the figure is not saved.
   :type save_path: str | Path | None, optional
   :param savefig_kwargs: Additional keyword arguments passed to plt.savefig().
   :type savefig_kwargs: Dict[str, Any], optional
   :param loci_levels_source: Source for constant-loci levels in `plot_surface_vs_current_and_angle()` when
                              plotting over current and angle. If "ticks", uses `ticks["x"]`/`ticks["y"]`
                              (with lims/fallback defaults). If "val" or "trn", uses unique x/y values
                              present in the corresponding point cloud slice.
   :type loci_levels_source: {"ticks", "val", "trn"}, optional















   ..
       !! processed by numpydoc !!

.. py:class:: Softmax(dim = -1, beta_log0 = 2.0, freeze_beta = False)

   Bases: :py:obj:`torch.nn.Module`


   
   Softmax activation function.
















   ..
       !! processed by numpydoc !!

.. py:class:: Squareplus(beta_log0 = -2.0)

   Bases: :py:obj:`torch.nn.Module`


   
   Rectifier-type activation function with one learnable parameter.
















   ..
       !! processed by numpydoc !!

.. py:function:: get_training_data(dataset_path, base, subsample = 1, other_keys = None)

   
   Get the training and validation data used by the model.

   This function re-instantiates the dataset with the same parameters to reproduce
   the training set. Validation data is the set difference (complement).

   :param dataset_path: Path to the npz file containing the dataset.
   :type dataset_path: str
   :param base: Base values of the target machine. They are only needed to re-instantiate the
                dataset; the returned data are not normalized.
   :type base: ~motulator.drive.utils.BaseValues
   :param subsample: Subsampling rate used in the training, defaults to 1 (no subsampling).
   :type subsample: int, optional
   :param other_keys: Additional fields of the npz file to be returned after the flux linkage and
                      current, defaults to None (no additional fields).
   :type other_keys: list[str] | None, optional

   :returns: ((train_psi, train_i, ...), (val_psi, val_i, ...)), where the arrays are
             flattened and in the units of the npz file.
   :rtype: tuple















   ..
       !! processed by numpydoc !!

.. py:function:: plot_output_vs_angle(fixed_value, theta_m_range, map_fcn, output = 'tau_m', input_type = 'i_s_dq', val_data = None, trn_data = None, opts = None)

   
   Plot torque or flux linkage as a function of angle at a fixed input.

   :param fixed_value: Fixed complex input value (e.g., i_s_dq or psi_s_dq).
   :type fixed_value: complex
   :param theta_m_range: Electrical rotor angle range (rad).
   :type theta_m_range: np.ndarray
   :param map_fcn: Flux or current map function with harmonics.
   :type map_fcn: Callable
   :param output: Output quantity to plot, defaults to "tau_m".
   :type output: {"psi_d", "psi_q", "tau_m"}, optional
   :param input_type: Type of the fixed input value, defaults to "i_s_dq".
   :type input_type: {"i_s_dq", "psi_s_dq"}, optional
   :param val_data: Validation data tuple containing (psi_s_dq, i_s_dq, theta_m, tau_m).
   :type val_data: tuple, optional
   :param trn_data: Training data tuple containing (psi_s_dq, i_s_dq, theta_m, tau_m).
   :type trn_data: tuple, optional
   :param opts: Plotting options.
   :type opts: PlotOptions, optional















   ..
       !! processed by numpydoc !!

.. py:function:: plot_surface_vs_current_and_angle(current_range, fixed_value, theta_m_range, map_fcn, input = 'i_q', output = 'tau_m', val_data = None, trn_data = None, opts = None)

   
   Plot selected output component vs selected input component over angle.

   :param current_range: Range of input values to vary.
   :type current_range: np.ndarray
   :param fixed_value: Fixed input value for the other axis.
   :type fixed_value: float
   :param theta_m_range: Electrical rotor angle range (rad).
   :type theta_m_range: np.ndarray
   :param map_fcn: Flux or current map function with harmonics.
   :type map_fcn: Callable
   :param input: Input axis to vary, defaults to "i_q".
   :type input: {"i_d", "i_q", "psi_d", "psi_q"}, optional
   :param output: Output quantity to plot, defaults to "tau_m".
   :type output: {"psi_d", "psi_q", "tau_m", "i_d", "i_q"}, optional
   :param val_data: Validation data tuple containing (psi_s_dq, i_s_dq, theta_m, tau_m).
   :type val_data: tuple, optional
   :param trn_data: Training data tuple containing (psi_s_dq, i_s_dq, theta_m, tau_m).
   :type trn_data: tuple, optional
   :param opts: Plotting options.
   :type opts: PlotOptions, optional















   ..
       !! processed by numpydoc !!

.. py:function:: print_current_map_errors_meas(current_map, data, base = None)

   
   Print error metrics for a measured current map.
















   ..
       !! processed by numpydoc !!

.. py:function:: print_flux_map_errors_meas(flux_map, data, base = None)

   
   Print error metrics for a measured flux map.
















   ..
       !! processed by numpydoc !!

.. py:function:: to_function(model)

   
   Convert a trained model to the numpy function of motulator.

   The modules of the model must have the same activation, one of `ACTIVATIONS`
   applied along the last axis (the default), with the same exponent `p`. The
   function is evaluated in double precision. It is saved to an npz file by its
   method `save` and loaded by `motulator.drive.gradnet.load_gradnet`.

   :param model: Trained model.
   :type model: GradNet

   :returns: The model as a numpy function.
   :rtype: ~motulator.drive.gradnet.GradNetFunction















   ..
       !! processed by numpydoc !!

.. py:function:: train_gradnet(dataset_path, base, is_flux_map=False, k = None, num_modules = 1, embed_dim = 12, batch_size = 128, epochs = 2000, lr = 0.001, save_model_path = None, subsample = 1, activation = None, device = None, *, i_low = 0.0, weight_low = 1.0)

   
   Train and save the GradNet model.

   :param dataset_path: Path to the training data file (npz format).
   :type dataset_path: str | Path
   :param base: Base values of the target machine. The training data are normalized with the
                base current and flux linkage, which are also stored in the model.
   :type base: ~motulator.drive.utils.BaseValues
   :param is_flux_map: Whether the model is a flux map or current map, defaults to False.
   :type is_flux_map: bool, optional
   :param k: Spatial harmonics order. If None, no harmonics are used, defaults to None.
   :type k: int | None, optional
   :param num_modules: Number of GradNet modules, defaults to 1.
   :type num_modules: int, optional
   :param embed_dim: Embedding dimension for the GradNet modules, defaults to 12.
   :type embed_dim: int, optional
   :param batch_size: Batch size for training, defaults to 128.
   :type batch_size: int, optional
   :param epochs: Number of training epochs, defaults to 2000.
   :type epochs: int, optional
   :param lr: Learning rate for the optimizer, defaults to 1e-3.
   :type lr: float, optional
   :param save_model_path: Path to save the trained model as an npz file (see `to_function`). If None,
                           saves to `model.npz` in current directory.
   :type save_model_path: str | Path | None, optional
   :param subsample: Subsampling factor for the training data, defaults to 1 (uses all data).
   :type subsample: int, optional
   :param activation: Activation function factory, defaults to PNormGradient. The trained model is
                      saved as a numpy function, which supports the activations in `ACTIVATIONS`.
   :type activation: Callable[[], torch.nn.Module] | None, optional
   :param device: Device to use for training. If None, automatically selects CUDA if available,
                  otherwise CPU.
   :type device: torch.device | None, optional
   :param i_low: Current limit (A, peak value) defining the low-current region, defaults to 0.
   :type i_low: float, optional
   :param weight_low: Loss weight of the data points whose current magnitude is below `i_low`,
                      defaults to 1 (unweighted loss). The low-current region is determined by the
                      current of the data point for both flux and current maps. A weight above 1
                      improves the accuracy at low currents, where a uniform data grid gives only a
                      few points. The weights are normalized with their mean over the training set,
                      so the loss of each batch is an unbiased estimate of the weighted loss of the
                      whole set, which corresponds to repeating those points `weight_low` times in the
                      dataset, except that the number of steps per epoch is unchanged.
   :type weight_low: float, optional















   ..
       !! processed by numpydoc !!

