1 /* 2 * Copyright (C) 2012-2013 たかはしのんき. All rights reserved. 3 * 4 * History: 5 * 0.7 2013-06-19 コメントの修正。 6 * 0.6 2013-06-15 JsDoc Toolkit対応。 7 * 0.5 2013-03-16 行ベクトルを BMatrix としてサポート。 8 * 0.4 2012-05-17 メソッド getValue, cross の性能改善。 9 * 0.3 2012-05-15 初期値の設定方法 2.を追加。prototype 設定の記法を変更。 10 * 0.2 2012-05-10 メソッド abs, inv, equals, diff, xor, mul, dot, cross, toTeX の追加。 11 * 0.1 2012-05-10 新規作成。Java 版より移植。 12 */ 13 14 /** 15 * @fileOverview BVector - 2進ベクトルオブジェクトの定義 16 * @version 0.7 17 * @author たかはしのんき 18 * 19 */ 20 21 // ビット操作のためのマスクを定義します。 22 var mask = [ 23 0x80000000, 0x40000000, 0x20000000, 0x10000000, 24 0x08000000, 0x04000000, 0x02000000, 0x01000000, 25 0x00800000, 0x00400000, 0x00200000, 0x00100000, 26 0x00080000, 0x00040000, 0x00020000, 0x00010000, 27 0x00008000, 0x00004000, 0x00002000, 0x00001000, 28 0x00000800, 0x00000400, 0x00000200, 0x00000100, 29 0x00000080, 0x00000040, 0x00000020, 0x00000010, 30 0x00000008, 0x00000004, 0x00000002, 0x00000001 31 ]; 32 33 /** 34 * 2進ベクトルオブジェクト BVector を定義します。<br> 35 * 1. bv = new BVector(4); // 次数 4 の2進ベクトル、初期値は (0, 0, 0, 0)<br> 36 * 2. bv = new BVector(4, 1); // 次数 4 の2進ベクトル、初期値は (1, 1, 1, 1)<br> 37 * 3. bv = new BVector(1, 0, 1, 0); // 次数 4 の2進ベクトル、初期値は (1, 0, 1, 0) 38 * @constructor 39 * @this {BVector} 40 * @since 0.1 41 */ 42 BVector = function() { 43 this.order = arguments.length; 44 if (arguments.length == 1) 45 this.order = arguments[0]; 46 if (arguments.length == 2 && arguments[0] > 1) 47 this.order = arguments[0]; 48 this.bits = new Array(Math.ceil(this.order / 32.0)); 49 if (arguments.length == 1) 50 this.clear(); 51 else if (arguments.length == 2 && arguments[0] > 1 && arguments[1] == 1) 52 for (var i = 1; i <= this.order; i++) 53 this.setValue(i, 1); 54 else 55 for (var i = 1; i <= this.order; i++) 56 if (arguments[i - 1]) 57 this.setValue(i, 1); 58 }; 59 60 BVector.prototype = { 61 62 /** 63 * 2進ベクトルをゼロクリアします。 64 * @since 0.2 65 */ 66 clear : function() { 67 for (var i = 0; i < this.bits.length; i++) 68 this.bits[i] = 0; 69 }, 70 71 /** 72 * 2進ベクトルオブジェクト BVector の要素 i に 0 か 1 の value を設定するメソッド 73 * BVector.setValue(i, value) を定義します。 74 * @param i 要素番号 75 * @param value 設定する値 76 * @since 0.1 77 */ 78 setValue : function(i, value) { 79 var i0 = i - 1; // 0 originに変換 80 var i1 = i0 & 0x1F; // 32 の剰余 81 var i2 = i0 >> 5; // 32 の商 82 if (value == 1) 83 this.bits[i2] |= mask[i1]; 84 else if (value == 0) 85 this.bits[i2] &= ~mask[i1]; 86 }, 87 88 /** 89 * 2進ベクトルオブジェクト BVector の要素 i の値を取り出すメソッド 90 * BVector.getValue(i) を定義します。 91 * @param i 要素番号 92 * @return 値 93 * @since 0.1 94 */ 95 getValue : function(i) { 96 var i0 = i - 1; // 0 originに変換 97 // i0 & 0x1F は 32 の剰余 98 // i0 >> 5 は 32 の商 99 return (this.bits[i0 >> 5] & mask[i0 & 0x1F]) ? 1 : 0; 100 }, 101 102 /** 103 * 2進ベクトルオブジェクト BVector をコピーするメソッド 104 * BVector.clone() を定義します。 105 * @return 2進ベクトルのコピーを返します。 106 * @since 0.1 107 */ 108 clone : function() { 109 var bv = new BVector(this.order); 110 for (var i = 0; i < this.bits.length; i++) 111 bv.bits[i] = this.bits[i]; 112 return bv; 113 }, 114 115 /** 116 * 2進ベクトルの値が1の要素を数え上げます。 117 * @return 値が1の要素を数え上げた数を返します。 118 * @since 0.2 119 */ 120 abs : function() { 121 var n = 0; 122 for (var i = 1; i <= this.order; i++) 123 if (this.getValue(i) == 1) 124 n++; 125 return n; 126 }, 127 128 /** 129 * 2進ベクトルを反転して(invert)返します。 130 * @return ベクトルの反転を返します。 131 * @since 0.2 132 */ 133 inv : function() { 134 var bv = new BVector(this.order); 135 var m1 = (this.order - 1) % 32; // 剰余 136 var mask1 = mask[m1]; 137 for (var mask2 = 0; mask1 != 0; mask1 <<= 1) { 138 mask2 |= mask1; 139 for (var i = 0; i < this.bits.length - 1; i++) 140 bv.bits[i] = ~this.bits[i]; 141 bv.bits[i] = ~this.bits[i] & mask2; 142 } 143 return bv; 144 }, 145 146 /** 147 * 2進ベクトルを転置して(transpose)2進行列として返します。 148 * @return ベクトルの転置を返します。 149 * @since 0.5 150 */ 151 tran : function() { 152 var bm = new BMatrix(1, this.order); 153 for (var j = 1; j <= this.order; j++) 154 bm.setValue(1, j, this.getValue(j)); 155 return bm; 156 }, 157 158 /** 159 * 2つの2進ベクトルが等しければtrueを返します。同じでないかエラーの場合はfalseを返します。 160 * @param bv2 比較対象のベクトル 161 * @return 2つのベクトルが等しければtrueを返します。 162 * @since 0.2 163 */ 164 equals : function(bv2) { 165 if (this.order != bv2.order) 166 return false; // 次元が異なる 167 for (var i = 0; i < this.bits.length; i++) 168 if (this.bits[i] != bv2.bits[i]) 169 return false; // 値が異なる 170 return true; 171 }, 172 173 /** 174 * 2進ベクトルオブジェクト bv2 との論理和をとるメソッド 175 * BVector.or(bv2) を定義します。 176 * @param bv2 論理和の第2オペランドを指定します。 177 * @return bv2 との論理和を返します。 178 * @since 0.1 179 */ 180 or : function(bv2) { 181 if (this.order != bv2.order) 182 return null; 183 var bv = this.clone(); 184 for (var i = 0; i < this.bits.length; i++) 185 bv.bits[i] |= bv2.bits[i]; 186 return bv; 187 }, 188 189 /** 190 * 2進ベクトルオブジェクト bv2 との論理積をとるメソッド 191 * BVector.and(bv2) を定義します。 192 * @param bv2 論理積の第2オペランドを指定します。 193 * @return bv2 との論理積を返します。 194 * @since 0.1 195 */ 196 and : function(bv2) { 197 if (this.order != bv2.order) 198 return null; 199 var bv = this.clone(); 200 for (var i = 0; i < this.bits.length; i++) 201 bv.bits[i] &= bv2.bits[i]; 202 return bv; 203 }, 204 205 /** 206 * 2進ベクトル同士の論理差を返します。エラーの場合はnullを返します。 207 * @param bv2 論理差の第2オペランド 208 * @return 2つのベクトルの論理差を返します。 209 * @since 0.2 210 */ 211 diff : function(bv2) { 212 if (this.order != bv2.order) 213 return null; 214 var bv = this.clone(); 215 for (var i = 0; i < this.bits.length; i++) 216 bv.bits[i] &= ~bv2.bits[i]; 217 return bv; 218 }, 219 220 /** 221 * 2進行列同士の排他的論理和を返します。エラーの場合はnullを返します。 222 * @param bv2 排他的論理和の第2オペランド 223 * @return 2つの行列の排他的論理和を返します。 224 * @since 0.2 225 */ 226 xor : function(bv2) { 227 if (this.order != bv2.order) 228 return null; 229 var bv = this.clone(); 230 for (var i = 0; i < this.bits.length; i++) 231 bv.bits[i] ^= bv2.bits[i]; 232 return bv; 233 }, 234 235 /** 236 * ベクトルとスカラ(0か1)の積を返します。エラーの場合はnullを返します。 237 * @param b2 積の第2オペランド 238 * @return ベクトルとスカラの積を返します。 239 * @since 0.2 240 */ 241 mul : function(b2) { 242 if (b2 != 0 && b2 != 1) 243 return null; 244 var bv = new BVector(this.order); 245 if (b2 == 0) 246 return bv; // 0 ベクトル 247 else 248 return this.clone(); 249 }, 250 251 /** 252 * 2進ベクトル同士の積(ドット積)を返します。エラーの場合は-1を返します。 253 * @param bv2 積の第2オペランド 254 * @return 2つのベクトルのドット積を返します。 255 * @since 0.2 256 */ 257 dot : function(bv2) { 258 if (this.order != bv2.order) 259 return -1; 260 var b = 0; 261 for (var i = 1; i <= this.order; i++) 262 b |= (this.getValue(i) & bv2.getValue(i)); 263 return b; 264 }, 265 266 /** 267 * 2進ベクトルと2進ベクトルの転置との積(クロス積)を返します。エラーの場合はnullを返します。 268 * @param bv2 積の第2オペランド 269 * @return 2つのベクトルのクロス積を返します。 270 * @since 0.2 271 */ 272 cross : function(bv2) { 273 if (this.order != bv2.order) 274 return null; 275 var bm = new BMatrix(this.order, this.order); 276 for (var j = 0; j < this.order; j++) 277 if (bv2.getValue(j + 1) == 1) 278 bm.colv[j] = this.clone(); 279 return bm; 280 }, 281 282 /** 283 * 2進ベクトルオブジェクト BVector を文字列に変換するメソッド 284 * BVector.toString() を定義します。 285 * @return 文字列を返します。 286 * @since 0.1 287 */ 288 toString : function() { 289 var str = "("; 290 for (var i = 0; i < this.order; i++) { 291 str = str + this.getValue(i + 1); // 1 origin に変換 292 if (i < this.order - 1) 293 str = str + ","; 294 } 295 str = str + ")"; 296 return str; 297 }, 298 299 /** 300 * 2進ベクトルオブジェクト BVector を TeX 形式に変換します。 301 * @since 0.2 302 */ 303 toTeX : function() { 304 var str = "\\begin{pmatrix}"; 305 for (var i = 0; i < this.order; i++) { 306 str = str + this.getValue(i + 1); // 1 origin に変換 307 if (i < this.order - 1) 308 str = str + "\\\\"; 309 } 310 str = str + "\\end{pmatrix}"; 311 return str; 312 }, 313 }; 314