Swift CORDIC Algorithm gives constant answer - swift

I tried to translate the MATLAB language on Cordic wikipedia webpage
However when I type those:
print(cordic(beta: Double.pi/9, n: 20))
print(cordic(beta: Double.pi/8, n: 20))
I get
[-0.17163433840184755, 0.98516072489744066]
[-0.17163433840184755, 0.98516072489744066]
It's always giving me a constant answer. Why? I'm sure that the "angle" and "Kvalues" arrays are properly calculated.
Here's the code:
import Foundation
var angles: [Double] = []
for i: Double in stride(from: 0, to: 27, by: 1) {
angles.append(atan(pow(2, -i)))
}
var Kvalues: [Double] = []
for i: Double in stride(from: 0, to: 23, by: 1) {
Kvalues.append(1/sqrt(abs(Double(1) + pow(2,-2 * i))))
if i > 0 {
Kvalues[Kvalues.count - 1] *= Kvalues[Kvalues.count - 2]
}
}
func min(_ a: Int, _ b: Int) -> Int {
return a > b ? b : a
}
func cordic(beta: Double, n: Int) -> [Double] {
var beta1 = beta
let Kn = Kvalues[min(n, Kvalues.count - 1)]
var v: [Double] = [1,0]
var poweroftwo: Double = 1
var angle = angles[0]
for j in 0 ..< n {
let sigma: Double = beta < 0 ? -1 : 1
let factor: Double = sigma * poweroftwo
v = [v[0] - v[1] * factor, v[1] + v[0] * factor]
beta1 -= sigma * angle
poweroftwo /= 2
angle = j + 2 > angles.count ? angle / 2 : angles[j + 2]
}
return [v[0] * Kn, v[1] * Kn]
}
print(cordic(beta: Double.pi/9, n: 20))
print(cordic(beta: Double.pi/8, n: 20))

You get the same result for different input because in
let sigma: Double = beta < 0 ? -1 : 1
beta should be beta1, which is the local variable that is
updated in the loop.
But even after fixing that the results are not correct, and that is
caused by two "off-by-one" index errors. The arrays in the algorithm
description are 1-based and Swift arrays are 0-based. So
let Kn = Kvalues[min(n, Kvalues.count - 1)]
// should be
let Kn = Kvalues[min(n-1, Kvalues.count - 1)]
and
angle = j + 2 > angles.count ? angle / 2 : angles[j + 2]
// should be
angle = j + 1 >= angles.count ? angle / 2 : angles[j + 1]
The angles and Kvalues arrays should be defined for i from 0 up to and including 27 resp. 23.
Finally, there is no need to define your own min function as there is one in the Swift standard library.
Putting it all together your code would be:
var angles: [Double] = []
for i: Double in stride(from: 0, through: 27, by: 1) {
angles.append(atan(pow(2, -i)))
}
var Kvalues: [Double] = []
for i: Double in stride(from: 0, through: 23, by: 1) {
Kvalues.append(1/sqrt(abs(Double(1) + pow(2,-2 * i))))
if i > 0 {
Kvalues[Kvalues.count - 1] *= Kvalues[Kvalues.count - 2]
}
}
func cordic(beta: Double, n: Int) -> [Double] {
var beta1 = beta
let Kn = Kvalues[min(n-1, Kvalues.count - 1)]
var v: [Double] = [1,0]
var poweroftwo: Double = 1
var angle = angles[0]
for j in 0 ..< n {
let sigma: Double = beta1 < 0 ? -1 : 1
let factor: Double = sigma * poweroftwo
v = [v[0] - v[1] * factor, v[1] + v[0] * factor]
beta1 -= sigma * angle
poweroftwo /= 2
angle = j + 1 >= angles.count ? angle / 2 : angles[j + 1]
}
return [v[0] * Kn, v[1] * Kn]
}
And that produces good approximations:
print(cordic(beta: Double.pi/9, n: 20)) // [0.93969210812600046, 0.34202155184390554]
print(cordic(beta: Double.pi/8, n: 20)) // [0.92388022188807306, 0.38268176805806309]
The exact values are
print(cos(Double.pi/9), sin(Double.pi/9)) // 0.939692620785908 0.342020143325669
print(cos(Double.pi/8), sin(Double.pi/8)) // 0.923879532511287 0.38268343236509

