Knowledge Map
2차원 행렬 클래스 본문
선형 대수에 행렬이 많이 나오는데, 행렬 책만 보기에도 그렇고, JS에는 파이썬의 Pandas나 그외 수학 라이브러리 같은 유명한 라이브러리는 없어서 간단한 수준의 2차원 행렬 클래스를 만들어 보았다. 행렬 입력하려고 [ [1,2,3], [1,2,3] ] 이런식으로 입력하는건 좀 많이 귀찮아서 그냥 1차원 배열로 입력하고, 열과 행의 길이를 입력해 놓아서 연산할때는 알아서 처리하게 했다.
배워가면서 점차 추가할 생각인데 일단은 해당 행 가져오기(getRow), 해당 열 가져오기(getCol), 행렬 생성, 행렬 합(add), 행렬 곱(x)만 해놓았다. 공부하면서 끄적거릴 용도라서 성능은 딱히..... ㅠㅠ
추가 : 0행렬, 단위행렬 추가
추가 : N x M => M x n 변환 추가
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | class Matrix { constructor({row, col, arr}){ this.row = row; this.col = col; this.arr = arr; } getRow(num){ var t = this.col * (num -1); return this.arr.slice(t, t+this.col); } getCol(num){ var result = [], len = this.arr.length, arr = this.arr, i = num-1; while(i < len){result.push(arr[i]); i+=this.col; } return result; } getOne(x,y){ return this.arr[(x-1)*this.col + (y-1)]; } add(v){ if(!(v instanceof Matrix) && isNaN(v) ) throw 'Matrix 클래스 또는 숫자만 가능합니다.'; if(typeof v === 'number') return new Matrix({ row:this.row, col:this.col, arr:this.arr.map(one => one+v) }); if(this.row !== v.row || this.col !== v.col) throw '행렬합은 동일한 사이즈의 행렬끼리만 가능합니다.'; return new Matrix({ row:this.row, col:this.col, arr:this.arr.map((o,i)=>o+v.arr[i]) }); } zero(){ return new Matrix({ row:this.row, col:this.col, arr:'0'.repeat(this.row*this.col).split('').map(a=>+a) }); } ident(){ return new Matrix({ row:this.row, col:this.col, arr: ('1'+('0'.repeat(this.col)+'1').repeat(this.row -1)).split('').map(o=>+o) }); } x(v){ if(!(v instanceof Matrix) && isNaN(v) ) throw 'Matrix 클래스 또는 숫자만 가능합니다.'; if(typeof v === 'number') return new Matrix({ row:this.row, col:this.col, arr:this.arr.map(one => one*v) }); if(this.col !== v.row) throw '행렬곱은 앞 행렬의 col 수와 뒷 행렬의 row 수가 같아야 합니다.'; var result = [], vTemp = []; for(var i = 0; i < this.row; i++){ for(var j = 0; j < v.col; j++){ result.push(this.getRow(i+1).reduce( (p,a,i) => p + a * (vTemp[j]|| (vTemp[j] = v.getCol(j+1)))[i],0) ); } } return new Matrix({row:this.row, col:v.col, arr:result}); } show() { console.log( this.arr.reduce( (p,a,i) => p + " " + a + (i % this.col === (this.col - 1) ? "\n" : "") , "" ) ); } tran1() { // N x N 행렬일때 변환 if(this.col !== this.row) throw "행과 열의 길이가 같아야 합니다."; var len = this.row; var temp = 0; var tempIndex = 0; var result = this.arr.slice();debugger; for(var i = 0; i < len; i++){ for(var j = i*(len + 1)+1; j < len*(i+1); j++){ tempIndex = (j - i * len) * len + i; temp = result[tempIndex]; result[tempIndex] = result[j]; result[j] = temp; } } return new Matrix({row:this.row,col:this.col,arr:result}); } tran2() { // N x M 행렬 => M x N 행렬 var result = []; for(var i = 0; i < this.col; i++){ result.push(...this.getCol(i+1)); } return new Matrix({row:this.col, col:this.row, arr:result}); } } | cs |
테스트
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | var a = new Matrix({row:4, col:4, arr:[11,12,13,14,21,22,23,24,31,32,33,34,41,42,43,44]}); var b = new Matrix({row:4, col:4, arr:[11,12,13,14,21,22,23,24,31,32,33,34,41,42,43,44]}); a.x(10); // 스칼라 곱 a.x(b); // 행렬 곱 AxB // N x N 행렬 변환 var c = new Matrix({row:4,col:4,arr:[1,1,1,1,0,1,1,1,0,0,1,1,0,0,0,1]}) c.tran1().show(); // M x N => N x M var d = new Matrix({row:5,col:3,arr:[1,1,1,1,1,1,0,1,1,0,0,1,0,0,0]}); d.tran2().show(); d.tran2().tran2().show(); | cs |
'WEB > JAVASCRIPT' 카테고리의 다른 글
formData & file sending (0) | 2018.02.08 |
---|---|
4x4 행렬곱 연산 테스트 (0) | 2017.09.25 |
Dispatch (0) | 2017.08.06 |
ES5 에서의 실행 컨텍스트 (0) | 2017.07.31 |
javascript API Geolocation (0) | 2017.04.25 |
Comments