[
  {
    "path": ".gitignore",
    "content": "KalmanFilter.xcodeproj/xcuserdata\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: objective-c\nosx_image: xcode9.1\n\nscript:\n  - xcodebuild clean build test -project KalmanFilter.xcodeproj -scheme KalmanFilter -destination 'platform=iOS Simulator,name=iPhone 8'\n\nafter_success:\n  - bash <(curl -s https://codecov.io/bash)\n\nnotifications:\n  email: true\n"
  },
  {
    "path": "KalmanFilter/DoubleExtension.swift",
    "content": "//\n//  DoubleExtension.swift\n//  KalmanFilterTest\n//\n//  Created by Oleksii on 20/06/16.\n//  Copyright © 2016 Oleksii Dykan. All rights reserved.\n//\n\nimport Foundation\n\n// MARK: Double as Kalman input\nextension Double: KalmanInput {\n    public var transposed: Double {\n        return self\n    }\n    \n    public var inversed: Double {\n        return 1 / self\n    }\n    \n    public var additionToUnit: Double {\n        return 1 - self\n    }\n}\n"
  },
  {
    "path": "KalmanFilter/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>FMWK</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>0.1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>$(CURRENT_PROJECT_VERSION)</string>\n\t<key>NSPrincipalClass</key>\n\t<string></string>\n</dict>\n</plist>\n"
  },
  {
    "path": "KalmanFilter/KalmanFilter.h",
    "content": "//\n//  KalmanFilter.h\n//  KalmanFilter\n//\n//  Created by Oleksii on 17/08/16.\n//  Copyright © 2016 Oleksii Dykan. All rights reserved.\n//\n\n#import <UIKit/UIKit.h>\n\n//! Project version number for KalmanFilter.\nFOUNDATION_EXPORT double KalmanFilterVersionNumber;\n\n//! Project version string for KalmanFilter.\nFOUNDATION_EXPORT const unsigned char KalmanFilterVersionString[];\n\n// In this header, you should import all the public headers of your framework using statements like #import <KalmanFilter/PublicHeader.h>\n\n\n"
  },
  {
    "path": "KalmanFilter/KalmanFilter.swift",
    "content": "//\n//  KalmanFilter.swift\n//  KalmanFilter\n//\n//  Created by Oleksii on 18/08/16.\n//  Copyright © 2016 Oleksii Dykan. All rights reserved.\n//\n\nimport Foundation\n\n/**\n Conventional Kalman Filter\n */\npublic struct KalmanFilter<Type: KalmanInput>: KalmanFilterType {\n    /// x̂_k|k-1\n    public let stateEstimatePrior: Type\n    /// P_k|k-1\n    public let errorCovariancePrior: Type\n    \n    public init(stateEstimatePrior: Type, errorCovariancePrior: Type) {\n        self.stateEstimatePrior = stateEstimatePrior\n        self.errorCovariancePrior = errorCovariancePrior\n    }\n    \n    /**\n     Predict step in Kalman filter.\n     \n     - parameter stateTransitionModel: F_k\n     - parameter controlInputModel: B_k\n     - parameter controlVector: u_k\n     - parameter covarianceOfProcessNoise: Q_k\n     \n     - returns: Another instance of Kalman filter with predicted x̂_k and P_k\n     */\n    public func predict(stateTransitionModel: Type, controlInputModel: Type, controlVector: Type, covarianceOfProcessNoise: Type) -> KalmanFilter {\n        // x̂_k|k-1 = F_k * x̂_k-1|k-1 + B_k * u_k\n        let predictedStateEstimate = stateTransitionModel * stateEstimatePrior + controlInputModel * controlVector\n        // P_k|k-1 = F_k * P_k-1|k-1 * F_k^t + Q_k\n        let predictedEstimateCovariance = stateTransitionModel * errorCovariancePrior * stateTransitionModel.transposed + covarianceOfProcessNoise\n        \n        return KalmanFilter(stateEstimatePrior: predictedStateEstimate, errorCovariancePrior: predictedEstimateCovariance)\n    }\n    \n    /**\n     Update step in Kalman filter. We update our prediction w\u001cith the measurements that we make\n     \n     - parameter measurement: z_k\n     - parameter observationModel: H_k\n     - parameter covarienceOfObservationNoise: R_k\n     \n     - returns: Updated with the measurements version of Kalman filter with new x̂_k and P_k\n     */\n    public func update(measurement: Type, observationModel: Type, covarienceOfObservationNoise: Type) -> KalmanFilter {\n        // H_k^t transposed. We cache it improve performance\n        let observationModelTransposed = observationModel.transposed\n        \n        // ỹ_k = z_k - H_k * x̂_k|k-1\n        let measurementResidual = measurement - observationModel * stateEstimatePrior\n        // S_k = H_k * P_k|k-1 * H_k^t + R_k\n        let residualCovariance = observationModel * errorCovariancePrior * observationModelTransposed + covarienceOfObservationNoise\n        // K_k = P_k|k-1 * H_k^t * S_k^-1\n        let kalmanGain = errorCovariancePrior * observationModelTransposed * residualCovariance.inversed\n        \n        // x̂_k|k = x̂_k|k-1 + K_k * ỹ_k\n        let posterioriStateEstimate = stateEstimatePrior + kalmanGain * measurementResidual\n        // P_k|k = (I - K_k * H_k) * P_k|k-1\n        let posterioriEstimateCovariance = (kalmanGain * observationModel).additionToUnit * errorCovariancePrior\n        \n        return KalmanFilter(stateEstimatePrior: posterioriStateEstimate, errorCovariancePrior: posterioriEstimateCovariance)\n    }\n}\n"
  },
  {
    "path": "KalmanFilter/KalmanFilterType.swift",
    "content": "//\n//  KalmanFilterType.swift\n//  KalmanFilter\n//\n//  Created by Oleksii on 18/08/16.\n//  Copyright © 2016 Oleksii Dykan. All rights reserved.\n//\n\nimport Foundation\n\npublic protocol KalmanInput {\n    var transposed: Self { get }\n    var inversed: Self { get }\n    var additionToUnit: Self { get }\n    \n    static func + (lhs: Self, rhs: Self) -> Self\n    static func - (lhs: Self, rhs: Self) -> Self\n    static func * (lhs: Self, rhs: Self) -> Self\n}\n\npublic protocol KalmanFilterType {\n    associatedtype Input: KalmanInput\n    \n    var stateEstimatePrior: Input { get }\n    var errorCovariancePrior: Input { get }\n    \n    func predict(stateTransitionModel: Input, controlInputModel: Input, controlVector: Input, covarianceOfProcessNoise: Input) -> Self\n    func update(measurement: Input, observationModel: Input, covarienceOfObservationNoise: Input) -> Self\n}\n"
  },
  {
    "path": "KalmanFilter/Matrix.swift",
    "content": "//\n//  Matrix.swift\n//  KalmanFilterTest\n//\n//  Created by Oleksii on 20/06/16.\n//  Copyright © 2016 Oleksii Dykan. All rights reserved.\n//\n\nimport Foundation\nimport Accelerate\n\npublic struct Matrix: Equatable {\n    // MARK: - Properties\n    public let rows: Int, columns: Int\n    public var grid: [Double]\n    \n    var isSquare: Bool {\n        return rows == columns\n    }\n    \n    // MARK: - Initialization\n    \n    /**\n     Initialization of matrix with rows * columns\n     size where all the elements are set to 0.0\n     \n     - parameter rows: number of rows in matrix\n     - parameter columns: number of columns in matrix\n     */\n    public init(rows: Int, columns: Int) {\n        let grid = Array(repeating: 0.0, count: rows * columns)\n        self.init(grid: grid, rows: rows, columns: columns)\n    }\n    \n    /**\n     Initialization with grid that contains all the\n     elements of matrix with given matrix size\n     \n     - parameter grid: array of matrix elements. **warning**\n     Should be of rows * column size.\n     - parameter rows: number of rows in matrix\n     - parameter columns: number of columns in matrix\n     */\n    public init(grid: [Double], rows: Int, columns: Int) {\n        assert(rows * columns == grid.count, \"grid size should be rows * column size\")\n        self.rows = rows\n        self.columns = columns\n        self.grid = grid\n    }\n    \n    /**\n     Initialization of \n     [column vector](https://en.wikipedia.org/wiki/Row_and_column_vectors)\n     with given array. Number of\n     elements in array equals to number of rows in vector.\n     \n     - parameter vector: array with elements of vector\n     */\n    public init(vector: [Double]) {\n        self.init(grid: vector, rows: vector.count, columns: 1)\n    }\n    \n    /**\n     Initialization of \n     [column vector](https://en.wikipedia.org/wiki/Row_and_column_vectors)\n     with given number of rows. Every element is assign to 0.0\n     \n     - parameter size: vector size\n     */\n    public init(vectorOf size: Int) {\n        self.init(rows: size, columns: 1)\n    }\n    \n    /**\n     Initialization of square matrix with given size. Number of\n     elements in array equals to size * size. Every elements is\n     assigned to 0.0\n     \n     - parameter size: number of rows and columns in matrix\n     */\n    public init(squareOfSize size: Int) {\n        self.init(rows: size, columns: size)\n    }\n    \n    /**\n     Initialization of \n     [identity matrix](https://en.wikipedia.org/wiki/Identity_matrix)\n     of given sizen\n     \n     - parameter size: number of rows and columns in identity matrix\n     */\n    public init(identityOfSize size: Int) {\n        self.init(squareOfSize: size)\n        for i in 0..<size {\n            self[i, i] = 1\n        }\n    }\n    \n    /**\n     Convenience initialization from 2D array\n     \n     - parameter array2d: 2D array representation of matrix\n     */\n    public init(_ array2d: [[Double]]) {\n        self.init(grid: array2d.flatMap({$0}), rows: array2d.count, columns: array2d.first?.count ?? 0)\n    }\n    \n    // MARK: - Public Methods\n    /**\n     Determines whether element exists at specified row and\n     column\n     \n     - parameter row: row index of element\n     - parameter column: column index of element\n     - returns: bool indicating whether spicified indeces are valid\n     */\n    public func indexIsValid(forRow row: Int, column: Int) -> Bool {\n        return row >= 0 && row < rows && column >= 0 && column < columns\n    }\n    \n    public subscript(row: Int, column: Int) -> Double {\n        get {\n            assert(indexIsValid(forRow: row, column: column), \"Index out of range\")\n            return grid[(row * columns) + column]\n        }\n        set {\n            assert(indexIsValid(forRow: row, column: column), \"Index out of range\")\n            grid[(row * columns) + column] = newValue\n        }\n    }\n}\n\n// MARK: - Equatable\n\npublic func == (lhs: Matrix, rhs: Matrix) -> Bool {\n    return lhs.rows == rhs.rows && lhs.columns == rhs.columns && lhs.grid == rhs.grid\n}\n\n// MARK: -  Matrix as KalmanInput\nextension Matrix: KalmanInput {\n    /**\n     [Transposed](https://en.wikipedia.org/wiki/Transpose)\n     version of matrix\n     \n     Compexity: O(n^2)\n     */\n    public var transposed: Matrix {\n        var resultMatrix = Matrix(rows: columns, columns: rows)\n        let columnLength = resultMatrix.columns\n        let rowLength = resultMatrix.rows\n        grid.withUnsafeBufferPointer { xp in\n            resultMatrix.grid.withUnsafeMutableBufferPointer { rp in\n                vDSP_mtransD(xp.baseAddress!, 1, rp.baseAddress!, 1, vDSP_Length(rowLength), vDSP_Length(columnLength))\n            }\n        }\n        return resultMatrix\n    }\n    \n    /**\n     Addition to Unit in form: **I - A**\n     where **I** - is \n     [identity matrix](https://en.wikipedia.org/wiki/Identity_matrix) \n     and **A** - is self\n     \n     **warning** Only for square matrices\n     \n     Complexity: O(n ^ 2)\n     */\n    public var additionToUnit: Matrix {\n        assert(isSquare, \"Matrix should be square\")\n        return Matrix(identityOfSize: rows) - self\n    }\n    \n    /**\n     Inversed matrix if\n     [it is invertible](https://en.wikipedia.org/wiki/Invertible_matrix)\n     */\n    public var inversed: Matrix {\n        assert(isSquare, \"Matrix should be square\")\n        \n        if rows == 1 {\n            return Matrix(grid: [1/self[0, 0]], rows: 1, columns: 1)\n        }\n        \n        var inMatrix:[Double] = grid\n        // Get the dimensions of the matrix. An NxN matrix has N^2\n        // elements, so sqrt( N^2 ) will return N, the dimension\n        var N:__CLPK_integer = __CLPK_integer(sqrt(Double(grid.count)))\n        var N2:__CLPK_integer = N\n        var N3:__CLPK_integer = N\n        var lwork = __CLPK_integer(grid.count)\n        // Initialize some arrays for the dgetrf_(), and dgetri_() functions\n        var pivots:[__CLPK_integer] = [__CLPK_integer](repeating: 0, count: grid.count)\n        var workspace:[Double] = [Double](repeating: 0.0, count: grid.count)\n        var error: __CLPK_integer = 0\n        \n        // Perform LU factorization\n        dgetrf_(&N, &N2, &inMatrix, &N3, &pivots, &error)\n        // Calculate inverse from LU factorization\n        dgetri_(&N, &inMatrix, &N2, &pivots, &workspace, &lwork, &error)\n        \n        if error != 0 {\n            assertionFailure(\"Matrix Inversion Failure\")\n        }\n        return Matrix.init(grid: inMatrix, rows: rows, columns: rows)\n    }\n    \n    /**\n     [Matrix determinant](https://en.wikipedia.org/wiki/Determinant)\n     */\n    public var determinant: Double {\n        assert(isSquare, \"Matrix should be square\")\n        var result = 0.0\n        if rows == 1 {\n            result = self[0, 0]\n        } else {\n            for i in 0..<rows {\n                let sign = i % 2 == 0 ? 1.0 : -1.0\n                result += sign * self[i, 0] * additionalMatrix(row: i, column: 0).determinant\n            }\n        }\n        return result\n    }\n    \n    public func additionalMatrix(row: Int, column: Int) -> Matrix {\n        assert(indexIsValid(forRow: row, column: column), \"Invalid arguments\")\n        var resultMatrix = Matrix(rows: rows - 1, columns: columns - 1)\n        for i in 0..<rows {\n            if i == row {\n                continue\n            }\n            for j in 0..<columns {\n                if j == column {\n                    continue\n                }\n                let resI = i < row ? i : i - 1\n                let resJ = j < column ? j : j - 1\n                resultMatrix[resI, resJ] = self[i, j]\n            }\n        }\n        return resultMatrix\n    }\n    \n    // MARK: - Private methods\n    fileprivate func operate(with otherMatrix: Matrix, closure: (Double, Double) -> Double) -> Matrix {\n        assert(rows == otherMatrix.rows && columns == otherMatrix.columns, \"Matrices should be of equal size\")\n        var resultMatrix = Matrix(rows: rows, columns: columns)\n        \n        for i in 0..<rows {\n            for j in 0..<columns {\n                resultMatrix[i, j] = closure(self[i, j], otherMatrix[i, j])\n            }\n        }\n        \n        return resultMatrix\n    }\n}\n\n/**\n Naive add matrices\n \n Complexity: O(n^2)\n */\npublic func + (lhs: Matrix, rhs: Matrix) -> Matrix {\n    assert(lhs.rows == rhs.rows && lhs.columns == rhs.columns, \"Matrices should be of equal size\")\n    var resultMatrix = Matrix(rows: lhs.rows, columns: lhs.columns)\n    vDSP_vaddD(lhs.grid, vDSP_Stride(1), rhs.grid, vDSP_Stride(1), &resultMatrix.grid, vDSP_Stride(1), vDSP_Length(lhs.rows * lhs.columns))\n    return resultMatrix\n}\n\n/**\n Naive subtract matrices\n \n Complexity: O(n^2)\n */\npublic func - (lhs: Matrix, rhs: Matrix) -> Matrix {\n    assert(lhs.rows == rhs.rows && lhs.columns == rhs.columns, \"Matrices should be of equal size\")\n    var resultMatrix = Matrix(rows: lhs.rows, columns: lhs.columns)\n    vDSP_vsubD(rhs.grid, vDSP_Stride(1), lhs.grid, vDSP_Stride(1), &resultMatrix.grid, vDSP_Stride(1), vDSP_Length(lhs.rows * lhs.columns))\n    return resultMatrix\n}\n\n\n/**\n Naive matrices multiplication\n \n Complexity: O(n^3)\n */\npublic func * (lhs: Matrix, rhs: Matrix) -> Matrix {\n    assert(lhs.columns == rhs.rows, \"Left matrix columns should be the size of right matrix's rows\")\n    var resultMatrix = Matrix(rows: lhs.rows, columns: rhs.columns)\n    let order = CblasRowMajor\n    let atrans = CblasNoTrans\n    let btrans = CblasNoTrans\n    let α = 1.0\n    let β = 1.0\n    let resultColumns = resultMatrix.columns\n    lhs.grid.withUnsafeBufferPointer { pa in\n        rhs.grid.withUnsafeBufferPointer { pb in\n            resultMatrix.grid.withUnsafeMutableBufferPointer { pc in\n                cblas_dgemm(order, atrans, btrans, Int32(lhs.rows), Int32(rhs.columns), Int32(lhs.columns), α, pa.baseAddress!, Int32(lhs.columns), pb.baseAddress!, Int32(rhs.columns), β, pc.baseAddress!, Int32(resultColumns))\n            }\n        }\n    }\n    \n    return resultMatrix\n}\n\n// MARK: - Nice additional methods\npublic func * (lhs: Matrix, rhs: Double) -> Matrix {\n    return Matrix(grid: lhs.grid.map({ $0*rhs }), rows: lhs.rows, columns: lhs.columns)\n}\n\npublic func * (lhs: Double, rhs: Matrix) -> Matrix {\n    return rhs * lhs\n}\n\n// MARK: - CustomStringConvertible for debug output\nextension Matrix: CustomStringConvertible {\n    public var description: String {\n        var description = \"\"\n        \n        for i in 0..<rows {\n            let contents = (0..<columns).map{\"\\(self[i, $0])\"}.joined(separator: \"\\t\")\n            \n            switch (i, rows) {\n            case (0, 1):\n                description += \"(\\t\\(contents)\\t)\"\n            case (0, _):\n                description += \"⎛\\t\\(contents)\\t⎞\"\n            case (rows - 1, _):\n                description += \"⎝\\t\\(contents)\\t⎠\"\n            default:\n                description += \"⎜\\t\\(contents)\\t⎥\"\n            }\n            \n            description += \"\\n\"\n        }\n        \n        return description\n    }\n}\n"
  },
  {
    "path": "KalmanFilter.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\tCE866F241D80A2FF00B5A9DD /* DoubleExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE866F231D80A2FF00B5A9DD /* DoubleExtension.swift */; };\n\t\tCE866F261D80A63400B5A9DD /* DoubleExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE866F251D80A63400B5A9DD /* DoubleExtensionTests.swift */; };\n\t\tCEA8B1E91D7EC02B009E3AAD /* Matrix.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA8B1E81D7EC02B009E3AAD /* Matrix.swift */; };\n\t\tCEA8B1EF1D7F1B99009E3AAD /* MatrixTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA8B1EE1D7F1B99009E3AAD /* MatrixTests.swift */; };\n\t\tCEAAE1F11D66640400D29016 /* KalmanFilterType.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEAAE1F01D66640400D29016 /* KalmanFilterType.swift */; };\n\t\tCEAAE1F31D66661D00D29016 /* KalmanFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEAAE1F21D66661D00D29016 /* KalmanFilter.swift */; };\n\t\tCEF0077C1D650AEE0084F081 /* KalmanFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = CEF0077B1D650AEE0084F081 /* KalmanFilter.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tCEF007831D650AEE0084F081 /* KalmanFilter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEF007781D650AEE0084F081 /* KalmanFilter.framework */; };\n\t\tCEF007881D650AEE0084F081 /* KalmanFilterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEF007871D650AEE0084F081 /* KalmanFilterTests.swift */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXContainerItemProxy section */\n\t\tCEF007841D650AEE0084F081 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = CEF0076F1D650AEE0084F081 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = CEF007771D650AEE0084F081;\n\t\t\tremoteInfo = KalmanFilter;\n\t\t};\n/* End PBXContainerItemProxy section */\n\n/* Begin PBXFileReference section */\n\t\tCE866F231D80A2FF00B5A9DD /* DoubleExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DoubleExtension.swift; sourceTree = \"<group>\"; };\n\t\tCE866F251D80A63400B5A9DD /* DoubleExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DoubleExtensionTests.swift; sourceTree = \"<group>\"; };\n\t\tCEA8B1E81D7EC02B009E3AAD /* Matrix.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Matrix.swift; sourceTree = \"<group>\"; };\n\t\tCEA8B1EE1D7F1B99009E3AAD /* MatrixTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MatrixTests.swift; sourceTree = \"<group>\"; };\n\t\tCEAAE1F01D66640400D29016 /* KalmanFilterType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KalmanFilterType.swift; sourceTree = \"<group>\"; };\n\t\tCEAAE1F21D66661D00D29016 /* KalmanFilter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KalmanFilter.swift; sourceTree = \"<group>\"; };\n\t\tCEF007781D650AEE0084F081 /* KalmanFilter.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = KalmanFilter.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tCEF0077B1D650AEE0084F081 /* KalmanFilter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KalmanFilter.h; sourceTree = \"<group>\"; };\n\t\tCEF0077D1D650AEE0084F081 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\tCEF007821D650AEE0084F081 /* KalmanFilterTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KalmanFilterTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tCEF007871D650AEE0084F081 /* KalmanFilterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KalmanFilterTests.swift; sourceTree = \"<group>\"; };\n\t\tCEF007891D650AEE0084F081 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\tCEF007741D650AEE0084F081 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tCEF0077F1D650AEE0084F081 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tCEF007831D650AEE0084F081 /* KalmanFilter.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\tCEF0076E1D650AEE0084F081 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tCEF0077A1D650AEE0084F081 /* KalmanFilter */,\n\t\t\t\tCEF007861D650AEE0084F081 /* KalmanFilterTests */,\n\t\t\t\tCEF007791D650AEE0084F081 /* Products */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tCEF007791D650AEE0084F081 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tCEF007781D650AEE0084F081 /* KalmanFilter.framework */,\n\t\t\t\tCEF007821D650AEE0084F081 /* KalmanFilterTests.xctest */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tCEF0077A1D650AEE0084F081 /* KalmanFilter */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tCEF0077B1D650AEE0084F081 /* KalmanFilter.h */,\n\t\t\t\tCEAAE1F01D66640400D29016 /* KalmanFilterType.swift */,\n\t\t\t\tCEAAE1F21D66661D00D29016 /* KalmanFilter.swift */,\n\t\t\t\tCEA8B1E81D7EC02B009E3AAD /* Matrix.swift */,\n\t\t\t\tCE866F231D80A2FF00B5A9DD /* DoubleExtension.swift */,\n\t\t\t\tCEF0077D1D650AEE0084F081 /* Info.plist */,\n\t\t\t);\n\t\t\tpath = KalmanFilter;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tCEF007861D650AEE0084F081 /* KalmanFilterTests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tCEF007871D650AEE0084F081 /* KalmanFilterTests.swift */,\n\t\t\t\tCEA8B1EE1D7F1B99009E3AAD /* MatrixTests.swift */,\n\t\t\t\tCE866F251D80A63400B5A9DD /* DoubleExtensionTests.swift */,\n\t\t\t\tCEF007891D650AEE0084F081 /* Info.plist */,\n\t\t\t);\n\t\t\tpath = KalmanFilterTests;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXHeadersBuildPhase section */\n\t\tCEF007751D650AEE0084F081 /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tCEF0077C1D650AEE0084F081 /* KalmanFilter.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXHeadersBuildPhase section */\n\n/* Begin PBXNativeTarget section */\n\t\tCEF007771D650AEE0084F081 /* KalmanFilter */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = CEF0078C1D650AEE0084F081 /* Build configuration list for PBXNativeTarget \"KalmanFilter\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tCEF007731D650AEE0084F081 /* Sources */,\n\t\t\t\tCEF007741D650AEE0084F081 /* Frameworks */,\n\t\t\t\tCEF007751D650AEE0084F081 /* Headers */,\n\t\t\t\tCEF007761D650AEE0084F081 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = KalmanFilter;\n\t\t\tproductName = KalmanFilter;\n\t\t\tproductReference = CEF007781D650AEE0084F081 /* KalmanFilter.framework */;\n\t\t\tproductType = \"com.apple.product-type.framework\";\n\t\t};\n\t\tCEF007811D650AEE0084F081 /* KalmanFilterTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = CEF0078F1D650AEE0084F081 /* Build configuration list for PBXNativeTarget \"KalmanFilterTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tCEF0077E1D650AEE0084F081 /* Sources */,\n\t\t\t\tCEF0077F1D650AEE0084F081 /* Frameworks */,\n\t\t\t\tCEF007801D650AEE0084F081 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\tCEF007851D650AEE0084F081 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = KalmanFilterTests;\n\t\t\tproductName = KalmanFilterTests;\n\t\t\tproductReference = CEF007821D650AEE0084F081 /* KalmanFilterTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\tCEF0076F1D650AEE0084F081 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastSwiftUpdateCheck = 0730;\n\t\t\t\tLastUpgradeCheck = 0910;\n\t\t\t\tORGANIZATIONNAME = \"Oleksii Dykan\";\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\tCEF007771D650AEE0084F081 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 7.3.1;\n\t\t\t\t\t\tLastSwiftMigration = 0910;\n\t\t\t\t\t};\n\t\t\t\t\tCEF007811D650AEE0084F081 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 7.3.1;\n\t\t\t\t\t\tLastSwiftMigration = 0910;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = CEF007721D650AEE0084F081 /* Build configuration list for PBXProject \"KalmanFilter\" */;\n\t\t\tcompatibilityVersion = \"Xcode 3.2\";\n\t\t\tdevelopmentRegion = English;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t);\n\t\t\tmainGroup = CEF0076E1D650AEE0084F081;\n\t\t\tproductRefGroup = CEF007791D650AEE0084F081 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\tCEF007771D650AEE0084F081 /* KalmanFilter */,\n\t\t\t\tCEF007811D650AEE0084F081 /* KalmanFilterTests */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\tCEF007761D650AEE0084F081 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tCEF007801D650AEE0084F081 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\tCEF007731D650AEE0084F081 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tCE866F241D80A2FF00B5A9DD /* DoubleExtension.swift in Sources */,\n\t\t\t\tCEAAE1F11D66640400D29016 /* KalmanFilterType.swift in Sources */,\n\t\t\t\tCEAAE1F31D66661D00D29016 /* KalmanFilter.swift in Sources */,\n\t\t\t\tCEA8B1E91D7EC02B009E3AAD /* Matrix.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tCEF0077E1D650AEE0084F081 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tCE866F261D80A63400B5A9DD /* DoubleExtensionTests.swift in Sources */,\n\t\t\t\tCEA8B1EF1D7F1B99009E3AAD /* MatrixTests.swift in Sources */,\n\t\t\t\tCEF007881D650AEE0084F081 /* KalmanFilterTests.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXTargetDependency section */\n\t\tCEF007851D650AEE0084F081 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = CEF007771D650AEE0084F081 /* KalmanFilter */;\n\t\t\ttargetProxy = CEF007841D650AEE0084F081 /* PBXContainerItemProxy */;\n\t\t};\n/* End PBXTargetDependency section */\n\n/* Begin XCBuildConfiguration section */\n\t\tCEF0078A1D650AEE0084F081 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.3;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tCEF0078B1D650AEE0084F081 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.3;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Owholemodule\";\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tCEF0078D1D650AEE0084F081 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tAPPLICATION_EXTENSION_API_ONLY = YES;\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"\";\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tINFOPLIST_FILE = KalmanFilter/Info.plist;\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.violentoctopus.KalmanFilter;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t\tSWIFT_SWIFT3_OBJC_INFERENCE = Default;\n\t\t\t\tSWIFT_VERSION = 4.0;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tCEF0078E1D650AEE0084F081 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tAPPLICATION_EXTENSION_API_ONLY = YES;\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"\";\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tINFOPLIST_FILE = KalmanFilter/Info.plist;\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 9.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.violentoctopus.KalmanFilter;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSWIFT_SWIFT3_OBJC_INFERENCE = Default;\n\t\t\t\tSWIFT_VERSION = 4.0;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tCEF007901D650AEE0084F081 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = KalmanFilterTests/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.violentoctopus.KalmanFilterTests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_SWIFT3_OBJC_INFERENCE = Default;\n\t\t\t\tSWIFT_VERSION = 4.0;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tCEF007911D650AEE0084F081 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tINFOPLIST_FILE = KalmanFilterTests/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.violentoctopus.KalmanFilterTests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_SWIFT3_OBJC_INFERENCE = Default;\n\t\t\t\tSWIFT_VERSION = 4.0;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\tCEF007721D650AEE0084F081 /* Build configuration list for PBXProject \"KalmanFilter\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tCEF0078A1D650AEE0084F081 /* Debug */,\n\t\t\t\tCEF0078B1D650AEE0084F081 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tCEF0078C1D650AEE0084F081 /* Build configuration list for PBXNativeTarget \"KalmanFilter\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tCEF0078D1D650AEE0084F081 /* Debug */,\n\t\t\t\tCEF0078E1D650AEE0084F081 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tCEF0078F1D650AEE0084F081 /* Build configuration list for PBXNativeTarget \"KalmanFilterTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tCEF007901D650AEE0084F081 /* Debug */,\n\t\t\t\tCEF007911D650AEE0084F081 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = CEF0076F1D650AEE0084F081 /* Project object */;\n}\n"
  },
  {
    "path": "KalmanFilter.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:KalmanFilter.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "KalmanFilter.xcodeproj/xcshareddata/xcschemes/KalmanFilter.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"0910\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"CEF007771D650AEE0084F081\"\n               BuildableName = \"KalmanFilter.framework\"\n               BlueprintName = \"KalmanFilter\"\n               ReferencedContainer = \"container:KalmanFilter.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      language = \"\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n         <TestableReference\n            skipped = \"NO\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"CEF007811D650AEE0084F081\"\n               BuildableName = \"KalmanFilterTests.xctest\"\n               BlueprintName = \"KalmanFilterTests\"\n               ReferencedContainer = \"container:KalmanFilter.xcodeproj\">\n            </BuildableReference>\n         </TestableReference>\n      </Testables>\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"CEF007771D650AEE0084F081\"\n            BuildableName = \"KalmanFilter.framework\"\n            BlueprintName = \"KalmanFilter\"\n            ReferencedContainer = \"container:KalmanFilter.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <AdditionalOptions>\n      </AdditionalOptions>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      language = \"\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"CEF007771D650AEE0084F081\"\n            BuildableName = \"KalmanFilter.framework\"\n            BlueprintName = \"KalmanFilter\"\n            ReferencedContainer = \"container:KalmanFilter.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <AdditionalOptions>\n      </AdditionalOptions>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"CEF007771D650AEE0084F081\"\n            BuildableName = \"KalmanFilter.framework\"\n            BlueprintName = \"KalmanFilter\"\n            ReferencedContainer = \"container:KalmanFilter.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "KalmanFilterTests/DoubleExtensionTests.swift",
    "content": "//\n//  DoubleExtensionTests.swift\n//  KalmanFilterTest\n//\n//  Created by Oleksii on 02/07/16.\n//  Copyright © 2016 Oleksii Dykan. All rights reserved.\n//\n\nimport XCTest\n@testable import KalmanFilter\n\nclass DoubleExtensionTests: XCTestCase {\n    \n    func testDoubleAsKalmanInput() {\n        XCTAssertEqual(5.2.transposed, 5.2)\n        XCTAssertEqual(2.0.inversed, 0.5)\n        XCTAssertEqual(0.2.additionToUnit, 0.8)\n    }\n    \n}\n"
  },
  {
    "path": "KalmanFilterTests/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>BNDL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "KalmanFilterTests/KalmanFilterTests.swift",
    "content": "//\n//  KalmanFilterTests.swift\n//  KalmanFilterTests\n//\n//  Created by Oleksii on 17/08/16.\n//  Copyright © 2016 Oleksii Dykan. All rights reserved.\n//\n\nimport XCTest\n@testable import KalmanFilter\n\nclass KalmanFilterTests: XCTestCase {\n    \n    func testKalmanFilter2D() {\n        let measurements = [1.0, 2.0, 3.0]\n        let accuracy = 0.00001\n        \n        let x = Matrix(vector: [0, 0])\n        let P = Matrix(grid: [1000, 0, 0, 1000], rows: 2, columns: 2)\n        let B = Matrix(identityOfSize: 2)\n        let u = Matrix(vector: [0, 0])\n        let F = Matrix(grid: [1, 1, 0, 1], rows: 2, columns: 2)\n        let H = Matrix(grid: [1, 0], rows: 1, columns: 2)\n        let R = Matrix(grid: [1], rows: 1, columns: 1)\n        let Q = Matrix(rows: 2, columns: 2)\n        \n        var kalmanFilter = KalmanFilter(stateEstimatePrior: x, errorCovariancePrior: P)\n        \n        for measurement in measurements {\n            let z = Matrix(grid: [measurement], rows: 1, columns: 1)\n            kalmanFilter = kalmanFilter.update(measurement: z, observationModel: H, covarienceOfObservationNoise: R)\n            kalmanFilter = kalmanFilter.predict(stateTransitionModel: F, controlInputModel: B, controlVector: u, covarianceOfProcessNoise: Q)\n        }\n        \n        let resultX = Matrix(vector: [3.9996664447958645, 0.9999998335552873])\n        let resultP = Matrix(grid: [2.3318904241194827, 0.9991676099921091, 0.9991676099921067, 0.49950058263974184], rows: 2, columns: 2)\n        \n        XCTAssertEqual(kalmanFilter.stateEstimatePrior[0, 0], resultX[0, 0], accuracy: accuracy)\n        XCTAssertEqual(kalmanFilter.stateEstimatePrior[1, 0], resultX[1, 0], accuracy: accuracy)\n        XCTAssertEqual(kalmanFilter.errorCovariancePrior[0, 0], resultP[0, 0], accuracy: accuracy)\n        XCTAssertEqual(kalmanFilter.errorCovariancePrior[0, 1], resultP[0, 1], accuracy: accuracy)\n        XCTAssertEqual(kalmanFilter.errorCovariancePrior[1, 0], resultP[1, 0], accuracy: accuracy)\n        XCTAssertEqual(kalmanFilter.errorCovariancePrior[1, 1], resultP[1, 1], accuracy: accuracy)\n    }\n    \n}\n"
  },
  {
    "path": "KalmanFilterTests/MatrixTests.swift",
    "content": "//\n//  MatrixTests.swift\n//  KalmanFilterTest\n//\n//  Created by Oleksii on 20/06/16.\n//  Copyright © 2016 Oleksii Dykan. All rights reserved.\n//\n\nimport XCTest\n@testable import KalmanFilter\n\nclass MatrixTests: XCTestCase {\n    \n    func testMatrixIsSquare() {\n        XCTAssertTrue(Matrix(identityOfSize: 2).isSquare)\n        XCTAssertFalse(Matrix(rows: 3, columns: 1).isSquare)\n    }\n    \n    func testMatrixEquatable() {\n        var matrixOne = Matrix(rows: 1, columns: 2)\n        var matrixTwo = Matrix(rows: 1, columns: 2)\n        \n        XCTAssertTrue(matrixOne == matrixTwo)\n        XCTAssertTrue(matrixTwo == matrixOne)\n        \n        matrixOne[0, 0] = 1\n        XCTAssertFalse(matrixOne == matrixTwo)\n        \n        matrixOne[0, 0] = 0\n        XCTAssertTrue(matrixTwo == matrixOne)\n        \n        matrixTwo = Matrix(rows: 2, columns: 1)\n        XCTAssertFalse(matrixOne == matrixTwo)\n    }\n    \n    func testMatrixInitialization() {\n        let rows = 4\n        let columns = 3\n        let matrix = Matrix(rows: rows, columns: columns)\n        \n        XCTAssertEqual(matrix.rows, rows)\n        XCTAssertEqual(matrix.columns, columns)\n        XCTAssertEqual(matrix.grid.count, rows * columns)\n        \n        let squareMatrix = Matrix(squareOfSize: rows)\n        \n        XCTAssertEqual(squareMatrix.rows, rows)\n        XCTAssertEqual(squareMatrix.columns, rows)\n        XCTAssertEqual(squareMatrix.grid.count, rows * rows)\n        \n        let identityMatrixSize = 3\n        let identityMatrix = Matrix(identityOfSize: identityMatrixSize)\n        var identityMatrixProper = Matrix(squareOfSize: identityMatrixSize)\n        \n        identityMatrixProper[0, 0] = 1\n        identityMatrixProper[1, 1] = 1\n        XCTAssertNotEqual(identityMatrix, identityMatrixProper)\n        \n        identityMatrixProper[2, 2] = 1\n        XCTAssertEqual(identityMatrix, identityMatrixProper)\n        \n        let vectorMatrixEmpty = Matrix(vectorOf: 2)\n        \n        XCTAssertEqual(vectorMatrixEmpty.rows, 2)\n        XCTAssertEqual(vectorMatrixEmpty.columns, 1)\n        \n        let vectorMatrix = Matrix(vector: [2, 1, 3])\n        \n        XCTAssertEqual(vectorMatrix.rows, 3)\n        XCTAssertEqual(vectorMatrix.columns, 1)\n        XCTAssertEqual(vectorMatrix[0, 0], 2)\n        XCTAssertEqual(vectorMatrix[1, 0], 1)\n        XCTAssertEqual(vectorMatrix[2, 0], 3)\n        \n        let array2d = [[1.0, 0.0], [0.0, 1.0]]\n        XCTAssertEqual(Matrix(array2d), Matrix(identityOfSize: 2))\n        XCTAssertEqual(Matrix([[2.0], [1], [3]]), vectorMatrix)\n    }\n    \n    func testMatrixCheckForSquare() {\n        XCTAssertTrue(Matrix(rows: 2, columns: 2).isSquare)\n        XCTAssertTrue(Matrix(squareOfSize: 2).isSquare)\n        XCTAssertTrue(Matrix(identityOfSize: 2).isSquare)\n        XCTAssertFalse(Matrix(rows: 3, columns: 2).isSquare)\n        XCTAssertFalse(Matrix(rows: 2, columns: 3).isSquare)\n    }\n    \n    func testMatrixIndexValidation() {\n        let rows = 2\n        let columns = 3\n        let matrix = Matrix(rows: rows, columns: columns)\n        \n        XCTAssertTrue(matrix.indexIsValid(forRow: 0, column: 0))\n        XCTAssertTrue(matrix.indexIsValid(forRow: rows - 1, column: columns - 1))\n        XCTAssertFalse(matrix.indexIsValid(forRow: rows, column: columns))\n        XCTAssertFalse(matrix.indexIsValid(forRow: -1, column: -1))\n    }\n    \n    // MARK: Matrix Kalman Filter Extension Tests\n    func testMatrixTranspose() {\n        let initialMatrix = Matrix([[5, 4], [4, 0], [7, 10], [-1, 8]])\n        let transposedMatrixProper = Matrix([[5, 4, 7, -1], [4, 0, 10, 8]])\n        XCTAssertEqual(initialMatrix.transposed, transposedMatrixProper)\n    }\n    \n    func testAdditionToUnit() {\n        let initialMatrix = Matrix([[4, 7, 1], [-2, 8, 3], [5, -4, 11]])\n        let properAddiotionToUnitMatrix = Matrix([[-3, -7, -1], [2, -7, -3], [-5, 4, -10]])\n        \n        XCTAssertEqual(initialMatrix.additionToUnit, properAddiotionToUnitMatrix)\n    }\n    \n    func testMatrixDeterminant() {\n        let initialMatrix = Matrix([[-2, 2, -3], [-1, 1, 3], [2, 0, -1]])\n        XCTAssertEqual(initialMatrix.determinant, 18)\n    }\n    \n    func testMatrixInversed() {\n        let initialMatrix = Matrix([[1, 2, 3], [0, 1, 4], [5, 6, 0]])\n        // Using accelerate causes a very slight precision issue\n        let properInversedMatrix = Matrix([[-24.000000000000089, 18.000000000000068, 5.0000000000000178], [20.000000000000075, -15.000000000000055, -4.0000000000000142], [-5.0000000000000195, 4.0000000000000133, 1.0000000000000033]])\n        \n        XCTAssertEqual(initialMatrix.inversed, properInversedMatrix)\n        XCTAssertEqual(Matrix(grid: [2], rows: 1, columns: 1).inversed, Matrix(grid: [1.0/2], rows: 1, columns: 1))\n    }\n    \n    func testMatrixAdditionAndSubtraction() {\n        let size = (2, 3)\n        let matrixOne = Matrix([[5, 7, 9], [11, -2, -3]])\n        let matrixTwo = Matrix([[-8, 4, 9], [6, 3, 2]])\n        \n        var additionMatrix = Matrix(rows: size.0, columns: size.1)\n        var subtractionMatrix = Matrix(rows: size.0, columns: size.1)\n        \n        additionMatrix[0, 0] = matrixOne[0, 0] + matrixTwo[0, 0]\n        additionMatrix[0, 1] = matrixOne[0, 1] + matrixTwo[0, 1]\n        additionMatrix[0, 2] = matrixOne[0, 2] + matrixTwo[0, 2]\n        additionMatrix[1, 0] = matrixOne[1, 0] + matrixTwo[1, 0]\n        additionMatrix[1, 1] = matrixOne[1, 1] + matrixTwo[1, 1]\n        additionMatrix[1, 2] = matrixOne[1, 2] + matrixTwo[1, 2]\n        \n        XCTAssertEqual(matrixOne + matrixTwo, additionMatrix)\n        \n        subtractionMatrix[0, 0] = matrixOne[0, 0] - matrixTwo[0, 0]\n        subtractionMatrix[0, 1] = matrixOne[0, 1] - matrixTwo[0, 1]\n        subtractionMatrix[0, 2] = matrixOne[0, 2] - matrixTwo[0, 2]\n        subtractionMatrix[1, 0] = matrixOne[1, 0] - matrixTwo[1, 0]\n        subtractionMatrix[1, 1] = matrixOne[1, 1] - matrixTwo[1, 1]\n        subtractionMatrix[1, 2] = matrixOne[1, 2] - matrixTwo[1, 2]\n        \n        XCTAssertEqual(matrixOne - matrixTwo, subtractionMatrix)\n    }\n    \n    func testMatrixMultiplication() {\n        let matrixOne = Matrix([[3.0, 4, 2]])\n        let matrixTwo = Matrix([[13, 9, 7, 15], [8, 7, 4, 6], [6, 4, 0, 3]])\n        let multipliedMatrices = Matrix([[83.0, 63, 37, 75]])\n        \n        XCTAssertEqual(matrixOne * matrixTwo, multipliedMatrices)\n    }\n    \n    func testMatrixMultiplicationByScalar() {\n        let matrix = Matrix(grid: [1, 2, 3, 4], rows: 2, columns: 2)\n        \n        XCTAssertEqual(matrix * 2, Matrix([[2, 4], [6, 8]]))\n        XCTAssertEqual(2 * matrix, Matrix([[2, 4], [6, 8]]))\n        XCTAssertEqual(matrix * 0.5, Matrix([[0.5, 1], [1.5, 2]]))\n    }\n    \n    func testMatrixStringDescription() {\n        let matrix = Matrix([[0.0, 2.0, 3.0, 4.0],\n                             [0.0, 2.0, 3.0, 4.0],\n                             [0.0, 2.0, 3.0, 4.0]])\n        \n        let string = \"⎛\\t0.0\\t2.0\\t3.0\\t4.0\\t⎞\\n\" +\n                     \"⎜\\t0.0\\t2.0\\t3.0\\t4.0\\t⎥\\n\" +\n                     \"⎝\\t0.0\\t2.0\\t3.0\\t4.0\\t⎠\\n\"\n        XCTAssertEqual(matrix.description, string)\n        XCTAssertEqual(Matrix([[0.0, 2.0, 3.0, 4.0]]).description, \"(\\t0.0\\t2.0\\t3.0\\t4.0\\t)\\n\")\n    }\n}\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2019 WEAREREASONABLEPEOPLE B.V.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# KalmanFilter\nSwift implementation of Conventional Kalman Filter algorithm\n\n[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)\n[![Build Status](https://travis-ci.org/wearereasonablepeople/KalmanFilter.svg?branch=master)](https://travis-ci.org/wearereasonablepeople/KalmanFilter)\n[![codecov](https://codecov.io/gh/wearereasonablepeople/KalmanFilter/branch/master/graph/badge.svg)](https://codecov.io/gh/wearereasonablepeople/KalmanFilter)\n\n## Motivation:\n[Kalman filter](https://en.wikipedia.org/wiki/Kalman_filter) is a widely applied algorithm to get a more\naccurate guess in noisy environment. It has a lot of applications in real life such as guidance, navigation\ncontrol for vehicles, etc. **Although it is mostly used to filter GPS data, this framework doesn't have a \nready-to-use solutions that work with GPS and is more general implementation of algorithm.**\n\n## Example of usage\n`Kalman filter` can work with anything that adopts `KalmanInput` protocol. Framework provides `Matrix` \nstruct that conforms to this protocol, although you can use anything that is more suitable for you. For \nexample, framework also provides `Double`'s extension with `KalmanInput` and you can use it if your\n`KalmanFilter` has only 1 dimension.\n\nThe code below is the example of usage of `1D KalmanFilter` taken from \n[here](http://bilgin.esme.org/BitsAndBytes/KalmanFilterforDummies). \n```swift\nlet measurements = [0.39, 0.50, 0.48, 0.29, 0.25, 0.32, 0.34, 0.48, 0.41, 0.45, 0.46, 0.59, 0.42]\nvar filter = KalmanFilter(stateEstimatePrior: 0.0, errorCovariancePrior: 1)\n\nfor measurement in measurements {\n    let prediction = filter.predict(1, controlInputModel: 0, controlVector: 0, covarianceOfProcessNoise: 0)\n    let update = prediction.update(measurement, observationModel: 1, covarienceOfObservationNoise: 0.1)\n    \n    filter = update\n}\n```\n## Sources\nAll the names of properties and methods' parameters names are taken from \n[wikipedia page](https://en.wikipedia.org/wiki/Kalman_filter#Details).\n\nIf you are looking for a good source to understand how `Kalman Filter` works then take a look at \n[this page](http://bilgin.esme.org/BitsAndBytes/KalmanFilterforDummies), \n[this one](http://www.bzarg.com/p/how-a-kalman-filter-works-in-pictures/) and there is a great series of\nvideo tutorials on [udacity](https://www.udacity.com/course/artificial-intelligence-for-robotics--cs373)\n"
  }
]