Created
October 24, 2017 08:34
-
-
Save KatagiriSo/28a1166da8235abb4d4aa06df86c6de1 to your computer and use it in GitHub Desktop.
Matrix swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// RDMatrix.swift | |
// RDMatrix | |
// | |
// Created by KatagiriSo on 2017/10/24. | |
// Copyright © 2017年 RodhosSoft. All rights reserved. | |
// | |
import Foundation | |
class RDMatrix <T:CustomStringConvertible> : CustomStringConvertible { | |
var maxX:Int = 0 | |
var maxY:Int = 0 | |
private var data:[String:T] = [:] | |
init() { | |
} | |
init(list:[[T]]) { | |
read(list: list) | |
} | |
init(vect:[T]) { | |
read(list: [vect]) | |
} | |
private static func key(_ x:Int, y:Int) -> String { | |
return "\(x)&\(y)" | |
} | |
func transpose() -> RDMatrix<T> { | |
let matrix = RDMatrix<T>() | |
for x in 0..<maxX { | |
for y in 0..<maxY { | |
matrix.set(y, x, self.get(x, y)) | |
} | |
} | |
return matrix | |
} | |
func set(_ x:Int, _ y:Int, _ v:T?) { | |
if x>=maxX { | |
self.maxX = x+1 | |
} | |
if y>=maxY { | |
self.maxY = y+1 | |
} | |
data[type(of:self).key(x, y: y)] = v | |
} | |
func get(_ x:Int, _ y:Int) -> T? { | |
return data[type(of:self).key(x, y: y)] | |
} | |
func clear() { | |
maxX = 0 | |
maxY = 0 | |
data.removeAll() | |
} | |
func read(list:[[T]]) { | |
self.clear() | |
var y = 0 | |
for lines in list { | |
var x = 0 | |
for num in lines { | |
self.set(x, y, num) | |
x = x + 1 | |
} | |
y = y + 1 | |
} | |
} | |
var description:String { | |
get { | |
var lines = "" | |
for y in 0..<maxY { | |
for x in 0..<maxX { | |
let v = get(x, y) | |
if let v = v { | |
lines = lines + String(describing: v) | |
} else { | |
lines = lines + "0" | |
} | |
} | |
lines = lines + "\n" | |
} | |
return lines | |
} | |
} | |
} | |
func *(left:RDMatrix<Int>, right:RDMatrix<Int>) -> RDMatrix<Int>? { | |
guard left.maxY == right.maxX else { | |
return nil | |
} | |
let matrix = RDMatrix<Int>() | |
matrix.maxX = left.maxX | |
matrix.maxY = right.maxY | |
for x in 0..<left.maxX { | |
for y in 0..<right.maxY { | |
var v:Int? = nil | |
for i in 0..<left.maxY { | |
if let l = left.get(x, i), let r = right.get(i, y) { | |
if let vv = v { | |
v = vv + l*r | |
} else { | |
v = l*r | |
} | |
} | |
} | |
matrix.set(x, y, v) | |
} | |
} | |
return matrix | |
} | |
func *(left:RDMatrix<Float>, right:RDMatrix<Float>) -> RDMatrix<Float>? { | |
guard left.maxY == right.maxX else { | |
return nil | |
} | |
let matrix = RDMatrix<Float>() | |
matrix.maxX = left.maxX | |
matrix.maxY = right.maxY | |
for x in 0..<left.maxX { | |
for y in 0..<right.maxY { | |
var v:Float? = nil | |
for i in 0..<left.maxY { | |
if let l = left.get(x, i), let r = right.get(i, y) { | |
if let vv = v { | |
v = vv + l*r | |
} else { | |
v = l*r | |
} | |
} | |
} | |
matrix.set(x, y, v) | |
} | |
} | |
return matrix | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment