コンテンツにスキップ

greedy

src

greedy は各振動子の位相を離散的な候補から 1 つずつ貪欲に選択していく組合せ最適化. アルゴリズムは Suzuki らの論文 (Suzuki et al., 2021) に基づく.

greedy が最適化するのは位相だけで, 振幅は最適化しない. 振幅は intensities で与え, greedy はその振幅を前提に位相を決める. intensities には全振動子共通の一様値 (Intensity) と, 振動子ごとのバッファの両方を渡せる. 振幅が 0 の振動子は探索から外れ, 位相は 0 になる.

振動子を訪問する順序を order で与える必要がある. 番号は Geometry 全体の通し番号 (デバイス順に 0 から geometry.num_transducers() - 1 まで) で, order には全振動子をちょうど 1 回ずつ含む並びを渡す. なお, 振動子は無作為な順に選ぶのが推奨されるため, 通常は乱数でシャッフルした並びを渡すこと.

greedy(
&geometry,
&foci,
wavelength,
&intensities,
&order,
&option,
&mut dst,
)?;
引数 型 説明
geometry &Geometry デバイス配置
foci &[AmplitudeTarget] 焦点列 (位置と目標振幅)
wavelength Length 波長
intensities impl Into<PatternIntensity> 振幅 (Intensity の一様値, または &[Vec<Intensity>] のデバイスごとのバッファ)
order &[usize] 振動子を訪問する順序 (通し番号の並び)
option &GreedyOption 追加オプション (下記参照)
dst &mut [Vec<Phase>] 位相の出力バッファ
GreedyOption {
phase_quantization_levels,
directivity,
objective_func,
}
フィールド 型 デフォルト
phase_quantization_levels NonZeroU8 16
directivity Directivity Sphere
objective_func fn(Complex<f32>, Amplitude) -> f32 abs_objective_func
  • phase_quantization_levels — 位相候補の分割数. 大きいほど位相分解能が上がる.
  • objective_func — 各候補を評価する目的関数. デフォルトの abs_objective_func は, 合成音圧の大きさと目標振幅の差の絶対値を返す.
    • Rust版のみ設定可能. 他の言語ではデフォルトの目的関数が使われる
use std::num::NonZeroU8;
use rand::seq::SliceRandom;
use autd3_rs::geometry::{Autd3, Geometry, offset};
use autd3_rs::units::{m, mm, s};
use autd3_rs::value::Intensity;
use autd3_rs_pattern::wavelength;
use autd3_rs_pattern_holo::{
AmplitudeTarget, Directivity, GreedyOption, Pa, abs_objective_func, greedy,
};
let geometry = Geometry::new(vec![Autd3::default()]);
let mut order: Vec<usize> = (0..geometry.num_transducers()).collect();
order.shuffle(&mut rand::rng());
let mut phases = geometry.phase_buffer();
greedy(
&geometry,
&[
AmplitudeTarget {
point: geometry.center() + offset(-30.0 * mm, 0.0 * mm, 150.0 * mm),
amplitude: 2.5e3 * Pa,
},
AmplitudeTarget {
point: geometry.center() + offset(30.0 * mm, 0.0 * mm, 150.0 * mm),
amplitude: 2.5e3 * Pa,
},
],
wavelength(340.0 * m / s),
Intensity::MAX,
&order,
&GreedyOption {
phase_quantization_levels: NonZeroU8::new(16).unwrap(),
directivity: Directivity::Sphere,
objective_func: abs_objective_func,
},
&mut phases,
)?;