Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
No results found
Show changes
Commits on Source (7)
//! Jacobi Stencil Iterations
//!
//! This module performs the Jacobi method for solving Laplace's differential equation.
use std::time::Instant; use std::time::Instant;
use std::vec; use std::{mem, vec};
use rayon::prelude::*; use rayon::prelude::*;
const SIZE: usize = if cfg!(debug_assertions) { 16 } else { 64 }; const SIZE: usize = if cfg!(debug_assertions) { 16 } else { 64 };
const ITERATIONS: usize = 1000;
pub fn laplace() { pub fn laplace() {
eprintln!(); eprintln!();
let matrix = matrix_setup(SIZE, SIZE); let mut matrix = matrix_setup(SIZE, SIZE);
eprintln!("Laplace iterations"); eprintln!("Laplace iterations");
let now = Instant::now(); let now = Instant::now();
let (i, residual) = compute(matrix, SIZE, SIZE); let residual = compute(&mut matrix, SIZE, SIZE, ITERATIONS);
let elapsed = now.elapsed(); let elapsed = now.elapsed();
eprintln!("{i} iterations: {elapsed:?} (residual: {residual})"); eprintln!("{ITERATIONS} iterations: {elapsed:?} (residual: {residual})");
assert!(residual < 0.001); assert!(residual < 0.001);
} }
fn matrix_setup(size_x: usize, size_y: usize) -> vec::Vec<vec::Vec<f64>> { fn matrix_setup(size_x: usize, size_y: usize) -> vec::Vec<f64> {
let mut matrix = vec![vec![0.0; size_x * size_y]; 2]; let mut matrix = vec![0.0; size_x * size_y];
// top row // top row
for x in 0..size_x { for f in matrix.iter_mut().take(size_x) {
matrix[0][x] = 1.0; *f = 1.0;
matrix[1][x] = 1.0;
} }
// bottom row // bottom row
for x in 0..size_x { for x in 0..size_x {
matrix[0][(size_y - 1) * size_x + x] = 1.0; matrix[(size_y - 1) * size_x + x] = 1.0;
matrix[1][(size_y - 1) * size_x + x] = 1.0;
} }
// left row // left row
for y in 0..size_y { for y in 0..size_y {
matrix[0][y * size_x] = 1.0; matrix[y * size_x] = 1.0;
matrix[1][y * size_x] = 1.0;
} }
// right row // right row
for y in 0..size_y { for y in 0..size_y {
matrix[0][y * size_x + size_x - 1] = 1.0; matrix[y * size_x + size_x - 1] = 1.0;
matrix[1][y * size_x + size_x - 1] = 1.0;
} }
matrix matrix
...@@ -89,20 +90,16 @@ fn iteration(cur: &[f64], next: &mut [f64], size_x: usize, size_y: usize) { ...@@ -89,20 +90,16 @@ fn iteration(cur: &[f64], next: &mut [f64], size_x: usize, size_y: usize) {
}); });
} }
pub fn compute(mut matrix: vec::Vec<vec::Vec<f64>>, size_x: usize, size_y: usize) -> (usize, f64) { fn compute(matrix: &mut [f64], size_x: usize, size_y: usize, iterations: usize) -> f64 {
let mut counter = 0; let mut clone = matrix.to_vec();
while counter < 1000 {
{
// allow a borrow and a reference to the same vector
let (current, next) = matrix.split_at_mut(1);
iteration(&current[0], &mut next[0], size_x, size_y); let mut current = matrix;
} let mut next = &mut clone[..];
matrix.swap(0, 1);
counter += 1; for _ in 0..iterations {
iteration(current, next, size_x, size_y);
mem::swap(&mut current, &mut next);
} }
(counter, get_residual(&matrix[0], size_x, size_y)) get_residual(current, size_x, size_y)
} }