[Rust / Python] Periodische Randbedingung

Erwägen Sie, dem realen $ \ mathbb {R} $ eine periodische Randbedingung mit einer Periode von $ b> 0 $ ($ \ mathbb {R} / b \ mathbb {R} $) aufzuerlegen, dh zwei Zahlen $ x $. Und $ x + b $ werden als eindeutige Darstellung der Koordinaten gleichgesetzt, die einer beliebigen Zahl $ x \ in \ mathbb {R} $ entsprechen.

Rostimplementierung

Klicken Sie hier, um den gesamten Code und die Funktionsprüfung anzuzeigen: [PlayGround](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=extern%20crate%20rand%3B%20%2F%2F%200.7.3 % 0Ause% 20rand% 3A% 3A% 7BRng% 2C% 20thread_rng% 7D% 3B% 0A% 0Afn% 20main ()% 20% 7B% 0A% 20% 20% 20% 20let% 20mut% 20rng% 20% 3D% 20thread_rng ()% 3B% 0A% 20% 20% 20% 20let% 20b% 20% 3D% 201,57% 3B% 0A% 20% 20% 20% 20% 0A% 20% 20% 20% 20 für% 20_% 20in% 200 128% 20% 7B% 0A% 20% 20% 20% 20% 20% 20% 20% 20let% 20x% 20% 3D% 20rng.gen_range (-6.% 2C% 206.)% 3B% 0A% 20% 20% 20% 20% 20% 20% 20% 20if% 20! Check1 (x% 2C% 20b)% 20% 7B% 20 println! (% 221% 3A% 20pbc (% 7B% 3A.03% 7D)) % 20% 3D% 20% 7B% 7D% 22% 2C% 20x% 2C% 20pbc1 (x% 2C% 20b))% 3B% 20% 7D% 3B% 0A% 20% 20% 20% 20% 20% 20% 20% 20 % 20% 20if% 20! Check2 (x% 2C% 20b)% 20% 7B% 20println! (% 222% 3A% 20pbc (% 7B% 3A.03% 7D)% 20% 3D% 20% 7B% 7D% 22% 2C% 20x% 2C% 20pbc2 (x% 2C% 20b))% 3B% 20% 7D% 3B% 0A% 20% 20% 20% 20% 7D% 0A% 7D% 0A% 0A% 0A% 23% 5Binline% 5D% 0Afn% 20pbc1 (x% 3A% 20f64% 2C% 20b% 3A% 20f64)% 20-% 3E% 20f64% 20% 7B% 0A% 20% 20% 20% 20let% 20dx% 20% 3D% 20x% 25b% 3B% 0A% 20% 20% 20% 20if% 20dx% 20% 3E% 3D% 200.% 20% 7B% 20dx% 20% 7D% 20else% 20% 7B% 20dx% 20% 2B% 20b % 20% 7D% 0A% 7D% 0A% 0A% 23% 5Binline% 5D% 0 Afn% 20pbc2 (x% 3A% 20f64% 2C% 20b% 3A% 20f64)% 20-% 3E% 20f64% 20% 7B% 0A% 20% 20% 20% 20x% 20-% 20 (x% 2Fb% 20) % 2B% 200,5) .floor () * b% 0A% 7D% 0A% 0A% 0A% 23% 5Binline% 5D% 0Afn% 20check1 (x% 3A% 20f64% 2C% 20b% 3A% 20f64)% 20-% 3E% 20bool% 20% 7B% 0A% 20% 20% 20% 20let% 20x% 20% 3D% 20pbc1 (x% 2C% 20b)% 3B% 0A% 20% 20% 20% 20% 0A% 20% 20 % 20% 20 (% 20x% 20% 3E% 3D% 200.% 20)% 26 (% 20x% 20% 3C% 20b% 20)% 0A% 7D% 0A% 0A% 23% 5Binline% 5D% 0Afn% 20check2 (x% 3A% 20f64% 2C% 20b% 3A% 20f64)% 20-% 3E% 20bool% 20% 7B% 0A% 20% 20% 20% 20let% 20x% 20% 3D% 20pbc2 (x% 2C%) 20b)% 3B% 0A% 20% 20% 20% 20% 0A% 20% 20% 20% 20 (% 20x% 20% 3E% 3D% 20-b% 2F2.% 20)% 26 (% 20x% 20) % 3C% 20b% 2F2.% 20)% 0A% 7D% 0A% 0A)

0 ≦ x < b

In Rust hat der Rest "x% b" das gleiche Vorzeichen wie "x". Wenn also "x" positiv ist, ist "x% b" in Ordnung, andernfalls müssen Sie "b" hinzufügen. ..

#[inline]
fn pbc1(x: f64, b: f64) -> f64 {
    let dx = x%b;
    if dx >= 0. { dx } else { dx + b }
}

Zuerst habe ich f64 :: is_sign_negative verwendet, aber aufgrund von Problemen beim Umgang mit -0.0 bin ich zu dem Schluss gekommen, dass Ungleichung verwendet werden sollte.

-b/2 ≦ x < b/2

In diesem Fall können Sie "(x / b + 0,5) .floor ()" berechnen, um herauszufinden, wie oft "b" verwendet werden sollte, um "x" in den gewünschten Abschnitt zu verschieben.

#[inline]
fn pbc2(x: f64, b: f64) -> f64 {
    x - (x/b + 0.5).floor()*b
}

Python-Implementierung

Der folgende Code kann entweder mit der Eingabe "x" ist float oder "np.ndarray" verwendet werden. Überprüfen Sie die Operation hier: Paiza

0 ≦ x < b

In Python ist der Rest so eingestellt, dass er $ 0 \ leq x % b <b $ (jetzt $ b> 0 $) erfüllt, also ist es ein Schuss.

def pbc1(x, b):
    return x%b

-b/2 ≦ x < b/2

Dies schreibt nur die obige Rust-Implementierung in Python um.

def pbc2(x, b):
    return x - np.floor(x/b + 0.5)*b

Recommended Posts

[Rust / Python] Periodische Randbedingung
Python-Grundlagen: Bedingungen und Iterationen
[Python] Sortierbar nach mehreren Bedingungen sortieren