import Foundation /// Multi-dimensional tensor for compute operations. /// /// ```swift /// // Create a 2D tensor /// let matrix = Tensor(shape: [2, 3], data: [1, 2, 3, 4, 5, 6]) /// /// // Create random tensor /// let random = Tensor.rand([512, 512]) /// /// // Operations /// let mean = random.mean() /// let transposed = matrix.transpose() /// ``` public struct Tensor: Codable, Equatable { public let shape: [Int] public let data: [Double] public let dtype: Precision /// Total number of elements public var size: Int { shape.reduce(1, *) } /// Number of dimensions public var ndim: Int { shape.count } public init(shape: [Int], data: [Double], dtype: Precision = .fp32) { let expectedSize = shape.reduce(1, *) precondition(data.count == expectedSize, "Data size \(data.count) does not match shape \(shape)") self.shape = shape self.data = data self.dtype = dtype } /// Get element at indices public subscript(indices: Int...) -> Double { precondition(indices.count == shape.count, "Index dimensions must match tensor dimensions") var idx = 0 var stride = 1 for i in (0.. Tensor { let newSize = newShape.reduce(1, *) precondition(newSize == size, "Cannot reshape tensor of size \(size) to shape \(newShape)") return Tensor(shape: newShape, data: data, dtype: dtype) } /// Transpose 2D tensor public func transpose() -> Tensor { precondition(ndim == 2, "Transpose only supported for 2D tensors") let rows = shape[0] let cols = shape[1] var transposed = [Double](repeating: 0, count: data.count) for i in 0.. Double { data.reduce(0, +) / Double(data.count) } /// Compute sum of all elements public func sum() -> Double { data.reduce(0, +) } /// Compute standard deviation public func std() -> Double { let meanVal = mean() let variance = data.map { ($0 - meanVal) * ($0 - meanVal) }.reduce(0, +) / Double(data.count) return sqrt(variance) } /// Find maximum value public func max() -> Double { data.max() ?? .nan } /// Find minimum value public func min() -> Double { data.min() ?? .nan } /// Apply ReLU activation public func relu() -> Tensor { Tensor(shape: shape, data: data.map { Swift.max(0, $0) }, dtype: dtype) } /// Apply sigmoid activation public func sigmoid() -> Tensor { Tensor(shape: shape, data: data.map { 1 / (1 + exp(-$0)) }, dtype: dtype) } /// Apply softmax activation public func softmax() -> Tensor { let maxVal = max() let expValues = data.map { exp($0 - maxVal) } let sum = expValues.reduce(0, +) return Tensor(shape: shape, data: expValues.map { $0 / sum }, dtype: dtype) } /// Convert to nested array (1D or 2D) public func toNestedArray() -> Any { switch ndim { case 1: return data case 2: let rows = shape[0] let cols = shape[1] return (0.. Tensor { Tensor(shape: [data.count], data: data) } /// Create tensor from 2D array public static func of(_ data: [[Double]]) -> Tensor { let rows = data.count let cols = data[0].count let flat = data.flatMap { $0 } return Tensor(shape: [rows, cols], data: flat) } /// Create tensor filled with zeros public static func zeros(_ shape: [Int]) -> Tensor { let size = shape.reduce(1, *) return Tensor(shape: shape, data: [Double](repeating: 0, count: size)) } /// Create tensor filled with ones public static func ones(_ shape: [Int]) -> Tensor { let size = shape.reduce(1, *) return Tensor(shape: shape, data: [Double](repeating: 1, count: size)) } /// Create tensor with uniform random values [0, 1) public static func rand(_ shape: [Int]) -> Tensor { let size = shape.reduce(1, *) return Tensor(shape: shape, data: (0.. Tensor { let size = shape.reduce(1, *) return Tensor(shape: shape, data: (0.. Tensor { var data = [Double](repeating: 0, count: n * n) for i in 0.. Tensor { let size = Int(ceil((end - start) / step)) return Tensor(shape: [size], data: (0.. Tensor { let step = (end - start) / Double(num - 1) return Tensor(shape: [num], data: (0..