1 /// Arbitrary indexable SIMD optimized tensor implementation. 2 module tern.legacy.tensor; 3 4 import tern.legacy.matrix; 5 import std.conv; 6 7 /// Arbitrary tensor implementation, allows any row length less than or equal to 256 bits in total and can be interacted with as an array. 8 public struct Tensor(T, size_t ROWS, size_t COLUMNS, size_t DEPTH) 9 { 10 public: 11 final: 12 Matrix!(T, ROWS, COLUMNS)[DEPTH] data; 13 14 this(Matrix!(T, ROWS, COLUMNS)[DEPTH] data) 15 { 16 this.data = data; 17 } 18 19 auto opBinary(string op, R)(const R rhs) 20 { 21 auto data = this.data; 22 foreach (i; 0..COLUMNS) 23 mixin("data[i] "~op~"= rhs;"); 24 return Tensor!(T, ROWS, COLUMNS, DEPTH)(data); 25 } 26 27 auto opBinary(string op, R)(const R rhs) shared 28 { 29 auto data = this.data; 30 foreach (i; 0..COLUMNS) 31 mixin("data[i] "~op~"= rhs;"); 32 return Tensor!(T, ROWS, COLUMNS, DEPTH)(data); 33 } 34 35 auto opBinaryRight(string op, L)(const L lhs) 36 { 37 auto data = this.data; 38 foreach (i; 0..COLUMNS) 39 mixin("lhs "~op~"= data[i];"); 40 return Tensor!(T, ROWS, COLUMNS, DEPTH)(data); 41 } 42 43 auto opBinaryRight(string op, L)(const L lhs) shared 44 { 45 auto data = this.data; 46 foreach (i; 0..COLUMNS) 47 mixin("lhs "~op~"= data[i];"); 48 return Tensor!(T, ROWS, COLUMNS, DEPTH)(data); 49 } 50 51 auto opOpAssign(string op, A)(A ahs) 52 { 53 foreach (i; 0..COLUMNS) 54 mixin("data[i] "~op~"= ahs;"); 55 return this; 56 } 57 58 auto opOpAssign(string op, A)(A ahs) shared 59 { 60 foreach (i; 0..COLUMNS) 61 mixin("data[i] "~op~"= ahs;"); 62 return this; 63 } 64 65 string toString() const shared 66 { 67 return data.to!string; 68 } 69 70 string toString() const 71 { 72 return data.to!string; 73 } 74 }