Skip to content

Commit

Permalink
[NBKCoreKit] Cleanup.
Browse files Browse the repository at this point in the history
  • Loading branch information
oscbyspro committed Nov 8, 2023
1 parent dd62d0e commit d9c35ed
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 84 deletions.
4 changes: 2 additions & 2 deletions Sources/NBKCoreKit/Private/NBK+Messages.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ extension NBK {
// MARK: Utilities
//=------------------------------------------------------------------------=

/// A message describing the source code location of an overflow error.
/// A message describing the location of an overflow error.
@inlinable public static func callsiteOverflowInfo(
function: StaticString = #function, file: StaticString = #file, line: UInt = #line) -> String {
"overflow in \(function) at \(file):\(line)"
}

/// A message describing the source code location of an out-of-bounds error.
/// A message describing the location of an out-of-bounds error.
@inlinable public static func callsiteOutOfBoundsInfo(
function: StaticString = #function, file: StaticString = #file, line: UInt = #line) -> String {
"out of bounds in \(function) at \(file):\(line)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ extension NBK.IntegerDescription {
/// - Returns: The `exponent` and `power` where `0` represents `Element.max + 1`.
///
@inlinable static func exponentiate(_ base: NBK.PowerOf2<Element>) -> Exponentiation {
//=----------------------------------=
precondition(base.value > 1)
//=----------------------------------=
let exponentiation: Exponentiation
Expand Down Expand Up @@ -294,26 +295,27 @@ extension NBK.IntegerDescription {
/// - Note: The power returned by this method is non-zero.
///
@inlinable static func exponentiate(_ base: NBK.NonPowerOf2<Element>) -> Exponentiation {
//=----------------------------------=
precondition(base.value > 1)
//=----------------------------------=
// radix: 003, 005, 006, 007, ...
//=----------------------------------=
let capacity: Int = Element.bitWidth.trailingZeroBitCount - 1
return Swift.withUnsafeTemporaryAllocation(of: Exponentiation.self, capacity: capacity) {
var exponentiation = Exponentiation(1, base.value)
let capacity: Int = Element.bitWidth.trailingZeroBitCount - 1
Swift.withUnsafeTemporaryAllocation(of: Exponentiation.self, capacity: capacity) {
let squares = NBK.unwrapping($0)!
var pointer = squares.baseAddress
var current = Exponentiation(1, base.value)
//=------------------------------=
// pointee: initialization
//=------------------------------=
loop: while true {
pointer.initialize(to: current)
pointer.initialize(to: exponentiation)

let product = current.power.multipliedReportingOverflow(by: current.power)
let product = exponentiation.power.multipliedReportingOverflow(by: exponentiation.power)
if product.overflow { break loop }

current.exponent &<<= 1 as Element
current.power = product.partialValue
exponentiation.exponent &<<= 1 as Element
exponentiation.power = product.partialValue
pointer = pointer.successor()
}
//=------------------------------=
Expand All @@ -324,15 +326,15 @@ extension NBK.IntegerDescription {
pointer = pointer.predecessor()

let square = pointer.move()
let product = current.power.multipliedReportingOverflow(by: square.power)
let product = exponentiation.power.multipliedReportingOverflow(by: square.power)
if product.overflow { continue loop }

current.exponent &+= square.exponent
current.power = product.partialValue
exponentiation.exponent &+= square.exponent
exponentiation.power = product.partialValue
}
//=------------------------------=
return current as Exponentiation
}
//=----------------------------------=
return exponentiation as Exponentiation
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//=----------------------------------------------------------------------------=
// This source file is part of the Numberick 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.
//=----------------------------------------------------------------------------=

//*============================================================================*
// MARK: * NBK x Strict Unsigned Integer x Mul. x Digit x Sub Sequence
//*============================================================================*
//=----------------------------------------------------------------------------=
// MARK: + Digit + Digit
//=----------------------------------------------------------------------------=

extension NBK.StrictUnsignedInteger.SubSequence where Base: MutableCollection {

//=------------------------------------------------------------------------=
// MARK: Transformations
//=------------------------------------------------------------------------=

/// Multiplies `base` by `multiplier` then adds `digit`.
///
/// - Returns: The `low` product is formed in `base` and the `high` product is returned in one element.
///
@inlinable public static func multiply(
_ base: inout Base, by multiplier: Base.Element, add digit: Base.Element) -> Base.Element {
//=--------------------------------------=
var carry: Base.Element = digit
var index: Base.Index = base.startIndex
//=--------------------------------------=
self.multiply(&base, by: multiplier, add: &carry, from: &index, to: base.endIndex)
//=--------------------------------------=
return carry as Base.Element
}

//=------------------------------------------------------------------------=
// MARK: Transformations x Inout
//=------------------------------------------------------------------------=

/// Multiplies `base` by `multiplier` then adds `digit` from `index` to `limit`.
///
/// - Returns: The `low` product is formed in `base[index..<limit]` and the `high` product is formed in `digit`.
///
@inlinable public static func multiply(
_ base: inout Base, by multiplier: Base.Element, add digit: inout Base.Element, from index: inout Base.Index, to limit: Base.Index) {
//=--------------------------------------=
Swift.assert(index >= base.startIndex)
Swift.assert(index <= limit)
Swift.assert(limit <= base.endIndex )
//=--------------------------------------=
forwards: while index < limit {
var wide = base[index].multipliedFullWidth(by: multiplier)
wide.high &+= Base.Element(bit: wide.low.addReportingOverflow(digit))
(digit, base[index]) = (wide)
base.formIndex(after: &index)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ extension NBK.StrictUnsignedInteger.SubSequence where Base: MutableCollection {
///
/// - Parameter base: A buffer of size `lhs.count` + `rhs.count`.
///
/// - Note: The `base` must be uninitialized or `pointee` must be trivial.
/// - Important: The `base` must be uninitialized, or its elements must be trivial.
///
/// [algorithm]: https://en.wikipedia.org/wiki/karatsuba_algorithm
///
Expand Down Expand Up @@ -145,7 +145,7 @@ extension NBK.StrictUnsignedInteger.SubSequence where Base: MutableCollection {
///
/// - Parameter base: A buffer of size `2 * elements.count`.
///
/// - Note: The `base` must be uninitialized or `pointee` must be trivial.
/// - Important: The `base` must be uninitialized, or its elements must be trivial.
///
/// [algorithm]: https://en.wikipedia.org/wiki/karatsuba_algorithm
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ extension NBK.StrictUnsignedInteger.SubSequence where Base: MutableCollection {
///
/// - Parameter base: A buffer of size `lhs.count` + `rhs.count`.
///
/// - Note: The `base` must be uninitialized or `pointee` must be trivial.
/// - Important: The `base` must be uninitialized, or its elements must be trivial.
///
/// [algorithm]: https://en.wikipedia.org/wiki/multiplication_algorithm
///
Expand Down Expand Up @@ -70,7 +70,7 @@ extension NBK.StrictUnsignedInteger.SubSequence where Base: MutableCollection {
///
/// - Parameter base: A buffer of size `2 * elements`.
///
/// - Note: The `base` must be uninitialized or `pointee` must be trivial.
/// - Important: The `base` must be uninitialized, or its elements must be trivial.
///
/// [algorithm]: https://en.wikipedia.org/wiki/multiplication_algorithm
///
Expand All @@ -95,18 +95,18 @@ extension NBK.StrictUnsignedInteger.SubSequence where Base: MutableCollection {
index = productIndex + 1 // add non-diagonal products

NBK.SUISS.incrementInIntersection(
&base, by: UnsafeBufferPointer(rebasing: elements[baseIndex...]),
times: multiplier, plus: 00000, at: &index)
&base, by: UnsafeBufferPointer(rebasing: elements[baseIndex...]),
times: multiplier, plus: Base.Element.zero, at: &index)

index = productIndex // partially double non-diagonal products

NBK.SUISS.multiply(&base, by: 0002, add: &carry, from: &index, to: productIndex + 2)
NBK.SUISS.multiply(&base, by: 2, add: &carry, from: &index, to: productIndex + 2)

index = productIndex // add this iteration's diagonal product

carry &+= Base.Element(bit: NBK.SUISS.incrementInIntersection(
&base, by: CollectionOfOne((multiplier)),
times: multiplier, plus: 00000, at: &index))
&base, by: CollectionOfOne(multiplier),
times: multiplier, plus: Base.Element.zero, at: &index))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,55 +10,6 @@
//*============================================================================*
// MARK: * NBK x Strict Unsigned Integer x Multiplication x Sub Sequence
//*============================================================================*
//=----------------------------------------------------------------------------=
// MARK: + Digit + Digit
//=----------------------------------------------------------------------------=

extension NBK.StrictUnsignedInteger.SubSequence where Base: MutableCollection {

//=------------------------------------------------------------------------=
// MARK: Transformations
//=------------------------------------------------------------------------=

/// Multiplies `base` by `multiplier` then adds `digit`.
///
/// - Returns: The `low` product is formed in `base` and the `high` product is returned in one element.
///
@inlinable public static func multiply(
_ base: inout Base, by multiplier: Base.Element, add digit: Base.Element) -> Base.Element {
//=--------------------------------------=
var carry: Base.Element = digit
var index: Base.Index = base.startIndex
//=--------------------------------------=
self.multiply(&base, by: multiplier, add: &carry, from: &index, to: base.endIndex)
//=--------------------------------------=
return carry as Base.Element
}

//=------------------------------------------------------------------------=
// MARK: Transformations x Inout
//=------------------------------------------------------------------------=

/// Multiplies `base` by `multiplier` then adds `digit` from `index` to `limit`.
///
/// - Returns: The `low` product is formed in `base[index..<limit]` and the `high` product is formed in `digit`.
///
@inlinable public static func multiply(
_ base: inout Base, by multiplier: Base.Element, add digit: inout Base.Element, from index: inout Base.Index, to limit: Base.Index) {
//=--------------------------------------=
Swift.assert(index >= base.startIndex)
Swift.assert(index <= limit)
Swift.assert(limit <= base.endIndex )
//=--------------------------------------=
forwards: while index < limit {
var wide = base[index].multipliedFullWidth(by: multiplier)
wide.high &+= Base.Element(bit: wide.low.addReportingOverflow(digit))
(digit, base[index]) = (wide)
base.formIndex(after: &index)
}
}
}

//=----------------------------------------------------------------------------=
// MARK: + where Base is Unsafe Buffer Pointer
//=----------------------------------------------------------------------------=
Expand All @@ -71,37 +22,37 @@ extension NBK.StrictUnsignedInteger.SubSequence where Base: MutableCollection {

/// Initializes `base` to the product of `lhs` and `rhs`.
///
/// - Parameters:
/// - base: A buffer of size `lhs.count` + `rhs.count`.
/// - Parameter base: A buffer of size `lhs.count` + `rhs.count`.
///
/// - Note: The `base` memory must be uninitialized or the pointee must be a trivial type.
/// - Important: The `base` must be uninitialized, or its elements must be trivial.
///
@inlinable public static func initialize<T>(
_ base: inout Base, to lhs: UnsafeBufferPointer<Base.Element>, times rhs: UnsafeBufferPointer<Base.Element>)
where Base == UnsafeMutableBufferPointer<T> {
//=--------------------------------------=
if lhs.count < 20 || rhs.count < 20 {
return self.initializeByLongAlgorithm(&base, to: lhs, times: rhs, plus: Base.Element.zero)
return self.initializeByLongAlgorithm(
&base, to: lhs, times: rhs, plus: Base.Element.zero)
} else {
return self.initializeByKaratsubaAlgorithm(&base, to: lhs, times: rhs)
return self.initializeByKaratsubaAlgorithm(
&base, to: lhs, times: rhs)
}
}

/// Initializes `base` to the square product of `elements`.
///
/// - Parameters:
/// - base: A buffer of size `2 * elements.count`.
/// - Parameter base: A buffer of size `2 * elements.count`.
///
/// - Note: The `base` memory must be uninitialized or the pointee must be a trivial type.
/// - Important: The `base` must be uninitialized, or its elements must be trivial.
///
@inlinable public static func initialize<T>(
_ base: inout Base, toSquareProductOf elements: UnsafeBufferPointer<Base.Element>)
where Base == UnsafeMutableBufferPointer<T> {
//=--------------------------------------=
if elements.count < 20 {
return self.initializeByLongAlgorithm(&base, toSquareProductOf: elements, plus: Base.Element.zero)
return self.initializeByLongAlgorithm(
&base, toSquareProductOf: elements, plus: Base.Element.zero)
} else {
return self.initializeByKaratsubaAlgorithm(&base, toSquareProductOf: elements)
return self.initializeByKaratsubaAlgorithm(
&base, toSquareProductOf: elements)
}
}
}

0 comments on commit d9c35ed

Please sign in to comment.