Related

Splitting method algorithm

(x^3 - 2x^2 - 5) is my equation.First of all I have two values like x = 2 and x = 4. My first two values must be count for equation and them results must be negative and positive each time. And second step is (2 + 4) / 2 = 3 this time x = 3 in equation. And the math operation continue with last one positive value and one negative value. I try this
var x = 2.0
var equation = pow(x, 3) - 2 * pow(x, 2) - 5
switch x {
case x : 2
equation = pow(x, 3) - 2 * pow(x, 2) - 5
case x : 4
equation = pow(x, 3) - 2 * pow(x, 2) - 5
default:
0
}
print(equation)
How can I assign first two values like 2 and 4 for one var x ?
Apparently you want to implement the bisection method to find the (real) solution (“root”) of an equation. The first step is to define that equation as a function, so that it can be evaluated at various points:
func f(_ x: Double) -> Double {
return pow(x, 3) - 2 * pow(x, 2) - 5
}
Then you need two variables for the left and right boundary of the current interval. These must be chosen such that f(x) has opposite signs at the boundaries. In your example:
var xleft = 2.0 // f(xleft) < 0
var xright = 4.0 // f(xright) > 0
Now you can start the iteration: Compute f(x) at the midpoint of the current interval, and replace xleft of xright, depending on whether f(x) is negative or positive. Continue until the approximation is good enough for your purposes:
let eps = 0.0000001 // Desired precision
let leftSign = f(xleft).sign
repeat {
let x = (xleft + xright)/2.0
let y = f(x)
if y == 0 {
xleft = x
break
} else if y.sign == leftSign {
xleft = x
} else {
xright = x
}
// print(xleft, xright)
} while xright - xleft > eps
// Print approximate solution:
print(xleft)
The next step would be to implement the bisection method itself as a function:
func bisect(_ f: ((Double) -> Double), xleft: Double, xright: Double, eps: Double = 1.0e-6) -> Double {
let yleft = f(xleft)
let yright = f(xright)
precondition(yleft * yright <= 0, "f must have opposite sign at the boundaries")
var xleft = xleft
var xright = xright
repeat {
let x = (xleft + xright)/2.0
let y = f(x)
if y == 0 {
return x
} else if y.sign == yleft.sign {
xleft = x
} else {
xright = x
}
} while xright - xleft > eps
return (xleft + xright)/2.0
}
so that it can be used with arbitrary equations:
let sol1 = bisect({ x in pow(x, 3) - 2 * pow(x, 2) - 5 }, xleft: 2.0, xright: 4.0)
print(sol1) // 2.690647602081299
let sol2 = bisect({ x in cos(x/2)}, xleft: 3.0, xright: 4.0, eps: 1.0e-15)
print(sol2) // 3.1415926535897936

Procedural mesh not rendering lighting [SceneKit - Xcode]

I am quite new to swift and Xcode however, I have been programming in other languages for several years. I am trying to procedurally create a 3D mesh in SceneKit (iOS). My code works as expected however, when running the application the generated object renders a flat black colour, ignoring all lighting. I have also added a cube to the scene to show that the scene lighting is working.
I would imagine that there is either a problem with the shader or that I need to define the normals of the geometry to fix this. I have tried playing around with a few properties of the SCNMaterial, but they don't seem to change anything.
If it is just a case of defining the normals, please could you advise how I would do this in Swift / SceneKit. Or perhaps I have missed something else, any help would be much appreciated.
Screenshot below:
My code below:
public static func CreateMesh (size: CGFloat, resolution: CGFloat) -> SCNNode? {
let axisCount = Int(floor(size / resolution))
let bottomLeft = CGVector(
dx: CGFloat(-(axisCount / 2)) * resolution,
dy: CGFloat(-(axisCount / 2)) * resolution
)
var verts = Array(
repeating: Array(
repeating: (i: Int(0), pos: SCNVector3.init(x: 0, y: 0, z: 0)),
count: axisCount),
count: axisCount
)
var vertsStream = [SCNVector3]()
var i : Int = 0
for x in 0...axisCount-1 {
for y in 0...axisCount-1 {
verts[x][y] = (
i,
SCNVector3(
x: Float(bottomLeft.dx + CGFloat(x) * resolution),
y: Float.random(in: 0..<0.1),
z: Float(bottomLeft.dy + CGFloat(y) * resolution)
)
)
vertsStream.append(verts[x][y].pos)
i += 1
}
}
var tris = [(a: Int, b: Int, c: Int)]()
var trisStream = [UInt16]()
for x in 0...axisCount - 2 {
for y in 0...axisCount - 2 {
// Quad
tris.append((
a: verts[x][y].i,
b: verts[x][y+1].i,
c: verts[x+1][y+1].i
))
tris.append((
a: verts[x+1][y+1].i,
b: verts[x+1][y].i,
c: verts[x][y].i
))
}
}
for t in tris {
trisStream.append(UInt16(t.a))
trisStream.append(UInt16(t.b))
trisStream.append(UInt16(t.c))
}
// Create scene element
let geometrySource = SCNGeometrySource(vertices: vertsStream)
let geometryElement = SCNGeometryElement(indices: trisStream, primitiveType: .triangles)
let geometryFinal = SCNGeometry(sources: [geometrySource], elements: [geometryElement])
let node = SCNNode(geometry: geometryFinal)
////////////////////////
// FIX MATERIAL
////////////////////////
let mat = SCNMaterial()
mat.diffuse.intensity = 1
mat.lightingModel = .blinn
mat.blendMode = .replace
node.geometry?.materials = [mat]
return node
}
After a lot of searching I managed to find a post with a line of code that looks something like this:
let gsNormals = SCNGeometrySource(normals: normalStream)
So from there I managed to work out how to set the surface normals. It seems like there really isn't a lot of online content / learning material when it comes to the more advanced topics like this in Xcode / Swift, which is quite unfortunate.
I have set it up to create a parabolic shape plane, just for testing. But this code will be used to generate a mesh from a height map, which should now be easy to implement. I think it's pretty useful code, so I have included it below incase anyone else ever has the same issue that I did.
public static func CreateMesh (size: CGFloat, resolution: CGFloat) -> SCNNode? {
let axisCount = Int(floor(size / resolution))
let bottomLeft = CGVector(
dx: CGFloat(-(axisCount / 2)) * resolution,
dy: CGFloat(-(axisCount / 2)) * resolution
)
/// Verticies ///
var verts = Array(
repeating: Array(
repeating: (i: Int(0), pos: SCNVector3.init(x: 0, y: 0, z: 0)),
count: axisCount),
count: axisCount
)
var vertsStream = [SCNVector3]()
var i = 0
for x in 0...axisCount - 1 {
for y in 0...axisCount - 1 {
var dx = axisCount / 2 - x
dx = dx * dx
var dy = axisCount / 2 - y
dy = dy * dy
let yVal = Float(Double(dx + dy) * 0.0125)
verts[x][y] = (
i: i,
pos: SCNVector3(
x: Float(bottomLeft.dx + CGFloat(x) * resolution),
//y: Float.random(in: 0..<0.1),
y: yVal,
z: Float(bottomLeft.dy + CGFloat(y) * resolution)
)
)
vertsStream.append(verts[x][y].pos)
i += 1
}
}
///
/// Triangles ///
var tris = [(a: Int, b: Int, c: Int)]()
var trisStream = [UInt32]()
for x in 0...axisCount - 2 {
for y in 0...axisCount - 2 {
// Quad
tris.append((
a: verts[x][y].i,
b: verts[x][y+1].i,
c: verts[x+1][y].i
))
tris.append((
a: verts[x+1][y].i,
b: verts[x][y+1].i,
c: verts[x+1][y+1].i
))
}
}
for t in tris {
trisStream.append(UInt32(t.a))
trisStream.append(UInt32(t.b))
trisStream.append(UInt32(t.c))
}
///
/// Normals ///
var normalStream = [SCNVector3]()
for x in 0...axisCount - 1 {
for y in 0...axisCount - 1 {
// calculate normal vector perp to average plane
let leftX = x == 0 ? 0 : x - 1
let rightX = x == axisCount - 1 ? axisCount - 1 : x + 1
let leftY = y == 0 ? 0 : y - 1
let rightY = y == axisCount - 1 ? axisCount - 1 : y + 1
let avgXVector = float3(verts[rightX][y].pos) - float3(verts[leftX][y].pos)
let avgYVector = float3(verts[x][rightY].pos) - float3(verts[x][leftY].pos)
// If you are unfamiliar with how to calculate normals
// search for vector cross product, this is used to find
// a vector that is orthogonal to two other vectors, in our
// case perpendicular to the surface
let normal = cross(
normalize(avgYVector),
normalize(avgXVector)
)
normalStream.append(SCNVector3(normal))
}
}
///
// Create scene element
let gsGeometry = SCNGeometrySource(vertices: vertsStream)
let gsNormals = SCNGeometrySource(normals: normalStream)
let geometryElement = SCNGeometryElement(indices: trisStream, primitiveType: .triangles)
let geometryFinal = SCNGeometry(sources: [gsGeometry, gsNormals], elements: [geometryElement])
let node = SCNNode(geometry: geometryFinal)
let mat = SCNMaterial()
mat.isDoubleSided = true
mat.lightingModel = .blinn
node.geometry?.materials = [mat]
return node
}

