How to resolve the algorithm Metallic ratios step by step in the Ruby programming language
How to resolve the algorithm Metallic ratios step by step in the Ruby programming language
Table of Contents
Problem Statement
Many people have heard of the Golden ratio, phi (φ). Phi is just one of a series of related ratios that are referred to as the "Metallic ratios". The Golden ratio was discovered and named by ancient civilizations as it was thought to be the most pure and beautiful (like Gold). The Silver ratio was was also known to the early Greeks, though was not named so until later as a nod to the Golden ratio to which it is closely related. The series has been extended to encompass all of the related ratios and was given the general name Metallic ratios (or Metallic means). Somewhat incongruously as the original Golden ratio referred to the adjective "golden" rather than the metal "gold". Metallic ratios are the real roots of the general form equation: where the integer b determines which specific one it is. Using the quadratic equation: Substitute in (from the top equation) 1 for a, -1 for c, and recognising that -b is negated we get: We only want the real root: When we set b to 1, we get an irrational number: the Golden ratio. With b set to 2, we get a different irrational number: the Silver ratio. When the ratio b is 3, it is commonly referred to as the Bronze ratio, 4 and 5 are sometimes called the Copper and Nickel ratios, though they aren't as standard. After that there isn't really any attempt at standardized names. They are given names here on this page, but consider the names fanciful rather than canonical. Note that technically, b can be 0 for a "smaller" ratio than the Golden ratio. We will refer to it here as the Platinum ratio, though it is kind-of a degenerate case. Metallic ratios where b > 0 are also defined by the irrational continued fractions:
So, The first ten Metallic ratios are:
There are other ways to find the Metallic ratios; one, (the focus of this task) is through successive approximations of Lucas sequences. A traditional Lucas sequence is of the form: and starts with the first 2 values 0, 1. For our purposes in this task, to find the metallic ratios we'll use the form: ( P is set to b and Q is set to -1. ) To avoid "divide by zero" issues we'll start the sequence with the first two terms 1, 1. The initial starting value has very little effect on the final ratio or convergence rate. Perhaps it would be more accurate to call it a Lucas-like sequence. At any rate, when b = 1 we get: more commonly known as the Fibonacci sequence. When b = 2:
And so on.
To find the ratio by successive approximations, divide the (n+1)th term by the nth. As n grows larger, the ratio will approach the b metallic ratio. For b = 1 (Fibonacci sequence): It converges, but pretty slowly. In fact, the Golden ratio has the slowest possible convergence for any irrational number.
For each of the first 10 Metallic ratios; b = 0 through 9: Optional, stretch goal - Show the value and number of iterations n, to approximate the Golden ratio to 256 decimal places. You may assume that the approximation has been reached when the next iteration does not cause the value (to the desired places) to change.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Metallic ratios step by step in the Ruby programming language
The provided Ruby code calculates the Lucas Sequence and uses it to approximate the Metallic Ratio for various values of 'b'. It also finds the number of terms required to achieve a specified precision.
Here's a detailed explanation:
-
Lucas Sequence (lucas() method):
- The
lucas()
method is defined as an enumerator that yields terms of the Lucas Sequence for a givenb
. - The Lucas Sequence is a type of integer sequence where each term is the sum of the previous two terms, like the Fibonacci sequence.
- In this case, the Lucas Sequence is defined as
x(n) = b * x(n-1) + x(n-2)
, where 'b' is the specified parameter.
- The
-
Metallic Ratio (metallic_ratio() method):
- The
metallic_ratio()
method takes two parameters:b
(which corresponds to the Lucas Sequence) andprecision
(the desired precision for the approximation). - It uses the
lucas()
iterator to generate terms of the Lucas Sequence and calculates an approximation of the Metallic Ratio asx(n) / x(n-1)
, wherex(n)
andx(n-1)
are successive terms in the sequence. - It iterates through the Lucas Sequence until the precision is achieved, keeping track of the previous and current approximations of the ratio.
- When the difference between the current and previous approximations becomes negligible (less than
precision / 2
), it returns aStruct
containing the approximate Metallic Ratio (ratio
) and the number of terms (terms
) required to achieve the precision.
- The
-
Usage:
- The code uses two arrays,
NAMES
and(0..9)
, to generate sample values forb
. - It computes the Lucas Sequences for these
b
values and prints them out. - It also calculates and displays the Metallic Ratios for these
b
values to 32 decimal places. - Additionally, it calculates the Golden Ratio (a specific Metallic Ratio with
b=1
) to 256 decimal places.
- The code uses two arrays,
Overall, this code demonstrates the use of iterators, approximations, and precision control to derive values related to the Lucas Sequence and the Metallic Ratio. It's a practical example of mathematical calculations performed in Ruby using BigDecimal for high-precision arithmetic.
Source code in the ruby programming language
require('bigdecimal')
require('bigdecimal/util')
# An iterator over the Lucas Sequence for 'b'.
# (The special case of: x(n) = b * x(n-1) + x(n-2).)
def lucas(b)
Enumerator.new do |yielder|
xn2 = 1 ; yielder.yield(xn2)
xn1 = 1 ; yielder.yield(xn1)
loop { xn2, xn1 = xn1, b * xn1 + xn2 ; yielder.yield(xn1) }
end
end
# Compute the Metallic Ratio to 'precision' from the Lucas Sequence for 'b'.
# (Uses the lucas(b) iterator, above.)
# The metallic ratio is approximated by x(n) / x(n-1).
# Returns a struct of the approximate metallic ratio (.ratio) and the
# number of terms required to achieve the given precision (.terms).
def metallic_ratio(b, precision)
xn2 = xn1 = prev = this = 0
lucas(b).each.with_index do |xn, inx|
case inx
when 0
xn2 = BigDecimal(xn)
when 1
xn1 = BigDecimal(xn)
prev = xn1.div(xn2, 2 * precision).round(precision)
else
xn2, xn1 = xn1, BigDecimal(xn)
this = xn1.div(xn2, 2 * precision).round(precision)
return Struct.new(:ratio, :terms).new(prev, inx - 1) if prev == this
prev = this
end
end
end
NAMES = [ 'Platinum', 'Golden', 'Silver', 'Bronze', 'Copper',
'Nickel', 'Aluminum', 'Iron', 'Tin', 'Lead' ]
puts
puts('Lucas Sequences...')
puts('%1s %s' % ['b', 'sequence'])
(0..9).each do |b|
puts('%1d %s' % [b, lucas(b).first(15)])
end
puts
puts('Metallic Ratios to 32 places...')
puts('%-9s %1s %3s %s' % ['name', 'b', 'n', 'ratio'])
(0..9).each do |b|
rn = metallic_ratio(b, 32)
puts('%-9s %1d %3d %s' % [NAMES[b], b, rn.terms, rn.ratio.to_s('F')])
end
puts
puts('Golden Ratio to 256 places...')
puts('%-9s %1s %3s %s' % ['name', 'b', 'n', 'ratio'])
gold_rn = metallic_ratio(1, 256)
puts('%-9s %1d %3d %s' % [NAMES[1], 1, gold_rn.terms, gold_rn.ratio.to_s('F')])
You may also check:How to resolve the algorithm Minimum positive multiple in base 10 using only 0 and 1 step by step in the Nim programming language
You may also check:How to resolve the algorithm Forward difference step by step in the 11l programming language
You may also check:How to resolve the algorithm List comprehensions step by step in the Sidef programming language
You may also check:How to resolve the algorithm Averages/Pythagorean means step by step in the Clojure programming language
You may also check:How to resolve the algorithm Scope modifiers step by step in the Free Pascal programming language