[Rust / Python] Condition aux limites périodique

Envisagez d'imposer une condition aux limites périodique sur le réel $ \ mathbb {R} $ avec une période de $ b> 0 $ ($ \ mathbb {R} / b \ mathbb {R} $), soit deux nombres $ x $. Et $ x + b $ sont assimilés, comme une représentation unique des coordonnées correspondant à n'importe quel nombre $ x \ in \ mathbb {R} $.

Implémentation de Rust

Cliquez ici pour consulter l'intégralité du code et de la vérification du fonctionnement: [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 pour% 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! Chèque1 (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% 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

Dans Rust, le reste «x% b» a le même signe que «x», donc si «x» est positif, alors «x% b» convient, sinon «b» doit être ajouté. ..

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

Au début, j'utilisais f64 :: is_sign_negative, mais suite à des problèmes de gestion de -0,0, je suis arrivé à la conclusion que l'inégalité devrait être utilisée.

-b/2 ≦ x < b/2

Dans ce cas, vous pouvez calculer (x / b + 0.5) .floor () pour savoir combien de fois b doit être utilisé pour déplacer x vers la section souhaitée.

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

Implémentation Python

Le code suivant peut être utilisé avec l'entrée x is float ou np.ndarray. Vérifiez l'opération ici: Paiza

0 ≦ x < b

En Python, le reste est défini pour satisfaire $ 0 \ leq x % b <b $ (maintenant $ b> 0 $), donc c'est un tir.

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

-b/2 ≦ x < b/2

Cela réécrit simplement l'implémentation Rust ci-dessus en Python.

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

Recommended Posts

[Rust / Python] Condition aux limites périodique
bases de python: conditions et itérations
[Python] Tri itérable selon plusieurs conditions