Swift Inverse FFT (IFFT) Via Chirp Z-Transform (CZT)

For arbitrary sample sizes (samples not equal to 2^N), I have been able to implement the FFT via the chirp Z-transform (CZT) using iOS Accelerate's FFT function (that only works for samples equal to 2^N).
The results are good and match the Matlab FFT output for any arbitrary length sequence (signal). I paste the code below.
My next challenge is to use iOS Accelerate's FFT function (that only works for samples equal to 2^N) for accomplishing an inverse FFT on arbitrary sample sizes (samples not equal to 2^N).
Since my CZT accomplishes arbitrary length FFT now (see below), I am hoping that an inverse CZT (ICZT) would accomplish an arbitrary length IFFT using iOS Accelerate's FFT function (that only works for samples equal to 2^N).
Any suggestions/guidence?
// FFT IOS ACCELERATE FRAMEWORK (works only for 2^N samples)
import Accelerate
public func fft(x: [Double], y: [Double], type: String) -> ([Double], [Double]) {
var real = [Double](x)
var imaginary = [Double](y)
var splitComplex = DSPDoubleSplitComplex(realp: &real, imagp: &imaginary)
let length = vDSP_Length(floor(log2(Float(real.count))))
let radix = FFTRadix(kFFTRadix2)
let weights = vDSP_create_fftsetupD(length, radix)
switch type.lowercased() {
case ("fft"): // CASE FFT
vDSP_fft_zipD(weights!, &splitComplex, 1, length, FFTDirection(FFT_FORWARD))
vDSP_destroy_fftsetup(weights)
case ("ifft"): // CASE INVERSE FFT
vDSP_fft_zipD(weights!, &splitComplex, 1, length, FFTDirection(FFT_INVERSE))
vDSP_destroy_fftsetup(weights)
real = real.map({ $0 / Double(x.count) }) // Normalize IFFT by sample count
imaginary = imaginary.map({ $0 / Double(x.count) }) // Normalize IFFT by sample count
default: // DEFAULT CASE (FFT)
vDSP_fft_zipD(weights!, &splitComplex, 1, length, FFTDirection(FFT_FORWARD))
vDSP_destroy_fftsetup(weights)
}
return (real, imaginary)
}
// END FFT IOS ACCELERATE FRAMEWORK (works only for 2^N samples)
// DEFINE COMPLEX NUMBERS
struct Complex<T: FloatingPoint> {
let real: T
let imaginary: T
static func +(lhs: Complex<T>, rhs: Complex<T>) -> Complex<T> {
return Complex(real: lhs.real + rhs.real, imaginary: lhs.imaginary + rhs.imaginary)
}
static func -(lhs: Complex<T>, rhs: Complex<T>) -> Complex<T> {
return Complex(real: lhs.real - rhs.real, imaginary: lhs.imaginary - rhs.imaginary)
}
static func *(lhs: Complex<T>, rhs: Complex<T>) -> Complex<T> {
return Complex(real: lhs.real * rhs.real - lhs.imaginary * rhs.imaginary,
imaginary: lhs.imaginary * rhs.real + lhs.real * rhs.imaginary)
}
}
extension Complex: CustomStringConvertible {
var description: String {
switch (real, imaginary) {
case (_, 0):
return "\(real)"
case (0, _):
return "\(imaginary)i"
case (_, let b) where b < 0:
return "\(real) - \(abs(imaginary))i"
default:
return "\(real) + \(imaginary)i"
}
}
}
// DEFINE COMPLEX NUMBERS
// DFT BASED ON CHIRP Z TRANSFORM (CZT)
public func dft(x: [Double]) -> ([Double], [Double]) {
let m = x.count // number of samples
var N: [Double] = Array(stride(from: Double(0), through: Double(m - 1), by: 1.0))
N = N.map({ $0 + Double(m) })
var NM: [Double] = Array(stride(from: Double(-(m - 1)), through: Double(m - 1), by: 1.0))
NM = NM.map({ $0 + Double(m) })
var M: [Double] = Array(stride(from: Double(0), through: Double(m - 1), by: 1.0))
M = M.map({ $0 + Double(m) })
let nfft = Int(pow(2, ceil(log2(Double(m + m - 1))))) // fft pad
var p1: [Double] = Array(stride(from: Double(-(m - 1)), through: Double(m - 1), by: 1.0))
p1 = (zip(p1, p1).map(*)).map({ $0 / Double(2) }) // W = WR + j*WI has to be raised to power p1
var WR = [Double]()
var WI = [Double]()
for i in 0 ..< p1.count { // Use De Moivre's formula to raise to power p1
WR.append(cos(p1[i] * 2.0 * M_PI / Double(m)))
WI.append(sin(-p1[i] * 2.0 * M_PI / Double(m)))
}
var aaR = [Double]()
var aaI = [Double]()
for j in 0 ..< N.count {
aaR.append(WR[Int(N[j] - 1)] * x[j])
aaI.append(WI[Int(N[j] - 1)] * x[j])
}
let la = nfft - aaR.count
let pad: [Double] = Array(repeating: 0, count: la) // 1st zero padding
aaR += pad
aaI += pad
let (fgr, fgi) = fft(x: aaR, y: aaI, type: "fft") // 1st FFT
var bbR = [Double]()
var bbI = [Double]()
for k in 0 ..< NM.count {
bbR.append((WR[Int(NM[k] - 1)]) / (((WR[Int(NM[k] - 1)])) * ((WR[Int(NM[k] - 1)])) + ((WI[Int(NM[k] - 1)])) * ((WI[Int(NM[k] - 1)])))) // take reciprocal
bbI.append(-(WI[Int(NM[k] - 1)]) / (((WR[Int(NM[k] - 1)])) * ((WR[Int(NM[k] - 1)])) + ((WI[Int(NM[k] - 1)])) * ((WI[Int(NM[k] - 1)])))) // take reciprocal
}
let lb = nfft - bbR.count
let pad2: [Double] = Array(repeating: 0, count: lb) // 2nd zero padding
bbR += pad2
bbI += pad2
let (fwr, fwi) = fft(x: bbR, y: bbI, type: "fft") // 2nd FFT
let fg = zip(fgr, fgi).map { Complex<Double>(real: $0, imaginary: $1) } // complexN 1
let fw = zip(fwr, fwi).map { Complex<Double>(real: $0, imaginary: $1) } // complexN 2
let cc = zip(fg, fw).map { $0 * $1 } // multiply above 2 complex numbers fg * fw
var ccR = cc.map { $0.real } // real part (vector) of complex multiply
var ccI = cc.map { $0.imaginary } // imag part (vector) of complex multiply
let lc = nfft - ccR.count
let pad3: [Double] = Array(repeating: 0, count: lc) // 3rd zero padding
ccR += pad3
ccI += pad3
let (ggr, ggi) = fft(x: ccR, y: ccI, type: "ifft") // 3rd FFT (IFFT)
var GGr = [Double]()
var GGi = [Double]()
var W2r = [Double]()
var W2i = [Double]()
for v in 0 ..< M.count {
GGr.append(ggr[Int(M[v] - 1)])
GGi.append(ggi[Int(M[v] - 1)])
W2r.append(WR[Int(M[v] - 1)])
W2i.append(WI[Int(M[v] - 1)])
}
let ggg = zip(GGr, GGi).map { Complex<Double>(real: $0, imaginary: $1) }
let www = zip(W2r, W2i).map { Complex<Double>(real: $0, imaginary: $1) }
let y = zip(ggg, www).map { $0 * $1 }
let yR = y.map { $0.real } // FFT real part (output vector)
let yI = y.map { $0.imaginary } // FFT imag part (output vector)
return (yR, yI)
}
// END DFT BASED ON CHIRP Z TRANSFORM (CZT)
// CHIRP DFT (CZT) TEST
let x: [Double] = [1, 2, 3, 4, 5] // arbitrary sample size
let (fftR, fftI) = dft(x: x)
print("DFT Real Part:", fftR)
print(" ")
print("DFT Imag Part:", fftI)
// Matches Matlab FFT Output
// DFT Real Part: [15.0, -2.5000000000000018, -2.5000000000000013, -2.4999999999999991, -2.499999999999996]
// DFT Imag Part: [-1.1102230246251565e-16, 3.4409548011779334, 0.81229924058226477, -0.81229924058226599, -3.4409548011779356]
// END CHIRP DFT (CZT) TEST
Posting my comment as an answer to close this question—
If you’re sure you want to use an ICZT as an equivalent of IFFT, then make your dft function accept a type: String argument like your fft. When type is ifft, all you need is to flip the sign here:
WI.append(sin(-p1[i] * 2.0 * M_PI / Double(m)))
Leave it negative for forward FFT, and positive for inverse FFT (IFFT).
Here’s some Octave/Matlab code I wrote to demonstrate CZT: gist.github.com/fasiha/42a21405de92ea46f59e. The demo shows how to use czt2 to do fft. The third argument to czt2 (called w in the code) is exp(-2j * pi / Nup) for FFT. Just conjugate it to exp(+2j * pi / Nup) to get IFFT.
That’s what flipping the sign in the sin in WI does.

