Holo
Holo is a set of Pattern computations for generating multiple focal points (control points) simultaneously. It optimizes the phase and amplitude of each transducer so that the target sound pressure is obtained at the specified multiple points.
The provided algorithms are as follows.
- Naive — single-step back-propagation
- GS — Gerchberg-Saxton method
- GS-PAT — GS-PAT method
- Greedy — combinatorial optimization that greedily determines the phase
Common Elements
Section titled “Common Elements”AmplitudeTarget
Section titled “AmplitudeTarget”A struct representing a focal point. It holds a position and a target amplitude.
Amplitude units Pa / kPa / dB
Section titled “Amplitude units Pa / kPa / dB”The target amplitude Amplitude is constructed by multiplying an f32 by an amplitude unit.
EmissionConstraint
Section titled “EmissionConstraint”The amplitude obtained from the optimization may be an intensity that the transducer cannot output as-is. Therefore, a constraint is specified for converting the amplitude obtained from the optimization into the transducer intensity to be output.
Normalize |
Normalizes by the maximum value |
Multiply(f32) |
Multiplies by a coefficient after normalization and clamps |
Uniform(Intensity) |
Sets all transducers to a constant intensity |
Clamp(Intensity, Intensity) |
Clamps the amplitude to the specified range |
It is specified via the constraint field of each Option.
The default differs depending on the algorithm.
Directivity
Section titled “Directivity”The directivity model of the transducer.
Either the omnidirectional Sphere (default) or the real-hardware directivity T4010A1 can be chosen.
It is specified via the directivity field of each Option.
TransducerMask
Section titled “TransducerMask”Selects the transducers to include in the optimization.
It is specified via the mask field of each Option (the default is AllEnabled).
TransducerMask::AllEnabled— uses all transducers (default).TransducerMask::Masked(&[Vec<bool>])— specifies enabled/disabled for each transducer individually.
LinAlgBackend (NalgebraBackend)
Section titled “LinAlgBackend (NalgebraBackend)”naive / gs / gspat delegate linear algebra operations to the LinAlgBackend trait.
NalgebraBackend is used as the standard implementation.
The backend is passed as the first argument of each function.
greedy does not use matrix operations, so it does not take a backend.
GPU Backend (WgpuBackend)
Section titled “GPU Backend (WgpuBackend)”WgpuBackend is a backend that performs calculations on the GPU.
The batch API
Section titled “The batch API”naive / gs / gspat each have a naive_batch / gs_batch / gspat_batch counterpart that solves several independent problems at once.
let problems = 64;let foci: Vec<AmplitudeTarget> = (0..problems) .map(|i| AmplitudeTarget { point: center + offset(i as f32 * 0.5 * mm, 0.0 * mm, 0.0 * mm), amplitude: 5e3 * Pa, }) .collect();
let mut dst = vec![geometry.pattern_buffer(); problems];gs_batch( &NalgebraBackend, &geometry, &foci, wavelength, &option, &mut dst,)?;The problem count is determined by the length of dst.
The foci are passed as a slice of length equal to the number of problems multiplied by the number of foci per problem.
An error is returned if the length of the slice is not divisible by the length of dst.
The gain comes from GPU backends, NalgebraBackend does not get faster.