greedy
srcgreedy は各振動子の位相を離散的な候補から 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,)?;greedy(geometry, foci, wavelength, intensities, order, option, dst)Holo.Greedy(geometry, foci, wavelength, intensities, order, option, dst);| 引数 | 型 | 説明 |
|---|---|---|
geometry |
&Geometry |
デバイス配置 |
foci |
&[AmplitudeTarget] |
焦点列 (位置と目標振幅) |
wavelength |
Length |
波長 |
intensities |
impl Into<PatternIntensity> |
振幅 (Intensity の一様値, または &[Vec<Intensity>] のデバイスごとのバッファ) |
order |
&[usize] |
振動子を訪問する順序 (通し番号の並び) |
option |
&GreedyOption |
追加オプション (下記参照) |
dst |
&mut [Vec<Phase>] |
位相の出力バッファ |
GreedyOption
Section titled “GreedyOption”GreedyOption { phase_quantization_levels, directivity, objective_func,}GreedyOption( phase_quantization_levels, directivity,)new GreedyOption{ PhaseQuantizationLevels = phaseQuantizationLevels, Directivity = directivity,}| フィールド | 型 | デフォルト |
|---|---|---|
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版のみ設定可能. 他の言語ではデフォルトの目的関数が使われる
Example
Section titled “Example”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,)?;import numpy as npfrom autd3.geometry import Autd3, Geometry, offsetfrom autd3.units import m, mm, sfrom autd3.value import Intensityfrom autd3_pattern import wavelengthfrom autd3_pattern_holo import ( AmplitudeTarget, Directivity, GreedyOption, Pa, greedy,)
geometry = Geometry([Autd3()])
order = np.random.default_rng().permutation(geometry.num_transducers())
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 * m / s), Intensity.MAX, order, GreedyOption( phase_quantization_levels=16, directivity=Directivity.Sphere, ), phases,)using System;using System.Linq;using AUTD3;using AUTD3.Holo;using static AUTD3.Units;using static AUTD3.Holo.HoloUnits;
var geometry = new Geometry(new[] { new Autd3() });
var order = Enumerable.Range(0, geometry.NumTransducers).Select(i => (uint)i).ToArray();Random.Shared.Shuffle(order);
var phases = geometry.PhaseBuffer();
Holo.Greedy( geometry, new[] { new AmplitudeTarget(geometry.Center + Offset(-30.0f * mm, 0.0f * mm, 150.0f * mm), 2.5e3f * Pa), new AmplitudeTarget(geometry.Center + Offset(30.0f * mm, 0.0f * mm, 150.0f * mm), 2.5e3f * Pa), }, Pattern.Wavelength(340.0f * m / s), Intensity.Max, order, new GreedyOption { PhaseQuantizationLevels = 16, Directivity = Directivity.Sphere, }, phases);