Today we’re going to have fun with fixed points. A fixed point of a function `f`

is the value `x`

such that `f(x) = x`

. Not everyone function has a fixed point. For example, `f(x) = x + 1`

has no fixed point. But many functions do. Cosine is one such function. Today we’re going to write code that finds the fixed point of the cosine function.

The procedure is basically this:

- Pick a number
`a`

. I’ll start with 1.0. - Check whether
`a`

is about the same as`cos(a)`

. If it is, return it. - Set
`a := cos(a)`

and repeat.

Here’s the procedure in Ruby:

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.

Learn more about bidirectional Unicode characters

TOLERANCE = 0.00000000000000000001 | |

def tolerance_equals?(a, b) | |

((a – b) * (a – b)) < TOLERANCE | |

end | |

def recursive_cosine_fixedpoint(a) | |

return a if tolerance_equals?(a, Math.cos(a)) | |

recursive_cosine_fixedpoint(Math.cos(a)) | |

end | |

puts "The fixed point of cosine is #{recursive_cosine_fixedpoint(1)}" | |

# The fixed point of cosine is 0.7390851331706995 |

And because we’re feeling whimsical, we’re going to do the same thing in Python:

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.

Learn more about bidirectional Unicode characters

import math | |

tolerance = 0.00000000000000000001 | |

def tolerance_equals(a, b): | |

return ((a – b) * (a – b)) < tolerance | |

def recursive_cosine_fixedpoint(a): | |

if tolerance_equals(a, math.cos(a)): | |

return a | |

return recursive_cosine_fixedpoint(math.cos(a)) | |

print("The fixed point of cosine is {}".format(recursive_cosine_fixedpoint(1))) | |

# The fixed point of cosine is 0.7390851331706995 |

And Rust:

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.

Learn more about bidirectional Unicode characters

const TOLERANCE: f64 = 0.00000000000000000001; | |

fn tolerance_equals(a: f64, b: f64) -> bool { | |

((a – b) * (a – b)) < TOLERANCE | |

} | |

fn recursive_cosine_fixedpoint(a: f64) -> f64 { | |

if tolerance_equals(a, a.cos()) { | |

a | |

} else { | |

recursive_cosine_fixedpoint(a.cos()) | |

} | |

} | |

fn main() { | |

println!("The fixed point of cosine is {}", recursive_cosine_fixedpoint(1f64)); | |

} | |

// The fixed point of cosine is 0.7390851331706995 |

And look! All three of these return exactly the same value 😀. OK that’s all for today. That was fun!

Till next time, happy learning!

-Will