'Float' is not identical to 'UInt8' Swift

I have no idea what's wrong with my code for a Taylor series:
func factorial(n: Int) -> Int {
return n == 0 ? 1 : n * factorial(n - 1)
}
func sin(num: Float) -> Float {
let rad : Float = num * 1.0 / 180.0 * 3.1415926535897;
var sum : Float = rad;
for i in 1...100 {
if (i % 2 == 0) {
sum += Float(pow(rad, 2 * i + 1) / Float(factorial(2 * i + 1)));
} else {
sum -= Float(pow(rad, 2 * i + 1)) / Float(factorial(2 * i + 1));
}
}
return sum;
}
print(sin(123.0));
Here are the errors:
<stdin>:11:17: error: cannot invoke '/' with an argument list of type '(#lvalue Float, $T25)'
sum += Float(pow(rad, 2 * i + 1) / Float(factorial(2 * i + 1)));
~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<stdin>:13:13: error: 'Float' is not identical to 'UInt8'
sum -= Float(pow(rad, 2 * i + 1)) / Float(factorial(2 * i + 1));
^
The pow function needs two arguments of the same type, either Float or Double, and so does the division.
Change your sum +/-=... statements to:
if (i % 2 == 0) {
sum += pow(rad, Float(2 * i + 1)) / Float(factorial(2 * i + 1))
} else {
sum -= pow(rad, Float(2 * i + 1)) / Float(factorial(2 * i + 1))
}
Do you need to deal with both Ints and Floats? Swift is really picky about types, so if you can stick to one, that will make your life way easier. With just Floats, you can get this working by adding a single line:
func factorial(n: Float) -> Float {
return n == 0 ? 1 : n * factorial(n - 1)
}
func sin(num: Float) -> Float {
let rad : Float = num * 1.0 / 180.0 * 3.1415926535897;
var sum : Float = rad;
for i in 1...100 {
let float_index :Float = Float(i)
if (i % 2 == 0) {
sum += Float(pow(rad, 2 * float_index + 1) / Float(factorial(2 * float_index + 1)));
} else {
sum -= Float(pow(rad, 2 * float_index + 1)) / Float(factorial(2 * float_index + 1));
}
}
return sum;
}
I think pow requires its arguments to be of the same type but what you have isn't going to work even if you do sort out that issue. That's because your factorial function is generating numbers that are too big.
The largest 64-bit integral number has about twenty digits while the factorial of 200 has about 375.
Ergo it won't fit into a Int, it won't even fit into a Double (double precision IEEE754 number), which maxes out at about 308 digits (upper range, obviously precision is less).
You'll need to move up to Float80 which provides for several thousand digits of range.
But, again, due to the limited precision, you're likely to introduce a lot of errors into your calculations. This would be true even with the IEEE754 quad precision, limited to about 34 decimal digits of precision.

