Optimization

Procedures and algorithms for numerical optimization.

The main method currently in use for acoustic levitation (in this package) is nonlinear numerical minimization of a cost function. The cost funcion should be constructed using the fields module.

levitate.optimization.phase_alignment(*states, method='parallel', output='states')

Align independet states with respect to the global phase.

Parameters
  • *states (arrary_like) – The states to align. THis can be passed in as a sequence of arguments, of as a (P, N)-shaped array, where P is the number of states and N is the number of elements in each state.

  • method (str, optional, keyword-only) – Which method to use for the alignment, default ‘parallel’. Should be one of ‘parallel’ or ‘sequential’, see below for description.

  • output (str, optional, keyword-only) – What the function should return, default ‘states’. The string should contain some combination of ‘states’ and/or ‘phases’. The funtion will return the aligned states and/or the obtained phases in the order found in the string. If only one of ‘states’ or ‘phases’ is found, only that one will be returned.

A single state for an array is only unique up to a global phase. When multiple states are considered, the global phase of each state can be shifted to minimize the difference between the states. This function takes a number of states and finds the optimal phase shifts for each of the states. This can operate in two distinct modes, a parallel mode and a sequential mode.

Method 'parallel' minimizes the sum of all magnitude differences of the states

\[\sum_k \sum_l || S_k e^{i\phi_k} - S_l e^{i\phi_l} ||^2\]

or equivalently, maximizes the sum of the states

\[|| \sum_k S_k e^{i\phi_k} ||^2.\]

Explicitly, this is done by numerically minimizing the cost function

\[O = \Re\{c A c^*\}\]

where \(c\) is a vector with the phases written on complex form, and \(A[i,j] = -\sum_n S_i[n] S_j^*[n] (1 - \delta_{ij})\). This is suitable for superposition, where we want the states to have the most power output.

Method sequential minimizes the difference between consecutive states in an iterative fashion. In each step, the difference

\[||S_k e^{i\phi_k} - S_{k-1} e^{i\phi_{k-1}}||\]

is minimized. This is done explicitly as

\[\phi_k = \phi_{k-1} - \arg\{ \sum_n S_k[n] S_{n-1}^*[n] \}\]

with \(\phi_0 = 0\). This procedure is suitable for state transitions, where the difference between non-consecutive states is irrelevant.

levitate.optimization.minimize(functions, array, start_values=None, use_real_imag=False, constrain_transducers=None, variable_amplitudes=False, callback=None, precall=None, basinhopping=False, minimize_kwargs=None, return_optim_status=False)

Minimizes a set of cost functions.

The cost function should have the signature f(complex_amplitudes) where complex_amplitudes is an ndarray with weight of each element in the transducer array. The function should return value, jacobians where the jacobians are the derivatives of the value w.r.t the transducers as defined in the full documentation. Also see the documentation of the field wrappers for further details.

This function supports minimization sequences. Pass an iterable of functions to start sequenced minimization, e.g. a list of cost functions. The arguments: use_real_imag, variable_amplitudes, constrain_transducers, callback, precall, basinhopping, and minimize_kwargs can be given as single values or as iterables of the same length as functions.

Parameters
  • functions – The cost function that should be minimized. A single callable, or an iterable of callables, as described above.

  • array (TransducerArray) – The array from which the cost functions are created.

  • start_values (complex ndarray, optional) – The start values for the optimization. Will default to 1 for all transducers if not given. Note that the precall for minimization sequences can overrule this value.

  • use_real_imag (bool, default False) – Toggles if the optimization should run using the phase-amplitude formulation or the real-imag formulation.

  • constrain_transducers (array_like) – Specifies a number of transducers which are constant elements in the minimization. Will be used as the second argument in np.delete

  • variable_amplitudes (bool) – Toggles the usage of varying amplitudes in the minimization. If use_real_imag is False ‘phases first’ is also a valid argument for this parameter. The minimizer will then automatically sequence to optimize first with fixed then with variable amplitudes, returning only the last result.

  • callback (callable) – A callback function which will be called after each step in sequenced minimization. Return false from the callback to break the sequence. Should have the signature : callback(array=array, result=result, optim_status=opt_res, idx=idx)

  • precall (callable) – Initialization function which will be called with the array phases, amplitudes, and the sequence index before each sequence step. Must return the initial phases and amplitudes for the sequence step. Default sets the phases and amplitudes to the solution of the previous sequence step, or the original state for the first iteration. Should have the signature : precall(complex_amplitudes, idx)

  • basinhopping (bool or int) – Specifies if basinhopping should be used. Pass an int to specify the number of basinhopping iterations, or True to use default value.

  • return_optim_status (bool) – Toggles the optim_status output.

  • minimize_kwargs (dict) – Extra keyword arguments which will be passed to scipy.minimize.

Returns

  • result (ndarray) – The array phases and amplitudes after minimization. Stacks sequenced results in the first dimension.

  • optim_status (OptimizeResult) – Scipy optimization result structure. Optional output, toggle with the corresponding input argument.