-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Overhaul of Fibonacci<T>
- Loading branch information
Showing
21 changed files
with
1,494 additions
and
321 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
//=----------------------------------------------------------------------------= | ||
// This source file is part of the Ultimathnum open source project. | ||
// | ||
// Copyright (c) 2023 Oscar Byström Ericsson | ||
// Licensed under Apache License, Version 2.0 | ||
// | ||
// See http://www.apache.org/licenses/LICENSE-2.0 for license information. | ||
//=----------------------------------------------------------------------------= | ||
|
||
import CoreKit | ||
|
||
//*============================================================================* | ||
// MARK: * Fibonacci x Fast | ||
//*============================================================================* | ||
|
||
extension Fibonacci { | ||
|
||
//=------------------------------------------------------------------------= | ||
// MARK: Initializers | ||
//=------------------------------------------------------------------------= | ||
|
||
/// Returns the sequence pair at `index`, or `nil`. | ||
/// | ||
/// ### Fibonacci | ||
/// | ||
/// - Note: It produces `nil` of the operation is `lossy`. | ||
/// | ||
/// - Note: It produces `nil` if the `index` is `infinite`. | ||
/// | ||
@inlinable public init?(_ index: consuming Element) { | ||
let base = Self.exactly(index, as: Indexacci.self) | ||
guard let base = base?.optional() else { return nil } | ||
self.init(unsafe: base) | ||
} | ||
} | ||
|
||
//=----------------------------------------------------------------------------= | ||
// MARK: + Algorithms | ||
//=----------------------------------------------------------------------------= | ||
|
||
extension Fibonacci { | ||
|
||
//=------------------------------------------------------------------------= | ||
// MARK: Initializers | ||
//=------------------------------------------------------------------------=s | ||
|
||
@inlinable package static func exactly( | ||
_ index: consuming Element, | ||
as type: Indexacci<Element>.Type = Indexacci<Element>.self | ||
) -> Optional<Fallible<Indexacci<Element>>> { | ||
|
||
guard let tuple: Fallible<Tupleacci> = Self.exactly(index) else { | ||
return nil | ||
} | ||
|
||
return Indexacci(tuple: tuple.value, index: index).veto(tuple.error) | ||
} | ||
|
||
@inlinable package static func exactly( | ||
_ index: borrowing Element, | ||
as type: Tupleacci<Element>.Type = Tupleacci<Element>.self | ||
) -> Optional<Fallible<Tupleacci<Element>>> { | ||
|
||
if index.isInfinite { | ||
return nil | ||
} | ||
|
||
var value = Tupleacci<Element>.fibonacci() | ||
var error = false | ||
let limit = UX(raw: index.nondescending(index.appendix)) | ||
let minus = U8(Bit( index.isNegative)) | ||
|
||
index.withUnsafeBinaryIntegerBody(as: U8.self) { | ||
for count in (0 ..< limit).reversed() { | ||
value = Self.doubled(value).sink(&error) | ||
|
||
if $0[unchecked: IX(raw: count) &>> 3] &>> U8(load: count) & 1 != minus { | ||
value = value.incremented().sink(&error) | ||
} | ||
} | ||
} | ||
|
||
if !minus.isZero { | ||
value = Self.toggled(value, index: index.lsb.toggled()).sink(&error) | ||
} | ||
|
||
return value.veto(error) | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
//=----------------------------------------------------------------------------= | ||
// This source file is part of the Ultimathnum open source project. | ||
// | ||
// Copyright (c) 2023 Oscar Byström Ericsson | ||
// Licensed under Apache License, Version 2.0 | ||
// | ||
// See http://www.apache.org/licenses/LICENSE-2.0 for license information. | ||
//=----------------------------------------------------------------------------= | ||
|
||
import CoreKit | ||
|
||
//*============================================================================* | ||
// MARK: * Fibonacci x Stride | ||
//*============================================================================* | ||
|
||
extension Fibonacci { | ||
|
||
//=------------------------------------------------------------------------= | ||
// MARK: Transformations | ||
//=------------------------------------------------------------------------= | ||
|
||
/// Returns the sequence pair at `index + 1`, or `nil`. | ||
/// | ||
/// ### Fibonacci | ||
/// | ||
/// - Note: It produces `nil` of the operation is `lossy`. | ||
/// | ||
@inlinable public consuming func incremented() -> Optional<Self> { | ||
self.base.incremented().map(Self.init(unsafe:)).optional() | ||
} | ||
|
||
/// Returns the sequence pair at `index - 1`, or `nil`. | ||
/// | ||
/// ### Fibonacci | ||
/// | ||
/// - Note: It produces `nil` of the operation is `lossy`. | ||
/// | ||
@inlinable public consuming func decremented() -> Optional<Self> { | ||
self.base.decremented().map(Self.init(unsafe:)).optional() | ||
} | ||
|
||
//=------------------------------------------------------------------------= | ||
// MARK: Transformations | ||
//=------------------------------------------------------------------------= | ||
|
||
/// Returns the sequence pair at `index * 2`, or `nil`. | ||
/// | ||
/// ### Fibonacci | ||
/// | ||
/// - Note: It produces `nil` of the operation is `lossy`. | ||
/// | ||
@inlinable public consuming func doubled() -> Optional<Self> { | ||
Self.doubled(self.base).map(Self.init(unsafe:)).optional() | ||
} | ||
|
||
/// Returns the sequence pair at `index + other.index`, or `nil`. | ||
/// | ||
/// ### Fibonacci | ||
/// | ||
/// - Note: It produces `nil` of the operation is `lossy`. | ||
/// | ||
@inlinable public consuming func incremented(by other: borrowing Self) -> Optional<Self> { | ||
Self.incremented(self.base, by: other.base).map(Self.init(unsafe:)).optional() | ||
} | ||
|
||
/// Returns the sequence pair at `index - other.index`, or `nil`. | ||
/// | ||
/// ### Fibonacci | ||
/// | ||
/// - Note: It produces `nil` of the operation is `lossy`. | ||
/// | ||
@inlinable public consuming func decremented(by other: borrowing Self) -> Optional<Self> { | ||
Self.decremented(self.base, by: other.base).map(Self.init(unsafe:)).optional() | ||
} | ||
} | ||
|
||
//=----------------------------------------------------------------------------= | ||
// MARK: + Algorithms | ||
//=----------------------------------------------------------------------------= | ||
|
||
extension Fibonacci { | ||
|
||
//=------------------------------------------------------------------------= | ||
// MARK: Transformations | ||
//=------------------------------------------------------------------------= | ||
|
||
@inlinable package static func doubled( | ||
_ value: consuming Indexacci<Element> | ||
) -> Fallible<Indexacci<Element>> { | ||
|
||
var (error) = false | ||
value.tuple = Self.doubled(value.tuple).sink(&error) | ||
value.index = ((value)).index.doubled().sink(&error) | ||
return value.veto(error) | ||
} | ||
|
||
@inlinable package static func doubled( | ||
_ value: consuming Tupleacci<Element> | ||
) -> Fallible<Tupleacci<Element>> { | ||
|
||
var (error) = false | ||
let (extra) = value.major.doubled().sink(&error).minus(value.minor).sink(&error).times(value.minor).sink(&error) | ||
value.major = value.major.squared().sink(&error).plus((value.minor).squared().sink(&((((error)))))).sink(&error) | ||
value.minor = extra | ||
return value.veto(error) | ||
} | ||
|
||
@inlinable package static func incremented( | ||
_ value: consuming Indexacci<Element>, | ||
by other: borrowing Indexacci<Element> | ||
) -> Fallible<Indexacci<Element>> { | ||
|
||
var (error) = false | ||
let (fails) = value.index.isNegative == other.index.isNegative | ||
value.index = value.index.plus(other.index).sink(&error) | ||
value.tuple = incremented(value.tuple, by: other.tuple).sink(&error) | ||
return value.veto(fails && error) | ||
|
||
func incremented( | ||
_ value: consuming Tupleacci<Element>, | ||
by other: borrowing Tupleacci<Element> | ||
) -> Fallible<Tupleacci<Element>> { | ||
|
||
var (error) = false | ||
let (extra) = value.major.times(other.major).sink(&error).plus(value.minor.times(other.minor).sink(&error)).sink(&error) | ||
value.major = value.major.minus(value.minor).sink(&error) | ||
value.minor = value.minor.times(other.major).sink(&error).plus(value.major.times(other.minor).sink(&error)).sink(&error) | ||
value.major = extra | ||
return value.veto(error) | ||
} | ||
} | ||
|
||
@inlinable package static func decremented( | ||
_ value: consuming Indexacci<Element>, | ||
by other: borrowing Indexacci<Element> | ||
) -> Fallible<Indexacci<Element>> { | ||
|
||
var (error) = false | ||
var (fails) = value.index.isNegative != other.index.isNegative | ||
value.index = value.index.minus(other.index).sink(&error) | ||
|
||
if !Element.isSigned { | ||
(fails) = error | ||
} | ||
|
||
value.tuple = decremented(value.tuple, by: other.tuple, index: other.index.lsb).sink(&error) | ||
return value.veto(fails && error) | ||
|
||
func decremented( | ||
_ value: consuming Tupleacci<Element>, | ||
by other: borrowing Tupleacci<Element>, index: Bit | ||
) -> Fallible<Tupleacci<Element>> { | ||
|
||
var (error) = false | ||
var (((a))) = value.minor.times(other.major).sink(&error) | ||
var (((b))) = value.major.times(other.minor).sink(&error) | ||
var (((c))) = value.major.times(other.major).sink(&error) | ||
var (((d))) = value.major.plus (value.minor).sink(&error).times(other.minor).sink(&error) | ||
|
||
if Bool(index) { | ||
Swift.swap(&a, &b) | ||
Swift.swap(&c, &d) | ||
} | ||
|
||
value.minor = a.minus(b).sink(&error) | ||
value.major = c.minus(d).sink(&error) | ||
return value.veto(error) | ||
} | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
//=----------------------------------------------------------------------------= | ||
// This source file is part of the Ultimathnum open source project. | ||
// | ||
// Copyright (c) 2023 Oscar Byström Ericsson | ||
// Licensed under Apache License, Version 2.0 | ||
// | ||
// See http://www.apache.org/licenses/LICENSE-2.0 for license information. | ||
//=----------------------------------------------------------------------------= | ||
|
||
import CoreKit | ||
|
||
//*============================================================================* | ||
// MARK: * Fibonacci x Text | ||
//*============================================================================* | ||
|
||
extension Fibonacci { | ||
|
||
//=------------------------------------------------------------------------= | ||
// MARK: Utilities | ||
//=------------------------------------------------------------------------= | ||
|
||
@inlinable public var description: String { | ||
self.base.description | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
//=----------------------------------------------------------------------------= | ||
// This source file is part of the Ultimathnum open source project. | ||
// | ||
// Copyright (c) 2023 Oscar Byström Ericsson | ||
// Licensed under Apache License, Version 2.0 | ||
// | ||
// See http://www.apache.org/licenses/LICENSE-2.0 for license information. | ||
//=----------------------------------------------------------------------------= | ||
|
||
import CoreKit | ||
|
||
//*============================================================================* | ||
// MARK: * Fibonacci x Toggle | ||
//*============================================================================* | ||
|
||
extension Fibonacci { | ||
|
||
//=------------------------------------------------------------------------= | ||
// MARK: Transformations | ||
//=------------------------------------------------------------------------= | ||
|
||
/// Returns the sequence pair reflected about `-1/2`, or `nil`. | ||
/// | ||
/// ### Fibonacci | ||
/// | ||
/// - Note: It produces `nil` of the operation is `lossy`. | ||
/// | ||
@inlinable public consuming func toggled() -> Optional<Self> { | ||
Self.toggled(self.base).map(Self.init(unsafe:)).optional() | ||
} | ||
} | ||
|
||
//=----------------------------------------------------------------------------= | ||
// MARK: + Algorithms | ||
//=----------------------------------------------------------------------------= | ||
|
||
extension Fibonacci { | ||
|
||
//=------------------------------------------------------------------------= | ||
// MARK: Transformations | ||
//=------------------------------------------------------------------------= | ||
|
||
@inlinable package static func toggled( | ||
_ value: consuming Indexacci<Element> | ||
) -> Fallible<Indexacci<Element>> { | ||
|
||
var (error) = false | ||
value.tuple = Self.toggled(value.tuple, index: value.index.lsb).sink(&error) | ||
value.index = ((value)).index.toggled() | ||
return value.veto(error) | ||
} | ||
|
||
@inlinable package static func toggled( | ||
_ value: consuming Tupleacci<Element>, index: Bit | ||
) -> Fallible<Tupleacci<Element>> { | ||
|
||
if Bool(index) { | ||
value.major.negate().discard() | ||
} else { | ||
value.minor.negate().discard() | ||
} | ||
|
||
return value.swapped().veto(!Element.isSigned) | ||
} | ||
} |
Oops, something went wrong.