Skip to content

Instantly share code, notes, and snippets.

@msp729
Last active February 27, 2025 23:07
Show Gist options
  • Select an option

  • Save msp729/6908233cb2b98274c19f4d9409044c5c to your computer and use it in GitHub Desktop.

Select an option

Save msp729/6908233cb2b98274c19f4d9409044c5c to your computer and use it in GitHub Desktop.
Rust compact matrix Fibonacci
use num_bigint::BigUint;
use num_traits::One;
use num_traits::Zero;
use core::ops::{Mul, MulAssign};
#[derive(Debug, Clone)]
struct FLM {
step: BigUint,
ident: BigUint,
}
impl FLM {
fn sum(&self) -> BigUint {
return self.step.clone() + self.ident.clone();
}
fn pow(&mut self, mut idx: u32) {
let mut base = self.clone();
while idx > 0 {
if idx % 2 == 1 {
*self *= &base;
}
idx /= 2;
base = base.clone() * base;
}
}
}
impl MulAssign<&FLM> for FLM {
fn mul_assign(&mut self, other: &Self) {
let s2 = &self.step * &other.step;
let sum = self.sum();
self.ident *= &other.ident;
self.step = sum * other.sum() - &self.ident;
self.ident += s2;
}
}
impl Mul for FLM {
type Output = Self;
fn mul(self, other: Self) -> Self {
let s2 = &self.step * &other.step;
let mut ident = &self.ident * &other.ident;
let step = self.sum() * other.sum() - &ident;
ident += s2;
FLM { step, ident }
}
}
fn fib(n: u32) -> BigUint {
let mut step = FLM {
step: BigUint::one(),
ident: BigUint::zero(),
};
step.pow(n);
return step.step;
}
fn main() {
fib(9 << 20);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment