1 /* 2 __ 3 / _| 4 __ _ _ _ _ __ ___ _ __ __ _ | |_ ___ ___ ___ 5 / _` | | | | '__/ _ \| '__/ _` | | _/ _ \/ __/ __| 6 | (_| | |_| | | | (_) | | | (_| | | || (_) \__ \__ \ 7 \__,_|\__,_|_| \___/|_| \__,_| |_| \___/|___/___/ 8 9 Copyright (C) 2018-2019 Aurora Free Open Source Software. 10 11 This file is part of the Aurora Free Open Source Software. This 12 organization promote free and open source software that you can 13 redistribute and/or modify under the terms of the GNU Lesser General 14 Public License Version 3 as published by the Free Software Foundation or 15 (at your option) any later version approved by the Aurora Free Open Source 16 Software Organization. The license is available in the package root path 17 as 'LICENSE' file. Please review the following information to ensure the 18 GNU Lesser General Public License version 3 requirements will be met: 19 https://www.gnu.org/licenses/lgpl.html . 20 21 Alternatively, this file may be used under the terms of the GNU General 22 Public License version 3 or later as published by the Free Software 23 Foundation. Please review the following information to ensure the GNU 24 General Public License requirements will be met: 25 http://www.gnu.org/licenses/gpl-3.0.html. 26 27 NOTE: All products, services or anything associated to trademarks and 28 service marks used or referenced on this file are the property of their 29 respective companies/owners or its subsidiaries. Other names and brands 30 may be claimed as the property of others. 31 32 For more info about intellectual property visit: aurorafoss.org or 33 directly send an email to: contact (at) aurorafoss.org . 34 */ 35 36 module aurorafw.math.matrix; 37 38 /** @file aurorafw/math/matrix.d 39 * Variable Matrix file. This contains a variable matrix struct that 40 * represents a grid with size of M * N. 41 * @author Luís Ferreira <contact@lsferreira.net> 42 * @since snapshot20180509 43 */ 44 45 /** A struct that represents a variable matrix. A struct that store's 46 * N*M array, allows to manipulate it. 47 * @since snapshot20180930 48 */ 49 @nogc pure @safe struct mat(T, size_t M, size_t N) { 50 this(T num) 51 in { 52 static assert(M == N, "invalid diagonal matrix"); 53 } 54 body { 55 foreach(size_t i; 0..M) 56 matrix[i * M + i] = num; 57 } 58 59 this(immutable ref mat!(T, M, N) mat) 60 { 61 this = mat; 62 } 63 64 this(T[M*N] arr) 65 { 66 matrix = arr; 67 } 68 69 this(T[] arr) 70 in { 71 assert(arr.length == M * N, "array doesn't have the same size"); 72 } 73 body { 74 matrix = arr; 75 } 76 77 pragma(inline) static mat!(T, M, N) zero() 78 { 79 mat!(T, M, N) ret; 80 ret.matrix[0..N*M] = 0; 81 return ret; 82 } 83 84 pragma(inline) static mat!(T, M, N) identity() 85 { 86 mat!(T, M, N) ret; 87 ret.setIdentity(); 88 return ret; 89 } 90 91 void setIdentity() @property 92 { 93 foreach(size_t x; 0 .. M) 94 foreach(size_t y; 0 .. N) 95 if (y == x) 96 matrix[x * M + y] = 1; 97 else 98 matrix[x * M + y] = 0; 99 } 100 101 bool opEquals(mat!(T, M, N) mat) const 102 { 103 return matrix == mat.matrix; 104 } 105 106 T opIndex(in size_t m, in size_t n) const 107 in 108 { 109 assert (n < N && m < M, "index out of bounds"); 110 } 111 body 112 { 113 return matrix[m * M + n]; 114 } 115 116 T opIndex(in size_t i) const 117 in 118 { 119 assert (i < N * M, "index out of bounds"); 120 } 121 body 122 { 123 return matrix[i]; 124 } 125 126 T opIndexAssign(in T val, in size_t m, in size_t n) 127 in 128 { 129 assert (n < N && m < M, "index out of bounds"); 130 } 131 body 132 { 133 return (matrix[m * M + n] = val); 134 } 135 136 T[] opSliceAssign(in T val, in size_t i1, in size_t i2) 137 in 138 { 139 assert (i1 < N * M && i2 < N * M, "index out of bounds"); 140 } 141 body 142 { 143 return (matrix[i1..i2] = val); 144 } 145 146 T[] opSliceAssign(in T val) 147 { 148 return (matrix[] = val); 149 } 150 151 mat!(T, M, N) opAdd(mat!(T, M, N) val) 152 { 153 auto res = mat!(T, M, N)(); 154 foreach(i; 0 .. M) 155 foreach(j; 0 .. N) 156 res[i, j] = this[i, j] + val[i, j]; 157 158 return res; 159 } 160 161 mat!(T, M, N) opSub(mat!(T, M, N) val) 162 { 163 auto res = mat!(T, M, N)(); 164 foreach(i; 0 .. M) 165 foreach(j; 0 .. N) 166 res[i, j] = this[i, j] - val[i, j]; 167 168 return res; 169 } 170 171 mat!(T, M, N) opMul(mat!(T, M, N) val) 172 { 173 auto res = mat!(T, M, N)(); 174 175 foreach (i; 0 .. M) 176 foreach (j; 0 .. N) 177 { 178 T sumProduct = 0; 179 foreach (k; 0 .. N) 180 sumProduct += this[i, k] * val[k, j]; 181 res[i, j] = sumProduct; 182 } 183 184 return res; 185 } 186 187 mat!(T, M, N) opAddAssign(mat!(T, M, N) val) 188 { 189 this += val; 190 return this; 191 } 192 193 mat!(T, M, N) opSubAssign(mat!(T, M, N) val) 194 { 195 this -= val; 196 return this; 197 } 198 199 mat!(T, M, N) opMulAssign(mat!(T, M, N) val) 200 { 201 this *= val; 202 return this; 203 } 204 205 mat!(T, M, N) opMul(T val) 206 { 207 auto res = mat!(T, M, N)(); 208 foreach(i, v; matrix) 209 res.matrix[i] = v * val; 210 return res; 211 } 212 213 mat!(T, M, N) opMulAssign(T val) 214 { 215 foreach(ref v; matrix) 216 v*= val; 217 return this; 218 } 219 220 T[M*N] matrix; 221 } 222 223 alias mat!(float, 2, 2) Matrix2x2f, Matrix2f, mat2; 224 alias mat!(float, 3, 3) Matrix3x3f, Matrix3f, mat3; 225 alias mat!(float, 4, 4) Matrix4x4f, Matrix4f, mat4; 226 alias mat!(double, 2, 2) Matrix2x2d, Matrix2d; 227 alias mat!(double, 3, 3) Matrix3x3d, Matrix3d; 228 alias mat!(double, 4, 4) Matrix4x4d, Matrix4d;