Lucas number: Difference between revisions

From Free Pascal wiki
Jump to navigationJump to search
(→‎recursive implementation: review implementation)
 
(5 intermediate revisions by 2 users not shown)
Line 8: Line 8:


== generation ==
== generation ==
The following implementations intend to merely show the ''principle''.
They lack of input checking, thus have undefined behavior when supplied with parameters out of range.


=== recursive implementation ===
=== recursive implementation ===
Line 27: Line 25:
   
   
\param n the index of the Lucas number to calculate
\param n the index of the Lucas number to calculate
\return the Lucas number at n
\return the Lucas number at n,
        unless n is out of range, then 0
        unless n is out of range, then 0
}
}
Line 60: Line 58:


=== based on Fibonacci sequence ===
=== based on Fibonacci sequence ===
The Lucas numbers can be calculated by using the <syntaxhighlight lang="pascal" enclose="none">fibonacci</syntaxhighlight> function shown in the article [[Fibonacci number]].
The Lucas numbers can be calculated by using the <syntaxhighlight lang="pascal" inline>fibonacci</syntaxhighlight> function shown in the article [[Fibonacci number]].
<syntaxhighlight lang="pascal" line start="54">
<syntaxhighlight lang="pascal" line start="54">
{**
{**
Line 87: Line 85:
// neutral element of addition
// neutral element of addition
// indicating n is out of range
// indicating n is out of range
// [there is no n satisfying L(n) = 0]
lucas := 0;
lucas := 0;
end;
end;
Line 94: Line 93:


=== iterative implementation ===
=== iterative implementation ===
This is in line with the [[Fibonacci number#iterative implementation|iterative implementation of <syntaxhighlight lang="pascal" enclose="none">fibonacci</syntaxhighlight>]] but with differing start values.
This is in line with the [[Fibonacci number#iterative implementation|iterative implementation of <syntaxhighlight lang="pascal" inline>fibonacci</syntaxhighlight>]] but with differing start values.
Therefore the code is not repeated here.
Therefore the code is not repeated here.


Line 101: Line 100:
While the code required for generation takes almost no space, a lookup table is the means of choice when an application needs them a lot.
While the code required for generation takes almost no space, a lookup table is the means of choice when an application needs them a lot.
Since Lucas numbers can be derived from Fibonacci numbers, usually only one table (those with the Fibonacci series) is stored, being a compromise between efficiency and memory utilization.
Since Lucas numbers can be derived from Fibonacci numbers, usually only one table (those with the Fibonacci series) is stored, being a compromise between efficiency and memory utilization.
In order to use the <syntaxhighlight lang="pascal" enclose="none">fibonacci</syntaxhighlight> table without margin case treatment, it has to be at least expanded to <syntaxhighlight lang="pascal" enclose="none">fibonacci[-1]</syntaxhighlight>.
In order to use the <syntaxhighlight lang="pascal" inline>fibonacci</syntaxhighlight> table without margin case treatment, it has to be at least expanded to <syntaxhighlight lang="pascal" inline>fibonacci[-1]</syntaxhighlight>.


An actual implementation is omitted here, since everyone wants it differently.
An actual implementation is omitted here, since everyone wants it differently.
Line 110: Line 109:
* [https://oeis.org/A000032 Lucas numbers in “the on-line encyclopedia of integer sequences”]
* [https://oeis.org/A000032 Lucas numbers in “the on-line encyclopedia of integer sequences”]
* [https://rosettacode.org/wiki/Lucas_sequence#Pascal Lucas sequence § “Pascal” on RosettaCode.org]
* [https://rosettacode.org/wiki/Lucas_sequence#Pascal Lucas sequence § “Pascal” on RosettaCode.org]
* [[gmp|GNU multiple precision arithmetic library]]'s functions [https://gmplib.org/manual/Lucas-Numbers-Algorithm.html#Lucas-Numbers-Algorithm <syntaxhighlight lang="c" enclose="none">mpz_lucnum_ui</syntaxhighlight> and <syntaxhighlight lang="c" enclose="none">mpz_lucnum2_ui</syntaxhighlight>]
* [[gmp|GNU multiple precision arithmetic library]]'s functions [https://gmplib.org/manual/Lucas-Numbers-Algorithm.html#Lucas-Numbers-Algorithm <syntaxhighlight lang="c" inline>mpz_lucnum_ui</syntaxhighlight> and <syntaxhighlight lang="c" inline>mpz_lucnum2_ui</syntaxhighlight>]

Latest revision as of 17:27, 6 August 2022

English (en) suomi (fi) français (fr)

The Lucas series is the sequence of numbers:

2, 1, 3, 4, 7, 11, 18, 29, 47, 

The idea is, that the next number is produced by summing the two preceding ones.

generation

recursive implementation

type
	/// domain for Lucas number function
	/// where result fits within a nativeUInt
	// You can not name it lucasDomain,
	// since the Lucas number function itself
	// is defined for all whole numbers
	// but the result beyond L(n) exceeds high(nativeUInt).
	lucasLeftInverseRange =
		{$ifdef CPU64} 0..92 {$else} 0..46 {$endif};

{**
	calculates Lucas number recursively
 
	\param n the index of the Lucas number to calculate
	\return the Lucas number at n,
	        unless n is out of range, then 0
}
function lucas(const n: lucasLeftInverseRange): nativeUInt;
begin
	case n of
		// recursive case
		2..high(n):
		begin
			lucas := lucas(n - 2) + lucas(n - 1);
		end;
		// base cases
		1:
		begin
			lucas := 1;
		end;
		0:
		begin
			lucas := 2;
		end;
		// abort case
		otherwise
		begin
			// neutral element of addition
			// indicating n is out of range
			// [there is no n satisfying L(n) = 0]
			lucas := 0;
		end;
	end;
end;

based on Fibonacci sequence

The Lucas numbers can be calculated by using the fibonacci function shown in the article Fibonacci number.

{**
	calculates Lucas number based on Fibonacci numbers
 
	\param n the index of the Lucas number to calculate
	\return the Lucas number at n,
	        unless n is out of range, then 0
}
function lucas(const n: lucasLeftInverseRange): nativeUInt;
begin
	case n of
		1..high(n):
		begin
			lucas := fibonacci(n - 1) + fibonacci(n + 1);
		end;
		0:
		begin
			// We can not deduce L(0) from Fibonacci
			// since that function is not defined for negative n
			// [we would call fibonacci(-1) + fibonacci(1)].
			lucas := 2;
		end;
		otherwise
		begin
			// neutral element of addition
			// indicating n is out of range
			// [there is no n satisfying L(n) = 0]
			lucas := 0;
		end;
	end;
end;

iterative implementation

This is in line with the iterative implementation of fibonacci but with differing start values. Therefore the code is not repeated here.

lookup

Calculating Lucas numbers every time they are needed is time-consuming. While the code required for generation takes almost no space, a lookup table is the means of choice when an application needs them a lot. Since Lucas numbers can be derived from Fibonacci numbers, usually only one table (those with the Fibonacci series) is stored, being a compromise between efficiency and memory utilization. In order to use the fibonacci table without margin case treatment, it has to be at least expanded to fibonacci[-1].

An actual implementation is omitted here, since everyone wants it differently. Also, do not program, what's already been programmed. For instance, the Lucas number functions of the GNU multiple precision arithmetic library take this approach.

see also