-
Notifications
You must be signed in to change notification settings - Fork 10.6k
Closed
Labels
compilerThe Swift compiler itselfThe Swift compiler itselfperformanceregressionswift 4.0type checkerArea → compiler: Semantic analysisArea → compiler: Semantic analysis
Description
Previous ID | SR-5583 |
Radar | rdar://problem/33627488 |
Original Reporter | lastdodo (JIRA User) |
Type | Bug |
Environment
x86_64-apple-macosx10.9
Additional Detail from JIRA
Votes | 0 |
Component/s | Compiler |
Labels | Bug, 4.0Regression, TypeChecker |
Assignee | None |
Priority | Medium |
md5: 2124e8902c4a15a09b59388a752aa3d3
Issue Description:
Currently I am working on a vector library in swift and have a problem with the Swift-compiler that ships with the 4th beta of Xcode 9.
Apple Swift version 4.0 (swiftlang-900.0.54.11 clang-900.0.31)
Target: x86_64-apple-macosx10.9
It has a problem compiling the methods that calculate the inverse and determinant of the matrix.
//
// matrix.swift
// illum
//
// Created by Anuschah Akbar-Rabii on 19.04.17.
//
//
import Foundation
public struct MatrixNxM<T> {
var m: [T]
private let xdim : Int
private let ydim : Int
subscript(i: Int, j: Int) -> T {
get {
precondition(i*xdim + j < self.m.count, "Index out of matrix bounds \(i) \(j)")
return self.m[i*xdim + j]
}
set {
self.m[i*xdim + j] = newValue
}
}
public init(xdim: Int, ydim: Int) {
self.xdim = xdim
self.ydim = ydim
self.m = [Any](repeating: 0.0, count: xdim*ydim) as! [T]
}
}
public struct Matrix4x4 {
var m: [Double]
subscript(i: Int, j: Int) -> Double {
get {
precondition(i*4 + j < self.m.count, "Index out of matrix bounds \(i) \(j)")
return self.m[i*4 + j]
}
set {
self.m[i*4 + j] = newValue
}
}
public init() {
m = [Double](repeating: 0.0, count: 16)
}
public static func identity() -> Matrix4x4 {
var identity = Matrix4x4()
identity[0,0] = 1.0;
identity[1,1] = 1.0;
identity[2,2] = 1.0;
identity[3,3] = 1.0;
return identity
}
public func determinant() -> Double {
let det = self[0,0] * self[1,1] * self[2,2] * self[3,3] +
self[0,0] * self[1,2] * self[2,3] * self[3,1] +
self[0,0] * self[1,3] * self[2,1] * self[3,2] +
self[0,1] * self[1,0] * self[2,3] * self[3,2] +
self[0,1] * self[1,2] * self[2,1] * self[3,3] +
self[0,1] * self[1,3] * self[2,2] * self[3,0] +
self[0,2] * self[1,0] * self[2,1] * self[3,3] +
self[0,2] * self[1,1] * self[2,3] * self[3,0] +
self[0,2] * self[1,3] * self[2,0] * self[3,0] +
self[0,3] * self[1,0] * self[2,2] * self[3,1] +
self[0,3] * self[1,1] * self[2,0] * self[3,2] +
self[0,3] * self[1,2] * self[2,1] * self[3,0] -
self[0,0] * self[1,1] * self[2,3] * self[3,2] -
self[0,0] * self[1,2] * self[2,1] * self[3,3] -
self[0,0] * self[1,3] * self[2,2] * self[3,1] -
self[0,1] * self[1,0] * self[2,2] * self[3,3] -
self[0,1] * self[1,2] * self[2,3] * self[3,0] -
self[0,1] * self[1,3] * self[2,0] * self[3,2] -
self[0,2] * self[1,0] * self[2,3] * self[3,1] -
self[0,2] * self[1,1] * self[2,0] * self[3,3] -
self[0,2] * self[1,3] * self[2,1] * self[3,0] -
self[0,3] * self[1,0] * self[2,1] * self[3,2] -
self[0,3] * self[1,1] * self[2,2] * self[3,0] -
self[0,3] * self[1,2] * self[2,0] * self[3,1]
return det
}
public func inverse() -> Matrix4x4 {
let det = self.determinant()
precondition(det != 0, "Determinant is zero, unable to calculate inverse Matrix")
let inv_det = 1.0 / det
var inverse = Matrix4x4()
inverse[0, 0] = (self[1,1] * self[2,2] * self[3,3] +
self[1,2] * self[2,3] * self[3,1] +
self[1,3] * self[2,1] * self[3,2] -
self[1,1] * self[2,3] * self[3,2] -
self[1,2] * self[2,1] * self[3,3] -
self[1,3] * self[2,2] * self[3,1]) * inv_det;
inverse[0, 1] = (self[0,1] * self[2,3] * self[3,2] +
self[0,2] * self[2,1] * self[3,3] +
self[1,3] * self[2,2] * self[3,1] -
self[0,1] * self[2,2] * self[3,3] -
self[0,2] * self[2,3] * self[3,1] -
self[0,3] * self[2,1] * self[3,2]) * inv_det;
inverse[0, 2] = (self[0,1] * self[1,2] * self[3,3] +
self[0,2] * self[1,3] * self[3,1] +
self[0,3] * self[1,1] * self[3,2] -
self[0,1] * self[1,3] * self[3,2] -
self[0,2] * self[1,1] * self[3,3] -
self[0,3] * self[1,2] * self[3,1]) * inv_det;
inverse[0, 3] = (self[0,1] * self[1,3] * self[2,2] +
self[0,2] * self[1,1] * self[2,3] +
self[0,3] * self[1,2] * self[2,1] -
self[0,1] * self[1,2] * self[2,3] -
self[0,2] * self[1,3] * self[2,1] -
self[0,3] * self[1,1] * self[2,2]) * inv_det;
inverse[1, 0] = (self[1,0] * self[2,3] * self[3,2] +
self[1,2] * self[2,0] * self[3,3] +
self[1,3] * self[2,2] * self[3,1] -
self[1,0] * self[2,2] * self[3,3] -
self[1,2] * self[2,3] * self[3,1] -
self[1,3] * self[2,0] * self[3,2]) * inv_det;
inverse[1, 1] = (self[0,0] * self[2,2] * self[3,3] +
self[0,2] * self[2,3] * self[3,1] +
self[0,3] * self[2,0] * self[3,2] -
self[0,0] * self[2,3] * self[3,2] -
self[0,2] * self[2,0] * self[3,3] -
self[0,3] * self[2,2] * self[3,0]) * inv_det;
inverse[1, 2] = (self[0,0] * self[1,3] * self[3,2] +
self[0,2] * self[1,0] * self[3,3] +
self[0,3] * self[1,2] * self[3,1] -
self[0,0] * self[1,2] * self[3,3] -
self[0,2] * self[1,3] * self[3,0] -
self[0,3] * self[1,0] * self[3,2]) * inv_det;
inverse[1, 3] = (self[0,0] * self[1,2] * self[2,3] +
self[0,2] * self[1,3] * self[2,2] +
self[0,3] * self[1,0] * self[2,2] -
self[0,0] * self[1,3] * self[2,2] -
self[0,2] * self[1,0] * self[2,3] -
self[0,3] * self[1,2] * self[2,0]) * inv_det;
inverse[2, 0] = (self[1,0] * self[2,1] * self[3,3] +
self[1,1] * self[2,3] * self[3,1] +
self[1,3] * self[2,1] * self[3,2] -
self[1,0] * self[2,3] * self[3,1] -
self[1,1] * self[2,0] * self[3,3] -
self[1,3] * self[2,1] * self[3,0]) * inv_det;
inverse[2, 1] = (self[0,0] * self[2,3] * self[3,1] +
self[0,1] * self[2,0] * self[3,3] +
self[0,3] * self[2,1] * self[3,1] -
self[0,0] * self[2,1] * self[3,3] -
self[0,1] * self[2,3] * self[3,0] -
self[0,3] * self[2,0] * self[3,1]) * inv_det;
inverse[2, 2] = (self[0,0] * self[1,1] * self[3,3] +
self[0,1] * self[1,3] * self[3,0] +
self[0,3] * self[1,0] * self[3,1] -
self[0,0] * self[1,3] * self[3,1] -
self[0,1] * self[1,0] * self[3,3] -
self[0,3] * self[1,1] * self[3,0]) * inv_det;
inverse[2, 3] = (self[0,0] * self[1,3] * self[2,1] +
self[0,1] * self[1,0] * self[2,3] +
self[0,3] * self[1,1] * self[2,0] -
self[0,0] * self[1,1] * self[2,3] -
self[0,1] * self[1,3] * self[2,0] -
self[0,3] * self[1,0] * self[2,1]) * inv_det;
inverse[3, 0] = (self[1,0] * self[2,2] * self[3,1] +
self[1,1] * self[2,0] * self[3,2] +
self[1,2] * self[2,1] * self[3,0] -
self[1,0] * self[2,1] * self[3,2] -
self[1,1] * self[2,2] * self[3,0] -
self[1,2] * self[2,0] * self[3,1]) * inv_det;
inverse[3, 1] = (self[0,0] * self[2,1] * self[3,2] +
self[0,1] * self[2,2] * self[3,0] +
self[0,2] * self[2,0] * self[3,2] -
self[0,0] * self[2,2] * self[3,1] -
self[0,1] * self[2,0] * self[3,2] -
self[0,2] * self[2,1] * self[3,0]) * inv_det;
inverse[3, 2] = (self[0,0] * self[1,2] * self[3,1] +
self[0,1] * self[1,0] * self[3,2] +
self[0,2] * self[1,1] * self[3,0] -
self[0,0] * self[1,1] * self[3,2] -
self[0,1] * self[1,2] * self[3,0] -
self[0,2] * self[1,0] * self[3,1]) * inv_det;
inverse[3, 3] = (self[0,0] * self[1,1] * self[2,2] +
self[0,1] * self[1,2] * self[2,0] +
self[0,2] * self[2,1] * self[2,1] -
self[0,0] * self[1,2] * self[2,1] -
self[0,1] * self[1,0] * self[2,2] -
self[0,2] * self[1,1] * self[2,0]) * inv_det;
return inverse
}
}
public func * (a: Matrix4x4, b: Matrix4x4) -> Matrix4x4 {
var c = Matrix4x4();
for i in 0..<4 {
for j in 0..<4 {
var ab: Double = 0.0;
for k in 0..<4 {
ab += a[i,k] * b[k,j];
}
c[i, j] = ab;
}
}
return c
}
The errors I get are
Sources/illumLib/matrix.swift:93:59: error: expression was too complex to be solved in reasonable time; consider breaking up the expression into distinct sub-expressions
This piece of code worked well with the swift3(.e.g. Xcode 8.3.3) compilers and the first and second Xcode 9 betas
The only way around this is splitting the calculation into multiple parts.
Metadata
Metadata
Assignees
Labels
compilerThe Swift compiler itselfThe Swift compiler itselfperformanceregressionswift 4.0type checkerArea → compiler: Semantic analysisArea → compiler: Semantic analysis