Type Sequence does not conform to protocol _Sequence (Swift Beta 4)

The following code that previously worked fine in Swift Beta 2 no longer compiles in Beta 4. Can anyone explain why, please?
for dx in [-1, 0, 1] { // Fine
for dy in (dx == 0) ? [-1, 1] : [0, (xIndex % 2) == 0 ? -1 : 1] { // Now fails
// ...
}
}
The error given is "Type 'Sequence' does not conform to protocol '_Sequence'". I know how to fix it (just set the inner range explicitly instead of using the ? operator), but why is this now an illegal expression?
The full function is:
func tilesAdjacentTo(#xIndex: Int, yIndex: Int) -> [HexTile] {
var adjacent = [HexTile]()
// We want to do this, where dy is -1 for even columns and +1 for odd
// adjacent += self.pieces[xIndex + 0][yIndex + 1]
// adjacent += self.pieces[xIndex + 0][yIndex - 1]
// adjacent += self.pieces[xIndex + 1][yIndex + 0]
// adjacent += self.pieces[xIndex + 1][yIndex + dy]
// adjacent += self.pieces[xIndex - 1][yIndex + 0]
// adjacent += self.pieces[xIndex - 1][yIndex + dy]
for dx in [-1, 0, 1] {
for dy in (dx == 0) ? [-1, 1] : [0, (xIndex % 2) == 0 ? -1 : 1] {
let x = xIndex + dx
let y = yIndex + dy
if (x > 0) &&
(x <= self.maxX) &&
(y > 0) &&
(y <= self.maxY)
{
adjacent += self.pieces[x][y]
}
}
}
//println("Adjacent \(adjacent.count)")
return adjacent
}