Swift Numerics provides a set of modules that support numerical computing in Swift. These modules fall broadly into two categories:
- API that is too specialized to go into the standard library, but which is sufficiently general to be centralized in a single common package.
- API that is under active development toward possible future inclusion in the standard library.
There is some overlap between these two categories, and API that begins in the first category may migrate to the second as it matures and new uses are discovered.
Swift Numerics modules are fine-grained; if you need support for Complex numbers, you can import the Complex module without pulling in everything else in the library as well:
import Complex let z = Complex<Double>.i
However, there is also a top-level
Numerics module that simply re-exports the complete public interface of swift-numerics:
import Numerics // All swift-numerics API is now available
Swift Numerics modules have minimal dependencies on other projects. The current modules assume only the availability of the Swift and C standard libraries and the runtime support provided by compiler-rt. Future expansion may assume the availability of other standard interfaces such as BLAS (Basic Linear Algebra Subprograms) and LAPACK (Linear Algebra Package), but modules with more specialized dependencies (or dependencies that are not available on all platforms supported by Swift) belong in a separate package.
Because we intend to make it possible to adopt Swift Numerics modules in the standard library at some future point, Swift Numerics uses the same license and contribution guidelines as the Swift project.
Swift Numerics is a standalone library separate from the core Swift project. In practice, it will act as a staging ground for some APIs that may eventually be incorporated into the Swift Standard Library, and when that happens such changes will be proposed to the Swift Standard Library using the established evolution process of the Swift project.
Swift Numerics uses GitHub issues to track bugs and features. We use pull requests for development.
To propose a new module:
- Raise an issue with the [new module] tag.
- Raise a PR with an implementation sketch.
- Once you have some consensus, ask an admin to create a feature branch against which PRs can be raised.
- When the design has stabilized and is functional enough to be useful, raise a PR to merge the new module to master.
To propose a new feature for an existing module:
- Raise an issue with the [enhancement] tag.
- Raise a PR with your implementation, and discuss the implementation there.
- Once there is a consensus that the new feature is desirable and the design is suitable, it can be merged.
To fix a bug, or make smaller improvements:
- Raise a PR with your change. Be sure to add test coverage for whatever changes you are making.
Questions about how to use Swift Numerics modules, or issues that are not clearly bugs can be discussed in the "Swift Numerics" section of the Swift forums.
You may find interesting
We Will Not Be Fielding Further Questions At This Time - 2020-01-22 19:07:33
There are two changes in this release to call out specifically:
Complex's conformance to Codable now uses an unkeyed container, so e.g.
.zerogets encoded as
[0,0]in JSON instead of the old
There's a new protocol,
Numericby adding the
/=operators, and a
.reciprocal: Self?property. The
Realprotocol refines it and
Complex<T>conforms to it, allowing you to write code that is generic over them. There are some additional operations that it probably makes sense to add to this protocol (e.g. square root); I expect to add them gradually as needed.
I also want to draw special attention to a change that I expect to make in the next tag. In order to make certain use patterns simpler, I intend to give the
Complex module a name that doesn't conflict with the
Complex type. If you have opinions about this change, or suggestions for a naming pattern to adopt for modules in Swift Numerics, please weigh in on that thread.
If you have any questions, use this discussion thread on the Swift forums.
We have the power - 2019-11-30 17:09:25
In earlier releases,
Real.pow(Self, Int) simply called through to
libm_pow. This is generally acceptable on platforms with a decent math library, but gets some cases wrong for
Double when the exponent is so large that it would be rounded in conversion to
For example, consider
Float.pow(-1, 0x1000001). Since the exponent is odd, the result should be
-1, but when we simply called
libm_pow(-1, Float(0x1000001)), the exponent was rounded to an even number, and the result was
This behavior is fixed in this release; in particular the parity of integer exponents is always preserved, so that we will not have sign errors like above. There is still additional work to be done on the
Real.pow implementations--especially to provide better support for platforms with suspect math libraries--but this is a significant improvement to these operations.
Complex API cleanup - 2019-11-20 21:35:08
There are two significant API changes to the Complex module in this release:
unsafeLengthSquaredproperty has been renamed
lengthSquared, because--while it can overflow or underflow--the result is always well-defined, and therefore does not lead to memory unsafety. The old property is still present, marked unavailable, so you should get a useful renaming message from the compiler or your IDE. The old property will be removed after a period of time.
Complex(length:phase:)initializer has been made non-optional. Instead it is now a precondition that the length must be either zero or infinite if phase is not finite. Updating code to account for this change should be quite straightforward, because you are unlikely to have been using the paths that could return nil previously. If you have any questions, please ask for assistance on the forums.
Linux testing improvements - 2019-11-12 20:39:56
Adds an empty Tests/LinuxMain.swift to fix building on Linux, and directs users to --enable-test-discovery for testing on Linux.
Initial tag - 2019-11-11 14:00:02
I haven't yet formally defined the release policy for this repo, but it's useful for SPM workflows to have a tag exist, so I'm cutting 0.0.0 with the first few rounds of bug fixes and cleanups from open source contributors.
Thanks to everyone who has jumped to contribute!