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} $.
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
}
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