2 * PROJECT: NyARToolkit
\r
3 * --------------------------------------------------------------------------------
\r
4 * This work is based on the original ARToolKit developed by
\r
7 * HITLab, University of Washington, Seattle
\r
8 * http://www.hitl.washington.edu/artoolkit/
\r
10 * The NyARToolkit is Java edition ARToolKit class library.
\r
11 * Copyright (C)2008-2009 Ryo Iizuka
\r
13 * This program is free software: you can redistribute it and/or modify
\r
14 * it under the terms of the GNU General Public License as published by
\r
15 * the Free Software Foundation, either version 3 of the License, or
\r
16 * (at your option) any later version.
\r
18 * This program is distributed in the hope that it will be useful,
\r
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
21 * GNU General Public License for more details.
\r
23 * You should have received a copy of the GNU General Public License
\r
24 * along with this program. If not, see <http://www.gnu.org/licenses/>.
\r
26 * For further information please contact.
\r
27 * http://nyatla.jp/nyatoolkit/
\r
28 * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
\r
31 package jp.nyatla.nyartoolkit.core;
\r
33 import jp.nyatla.nyartoolkit.NyARException;
\r
34 import jp.nyatla.nyartoolkit.core.types.matrix.*;
\r
38 * ARToolKitのARMat構造体と、その処理関数に相当する機能があります。
\r
39 * 2x2,3x3,4x4行列については、NyAToolKitの行列計算クラス({@link NyARDoubleMatrix44},{@link NyARDoubleMatrix33},{@link NyARDoubleMatrix22},)
\r
40 * がありますので、こちらを使ってください。
\r
42 * このクラスは、今後統合・削除する可能性があります。
\r
45 public class NyARMat
\r
47 /** 配列値を格納するバッファ。配列サイズと行列サイズは必ずしも一致しないことに注意。配列のサイズを行列の大きさとして使わないこと!*/
\r
48 protected double[][] _m;
\r
49 private int[] __matrixSelfInv_nos;
\r
57 * @throws NyARException
\r
59 protected NyARMat() throws NyARException
\r
61 throw new NyARException();
\r
65 * 行列のサイズを指定して、NyARMatオブジェクトを作成します。
\r
71 public NyARMat(int i_row, int i_clm)
\r
73 this._m = new double[i_row][i_clm];
\r
76 this.__matrixSelfInv_nos=new int[i_row];
\r
101 * 関数を実行すると、行列の各値は不定になります。
\r
107 public void realloc(int i_row, int i_clm)
\r
109 if (i_row <= this._m.length && i_clm <= this._m[0].length) {
\r
113 this._m = new double[i_row][i_clm];
\r
114 this.__matrixSelfInv_nos=new int[i_row];
\r
122 * i_mat_aとi_mat_bの積を計算して、thisへ格納します。
\r
127 * @throws NyARException
\r
129 public void matrixMul(NyARMat i_mat_a, NyARMat i_mat_b) throws NyARException
\r
131 assert i_mat_a.clm == i_mat_b.row && this.row==i_mat_a.row && this.clm==i_mat_b.clm;
\r
135 double[][] am = i_mat_a._m, bm = i_mat_b._m, dm = this._m;
\r
137 for (r = 0; r < this.row; r++) {
\r
138 for (c = 0; c < this.clm; c++) {
\r
140 for (i = 0; i < i_mat_a.clm; i++) {
\r
141 w += am[r][i] * bm[i][c];
\r
150 * 逆行列を計算して、thisへ格納します。
\r
152 * 逆行列が計算できたかの、真偽値を返します。trueなら、逆行列が存在します。falseなら、逆行列はありません。
\r
153 * 失敗すると、thisの内容は不定になります。
\r
154 * @throws NyARException
\r
156 public boolean matrixSelfInv() throws NyARException
\r
158 double[][] ap = this._m;
\r
159 int dimen = this.row;
\r
160 int dimen_1 = dimen - 1;
\r
161 double[] ap_n, ap_ip, ap_i;// wap;
\r
163 int[] nos = __matrixSelfInv_nos;//ワーク変数
\r
165 double p, pbuf, work;
\r
170 throw new NyARException();
\r
172 ap[0][0] = 1.0 / ap[0][0];// *ap = 1.0 / (*ap);
\r
173 return true;/* 1 dimension */
\r
176 for (int n = 0; n < dimen; n++) {
\r
181 * nyatla memo ipが定まらないで計算が行われる場合があるので挿入。 ループ内で0初期化していいかが判らない。
\r
185 for (int n = 0; n < dimen; n++) {
\r
186 ap_n = ap[n];// wcp = ap + n * rowa;
\r
188 for (int i = n; i < dimen; i++) {
\r
189 if (p < (pbuf = Math.abs(ap[i][0]))) {
\r
194 // if (p <= matrixSelfInv_epsl){
\r
197 // throw new NyARException();
\r
205 for (j = 0; j < dimen; j++) {// for(j = 0, wap = ap + ip * rowa,
\r
206 // wbp = wcp; j < dimen ; j++) {
\r
207 work = ap_ip[j]; // work = *wap;
\r
208 ap_ip[j] = ap_n[j];
\r
213 for (j = 0; j < dimen_1; j++) {
\r
214 ap_n[j] = ap_n[j + 1] / work;// *wap = *(wap + 1) / work;
\r
216 ap_n[j] = 1.0 / work;// *wap = 1.0 / work;
\r
217 for (int i = 0; i < dimen; i++) {
\r
219 ap_i = ap[i];// wap = ap + i * rowa;
\r
221 for (j = 0; j < dimen_1; j++) {// for(j = 1, wbp = wcp,work = *wap;j < dimen ;j++, wap++, wbp++)
\r
222 ap_i[j] = ap_i[j + 1] - work * ap_n[j];// wap = *(wap +1) - work *(*wbp);
\r
224 ap_i[j] = -work * ap_n[j];// *wap = -work * (*wbp);
\r
229 for (int n = 0; n < dimen; n++) {
\r
230 for (j = n; j < dimen; j++) {
\r
236 for (int i = 0; i < dimen; i++) {
\r
238 work = ap_i[j];// work = *wap;
\r
239 ap_i[j] = ap_i[n];// *wap = *wbp;
\r
240 ap_i[n] = work;// *wbp = work;
\r
249 public void zeroClear()
\r
253 for (i = row - 1; i >= 0; i--) {
\r
254 for (i2 = clm - 1; i2 >= 0; i2--) {
\r
261 * i_copy_fromの内容を、thisへコピーします。
\r
262 * @param i_copy_from
\r
264 * この行列のサイズは、thisと同じでなければなりません。
\r
266 public void copyFrom(NyARMat i_copy_from) throws NyARException
\r
269 if (this.row != i_copy_from.row || this.clm != i_copy_from.clm) {
\r
270 throw new NyARException();
\r
273 for (int r = this.row - 1; r >= 0; r--) {
\r
274 for (int c = this.clm - 1; c >= 0; c--) {
\r
275 this._m[r][c] = i_copy_from._m[r][c];
\r
281 * 返却値の有効期間に注意してください。
\r
282 * この値の有効時間は、次にこのこのインスタンスの関数を実行するまでの間です。
\r
286 public double[][] getArray()
\r
293 * ARToolKitのarMatrixTrans関数と同等な関数です。sourceの転置行列をdestに得ます。
\r
294 * この関数は未チェックの為、実行すると例外が発生します。
\r
300 public static void matrixTrans(NyARMat dest, NyARMat source) throws NyARException
\r
302 if (dest.row != source.clm || dest.clm != source.row) {
\r
303 throw new NyARException();
\r
305 NyARException.trap("未チェックのパス");
\r
307 for (int r = 0; r < dest.row; r++) {
\r
308 for (int c = 0; c < dest.clm; c++) {
\r
309 dest._m[r][c] = source._m[c][r];
\r
315 * ARToolKitの、arMatrixUnit関数と同等な関数です。unitを単位行列に初期化します。
\r
316 * この関数は未チェックの為、実行すると例外が発生します。
\r
320 public static void matrixUnit(NyARMat unit) throws NyARException
\r
322 if (unit.row != unit.clm) {
\r
323 throw new NyARException();
\r
325 NyARException.trap("未チェックのパス");
\r
327 for (int r = 0; r < unit.getRow(); r++) {
\r
328 for (int c = 0; c < unit.getClm(); c++) {
\r
330 unit._m[r][c] = 1.0;
\r
332 unit._m[r][c] = 0.0;
\r
339 * i_sourceの内容を、thisへコピーします。
\r
343 public void matrixDup(NyARMat i_source) throws NyARException
\r
345 // 自身の配列サイズを相手のそれより大きいことを保障する。
\r
346 this.realloc(i_source.row, i_source.clm);
\r
349 double[][] src_m, dest_m;
\r
350 src_m = i_source._m;
\r
353 for (r = this.row - 1; r >= 0; r--) {
\r
354 for (c = this.clm - 1; c >= 0; c--) {
\r
355 dest_m[r][c] = src_m[r][c];
\r
363 * @throws NyARException
\r
365 public NyARMat matrixAllocDup() throws NyARException
\r
367 NyARMat result = new NyARMat(this.row, this.clm);
\r
370 double[][] dest_m, src_m;
\r
371 dest_m = result._m;
\r
374 for (r = this.row - 1; r >= 0; r--) {
\r
375 for (c = this.clm - 1; c >= 0; c--) {
\r
376 dest_m[r][c] = src_m[r][c];
\r
383 private static final double PCA_EPS = 1e-6; // #define EPS 1e-6
\r
385 private static final int PCA_MAX_ITER = 100; // #define MAX_ITER 100
\r
387 private static final double PCA_VZERO = 1e-16; // #define VZERO 1e-16
\r
390 * ARToolKitのEX関数と同等な関数です。
\r
394 * @throws NyARException
\r
396 private void PCA_EX(NyARVec mean) throws NyARException
\r
402 double[][] lm = this._m;
\r
404 if (lrow <= 0 || lclm <= 0) {
\r
405 throw new NyARException();
\r
407 if (mean.getClm() != lclm) {
\r
408 throw new NyARException();
\r
410 // double[] mean_array=mean.getArray();
\r
411 // mean.zeroClear();
\r
412 final double[] mean_array = mean.getArray();
\r
415 for (i2 = 0; i2 < lclm; i2++) {
\r
417 for (i = 0; i < lrow; i++) {
\r
418 // *(v++) += *(m++);
\r
421 mean_array[i2] = w / lrow;// mean->v[i] /= row;
\r
426 * ARToolKitのCENTER関数と同等な関数です。
\r
433 private static void PCA_CENTER(NyARMat inout, NyARVec mean)throws NyARException
\r
440 if (mean.getClm() != clm) {
\r
441 throw new NyARException();
\r
443 double[][] im = inout._m;
\r
446 v = mean.getArray();
\r
447 // 特にパフォーマンスが劣化するclm=1と2ときだけ、別パスで処理します。
\r
451 for (int i = 0; i < row; i++) {
\r
458 for (int i = 0; i < row; i++) {
\r
465 for (int i = 0; i < row; i++) {
\r
467 for (int j = 0; j < clm; j++) {
\r
468 // *(m++) -= *(v++);
\r
478 * ARToolKitのx_by_xtと同等な関数です。
\r
480 * この関数は未チェックの為、使用すると例外が発生します。
\r
485 * @throws NyARException
\r
487 private static void PCA_x_by_xt(NyARMat input, NyARMat output) throws NyARException
\r
489 NyARException.trap("動作未チェック/配列化未チェック");
\r
494 NyARException.trap("未チェックのパス");
\r
497 NyARException.trap("未チェックのパス");
\r
498 if (output.row != row || output.clm != row) {
\r
499 throw new NyARException();
\r
502 // out = output.getArray();
\r
503 for (int i = 0; i < row; i++) {
\r
504 for (int j = 0; j < row; j++) {
\r
506 NyARException.trap("未チェックのパス");
\r
507 output._m[i][j] = output._m[j][i];// *out =
\r
508 // output->m[j*row+i];
\r
510 NyARException.trap("未チェックのパス");
\r
511 in1 = input._m[i];// input.getRowArray(i);//in1 = &(input->m[clm*i]);
\r
512 in2 = input._m[j];// input.getRowArray(j);//in2 = &(input->m[clm*j]);
\r
513 output._m[i][j] = 0;// *out = 0.0;
\r
514 for (int k = 0; k < clm; k++) {
\r
515 output._m[i][j] += (in1[k] * in2[k]);// *out += *(in1++)
\r
525 * ARToolKitのxt_by_x関数と同等な関数です。
\r
531 * @throws NyARException
\r
533 private static void PCA_xt_by_x(NyARMat input, NyARMat i_output) throws NyARException
\r
540 if (i_output.row != clm || i_output.clm != clm) {
\r
541 throw new NyARException();
\r
545 double[][] out_m = i_output._m;
\r
547 for (int i = 0; i < clm; i++) {
\r
548 for (j = 0; j < clm; j++) {
\r
550 out_m[i][j] = out_m[j][i];// *out = output->m[j*clm+i];
\r
552 w = 0.0;// *out = 0.0;
\r
553 for (k = 0; k < row; k++) {
\r
554 in_ = input._m[k];// in=input.getRowArray(k);
\r
555 w += (in_[i] * in_[j]);// *out += *in1 * *in2;
\r
563 private final NyARVec wk_PCA_QRM_ev = new NyARVec(1);
\r
566 * ARToolKitのQRM関数と同等な関数です。
\r
570 * @throws NyARException
\r
572 private void PCA_QRM(NyARVec dv) throws NyARException
\r
574 double w, t, s, x, y, c;
\r
576 double[] dv_array = dv.getArray();
\r
579 if (dim != this.clm || dim < 2) {
\r
580 throw new NyARException();
\r
582 if (dv.getClm() != dim) {
\r
583 throw new NyARException();
\r
586 NyARVec ev = this.wk_PCA_QRM_ev;
\r
588 double[] ev_array = ev.getArray();
\r
590 throw new NyARException();
\r
592 final double[][] L_m = this._m;
\r
593 this.vecTridiagonalize(dv, ev, 1);
\r
595 ev_array[0] = 0.0;// ev->v[0] = 0.0;
\r
596 for (int h = dim - 1; h > 0; h--) {
\r
598 while (j > 0&& Math.abs(ev_array[j]) > PCA_EPS* (Math.abs(dv_array[j - 1]) + Math.abs(dv_array[j]))) {// while(j>0 && fabs(ev->v[j]) >EPS*(fabs(dv->v[j-1])+fabs(dv->v[j])))
\r
608 if (iter > PCA_MAX_ITER) {
\r
611 w = (dv_array[h - 1] - dv_array[h]) / 2;// w = (dv->v[h-1] -dv->v[h]) / 2;//ここ?
\r
612 t = ev_array[h] * ev_array[h];// t = ev->v[h] * ev->v[h];
\r
613 s = Math.sqrt(w * w + t);
\r
617 x = dv_array[j] - dv_array[h] + t / (w + s);// x = dv->v[j] -dv->v[h] +t/(w+s);
\r
618 y = ev_array[j + 1];// y = ev->v[j+1];
\r
619 for (int k = j; k < h; k++) {
\r
620 if (Math.abs(x) >= Math.abs(y)) {
\r
621 if (Math.abs(x) > PCA_VZERO) {
\r
623 c = 1 / Math.sqrt(t * t + 1);
\r
631 s = 1.0 / Math.sqrt(t * t + 1);
\r
634 w = dv_array[k] - dv_array[k + 1];// w = dv->v[k] -dv->v[k+1];
\r
635 t = (w * s + 2 * c * ev_array[k + 1]) * s;// t = (w * s +2 * c *ev->v[k+1]) *s;
\r
636 dv_array[k] -= t;// dv->v[k] -= t;
\r
637 dv_array[k + 1] += t;// dv->v[k+1] += t;
\r
639 NyARException.trap("未チェックパス");
\r
641 ev_array[k] = c * ev_array[k] - s * y;// ev->v[k]= c *ev->v[k]- s * y;
\r
644 ev_array[k + 1] += s * (c * w - 2 * s * ev_array[k + 1]);// ev->v[k+1]+= s * (c* w- 2* s *ev->v[k+1]);
\r
646 for (int i = 0; i < dim; i++) {
\r
647 x = L_m[k][i];// x = a->m[k*dim+i];
\r
648 y = L_m[k + 1][i];// y = a->m[(k+1)*dim+i];
\r
649 L_m[k][i] = c * x - s * y;// a->m[k*dim+i] = c * x - s* y;
\r
650 L_m[k + 1][i] = s * x + c * y;// a->m[(k+1)*dim+i] = s* x + c * y;
\r
653 NyARException.trap("未チェックパス");
\r
655 x = ev_array[k + 1];// x = ev->v[k+1];
\r
656 y = -s * ev_array[k + 2];// y = -s * ev->v[k+2];
\r
657 ev_array[k + 2] *= c;// ev->v[k+2] *= c;
\r
661 } while (Math.abs(ev_array[h]) > PCA_EPS
\r
662 * (Math.abs(dv_array[h - 1]) + Math.abs(dv_array[h])));
\r
664 for (int k = 0; k < dim - 1; k++) {
\r
666 t = dv_array[h];// t = dv->v[h];
\r
667 for (int i = k + 1; i < dim; i++) {
\r
668 if (dv_array[i] > t) {// if( dv->v[i] > t ) {
\r
670 t = dv_array[h];// t = dv->v[h];
\r
673 dv_array[h] = dv_array[k];// dv->v[h] = dv->v[k];
\r
674 dv_array[k] = t;// dv->v[k] = t;
\r
675 this.flipRow(h, k);
\r
680 * 行列のうち、指定した2列の値を入れ替えます。
\r
686 private void flipRow(int i_row_1, int i_row_2)
\r
690 double[] r1 = this._m[i_row_1], r2 = this._m[i_row_2];
\r
692 for (i = clm - 1; i >= 0; i--) {
\r
700 * ARToolKitのEV_create関数と同等な関数です。
\r
710 * @throws NyARException
\r
712 private static void PCA_EV_create(NyARMat input, NyARMat u, NyARMat output,NyARVec ev) throws NyARException
\r
714 NyARException.trap("未チェックのパス");
\r
716 row = input.row;// row = input->row;
\r
717 clm = input.clm;// clm = input->clm;
\r
718 if (row <= 0 || clm <= 0) {
\r
719 throw new NyARException();
\r
721 if (u.row != row || u.clm != row) {// if( u->row != row || u->clm !=
\r
723 throw new NyARException();
\r
725 if (output.row != row || output.clm != clm) {// if( output->row !=
\r
726 // row || output->clm !=
\r
728 throw new NyARException();
\r
730 if (ev.getClm() != row) {// if( ev->clm != row ){
\r
731 throw new NyARException();
\r
734 double[] m1, ev_array;
\r
737 NyARException.trap("未チェックのパス");
\r
738 m = output._m;// m = output->m;
\r
741 ev_array = ev.getArray();
\r
742 for (i = 0; i < row; i++) {
\r
743 NyARException.trap("未チェックのパス");
\r
744 if (ev_array[i] < PCA_VZERO) {// if( ev->v[i] < VZERO ){
\r
747 NyARException.trap("未チェックのパス");
\r
748 work = 1 / Math.sqrt(Math.abs(ev_array[i]));// work = 1 /
\r
749 // sqrt(fabs(ev->v[i]));
\r
750 for (int j = 0; j < clm; j++) {
\r
752 m1 = u._m[i];// m1 = &(u->m[i*row]);
\r
753 // m2=input.getPointer(j);//m2 = &(input->m[j]);
\r
754 for (int k = 0; k < row; k++) {
\r
755 sum += m1[k] + in_[k][j];// sum += *m1 * *m2;
\r
756 // m1.incPtr(); //m1++;
\r
757 // m2.addPtr(clm);//m2 += clm;
\r
759 m1[j] = sum * work;// *(m++) = sum * work;
\r
760 // {//*(m++) = sum * work;
\r
761 // m.set(sum * work);
\r
765 for (; i < row; i++) {
\r
766 NyARException.trap("未チェックのパス");
\r
767 ev_array[i] = 0.0;// ev->v[i] = 0.0;
\r
768 for (int j = 0; j < clm; j++) {
\r
770 // m.set(0.0);//*(m++) = 0.0;
\r
776 private NyARMat wk_PCA_PCA_u = null;
\r
779 * ARToolKitのPCA関数と同等な関数です。
\r
785 * @throws NyARException
\r
787 private void PCA_PCA(NyARMat o_output, NyARVec o_ev) throws NyARException
\r
790 int l_row, l_clm, min;
\r
791 double[] ev_array = o_ev.getArray();
\r
793 l_row = this.row;// row = input->row;
\r
794 l_clm = this.clm;// clm = input->clm;
\r
795 min = (l_clm < l_row) ? l_clm : l_row;
\r
796 if (l_row < 2 || l_clm < 2) {
\r
797 throw new NyARException();
\r
799 if (o_output.clm != this.clm) {// if( output->clm != input->clm ){
\r
800 throw new NyARException();
\r
802 if (o_output.row != min) {// if( output->row != min ){
\r
803 throw new NyARException();
\r
805 if (o_ev.getClm() != min) {// if( ev->clm != min ){
\r
806 throw new NyARException();
\r
809 NyARMat u;// u =new NyARMat( min, min );
\r
810 if (this.wk_PCA_PCA_u == null) {
\r
811 u = new NyARMat(min, min);
\r
812 this.wk_PCA_PCA_u = u;
\r
814 u = this.wk_PCA_PCA_u;
\r
815 u.realloc(min, min);
\r
818 if (l_row < l_clm) {
\r
819 NyARException.trap("未チェックのパス");
\r
820 PCA_x_by_xt(this, u);// if(x_by_xt( input, u ) < 0 ) {
\r
822 PCA_xt_by_x(this, u);// if(xt_by_x( input, u ) < 0 ) {
\r
827 if (l_row < l_clm) {
\r
828 NyARException.trap("未チェックのパス");
\r
829 PCA_EV_create(this, u, o_output, o_ev);
\r
831 m1 = u._m;// m1 = u->m;
\r
832 m2 = o_output._m;// m2 = output->m;
\r
834 for (i = 0; i < min; i++) {
\r
835 if (ev_array[i] < PCA_VZERO) {// if( ev->v[i] < VZERO ){
\r
838 for (int j = 0; j < min; j++) {
\r
839 m2[i][j] = m1[i][j];// *(m2++) = *(m1++);
\r
842 for (; i < min; i++) {// for( ; i < min; i++){
\r
843 // コードを見た限りあってそうだからコメントアウト(2008/03/26)NyARException.trap("未チェックのパス");
\r
844 ev_array[i] = 0.0;// ev->v[i] = 0.0;
\r
845 for (int j = 0; j < min; j++) {
\r
846 m2[i][j] = 0.0;// *(m2++) = 0.0;
\r
852 * 現在の行列に主成分分析を実行して、結果をthisと引数へ格納します。
\r
860 * @throws NyARException
\r
862 public void pca(NyARMat o_evec, NyARVec o_ev, NyARVec o_mean)throws NyARException
\r
864 final double l_row = this.row;// row = input->row;
\r
865 final double l_clm = this.clm;// clm = input->clm;
\r
866 final double check=(l_row < l_clm) ? l_row : l_clm;
\r
868 assert l_row >= 2 || l_clm >= 2;
\r
869 assert o_evec.clm == l_clm && o_evec.row == check;
\r
870 assert o_ev.getClm() == check;
\r
871 assert o_mean.getClm() == l_clm;
\r
873 final double srow = Math.sqrt((double) l_row);
\r
876 PCA_CENTER(this, o_mean);
\r
880 for (i = 0; i < l_row; i++) {
\r
881 for (j = 0; j < l_clm; j++) {
\r
882 this._m[i][j] /= srow;// work->m[i] /= srow;
\r
886 PCA_PCA(o_evec, o_ev);
\r
889 double[] ev_array = o_ev.getArray();
\r
890 int ev_clm = o_ev.getClm();
\r
892 for (i = 0; i < ev_clm; i++) {// for(int i = 0; i < ev->clm; i++ ){
\r
893 sum += ev_array[i];// sum += ev->v[i];
\r
896 for (i = 0; i < ev_clm; i++) {// for(int i = 0; i < ev->clm; i++ ){
\r
897 ev_array[i] /= sum;// ev->v[i] /= sum;
\r
904 private final NyARVec wk_vecTridiagonalize_vec = new NyARVec(0);
\r
906 private final NyARVec wk_vecTridiagonalize_vec2 = new NyARVec(0);
\r
909 * ARToolKitの、arVecTridiagonalize関数と同等な関数です。
\r
916 * 演算開始列(よくわからないけどarVecTridiagonalizeの呼び出し元でなんかしてる)
\r
917 * @throws NyARException
\r
919 private void vecTridiagonalize(NyARVec d, NyARVec e, int i_e_start)throws NyARException
\r
921 NyARVec vec = wk_vecTridiagonalize_vec;
\r
922 // double[][] a_array=a.getArray();
\r
926 if (this.clm != this.row) {// if(a.getClm()!=a.getRow()){
\r
927 throw new NyARException();
\r
929 if (this.clm != d.getClm()) {// if(a.getClm() != d.clm){
\r
930 throw new NyARException();
\r
932 if (this.clm != e.getClm()) {// if(a.getClm() != e.clm){
\r
933 throw new NyARException();
\r
935 dim = this.getClm();
\r
937 double[] d_vec, e_vec;
\r
938 d_vec = d.getArray();
\r
939 e_vec = e.getArray();
\r
942 for (int k = 0; k < dim - 2; k++) {
\r
944 a_vec_k = this._m[k];
\r
945 vec.setNewArray(a_vec_k, clm);// vec=this.getRowVec(k);//double[]
\r
946 // vec_array=vec.getArray();
\r
947 NyARException.trap("未チェックパス");
\r
948 d_vec[k] = a_vec_k[k];// d.v[k]=vec.v[k];//d.set(k,v.get(k));
\r
949 // //d->v[k] = v[k];
\r
951 // wv1.clm = dim-k-1;
\r
952 // wv1.v = &(v[k+1]);
\r
953 NyARException.trap("未チェックパス");
\r
954 e_vec[k + i_e_start] = vec.vecHousehold(k + 1);// e.v[k+i_e_start]=vec.vecHousehold(k+1);//e->v[k]= arVecHousehold(&wv1);
\r
955 if (e_vec[k + i_e_start] == 0.0) {// if(e.v[k+i_e_start]== 0.0){//if(e.v[k+i_e_start]== 0.0){
\r
959 for (int i = k + 1; i < dim; i++) {
\r
961 for (int j = k + 1; j < i; j++) {
\r
962 NyARException.trap("未チェックのパス");
\r
963 s += this._m[j][i] * a_vec_k[j];// s += a_array[j][i] *vec.v[j];//s +=a.get(j*dim+i) *v.get(j);//s +=a->m[j*dim+i] * v[j];
\r
965 for (int j = i; j < dim; j++) {
\r
966 NyARException.trap("未チェックのパス");
\r
967 s += this._m[i][j] * a_vec_k[j];// s += a_array[i][j] *vec.v[j];//s +=a.get(i*dim+j) *v.get(j);//s +=a->m[i*dim+j] * v[j];
\r
969 NyARException.trap("未チェックのパス");
\r
970 d_vec[i] = s;// d.v[i]=s;//d->v[i] = s;
\r
973 // wv1.clm = wv2.clm = dim-k-1;
\r
974 // wv1.v = &(v[k+1]);
\r
975 // wv2.v = &(d->v[k+1]);
\r
976 a_vec_k = this._m[k];
\r
977 vec.setNewArray(a_vec_k, clm);// vec=this.getRowVec(k);
\r
978 // vec_array=vec.getArray();
\r
979 NyARException.trap("未チェックパス");
\r
980 t = vec.vecInnerproduct(d, k + 1) / 2;
\r
981 for (int i = dim - 1; i > k; i--) {
\r
982 NyARException.trap("未チェックパス");
\r
983 p = a_vec_k[i];// p = v.get(i);//p = v[i];
\r
985 q = d_vec[i];// d.v[i]-=t*p;q=d.v[i];//q = d->v[i] -= t*p;
\r
986 for (int j = i; j < dim; j++) {
\r
987 NyARException.trap("未チェックパス");
\r
988 this._m[i][j] -= p * (d_vec[j] + q * a_vec_k[j]);// a.m[i][j]-=p*(d.v[j] +q*vec.v[j]);//a->m[i*dim+j] -=p*(d->v[j]) + q*v[j];
\r
994 d_vec[dim - 2] = this._m[dim - 2][dim - 2];// d.v[dim-2]=a.m[dim-2][dim-2];//d->v[dim-2]=a->m[(dim-2)*dim+(dim-2)];
\r
995 e_vec[dim - 2 + i_e_start] = this._m[dim - 2][dim - 1];// e.v[dim-2+i_e_start]=a.m[dim-2][dim-1];//e->v[dim-2] = a->m[(dim-2)*dim+(dim-1)];
\r
999 d_vec[dim - 1] = this._m[dim - 1][dim - 1];// d.v[dim-1]=a_array[dim-1][dim-1];//d->v[dim-1] =a->m[(dim-1)*dim+(dim-1)];
\r
1001 NyARVec vec2 = this.wk_vecTridiagonalize_vec2;
\r
1002 for (int k = dim - 1; k >= 0; k--) {
\r
1003 a_vec_k = this._m[k];
\r
1004 vec.setNewArray(a_vec_k, clm);// vec=this.getRowVec(k);//v =a.getPointer(k*dim);//v = &(a->m[k*dim]);
\r
1005 if (k < dim - 2) {
\r
1006 for (int i = k + 1; i < dim; i++) {
\r
1007 // wv1.clm = wv2.clm = dim-k-1;
\r
1008 // wv1.v = &(v[k+1]);
\r
1009 // wv2.v = &(a->m[i*dim+k+1]);
\r
1010 vec2.setNewArray(this._m[i], clm);// vec2=this.getRowVec(i);
\r
1012 t = vec.vecInnerproduct(vec2, k + 1);
\r
1013 for (int j = k + 1; j < dim; j++) {
\r
1014 NyARException.trap("未チェックパス");
\r
1015 this._m[i][j] -= t * a_vec_k[j];// a_array[i][j]-=t*vec.v[j];//a.subValue(i*dim+j,t*v.get(j));//a->m[i*dim+j]-= t * v[j];
\r
1019 for (int i = 0; i < dim; i++) {
\r
1020 a_vec_k[i] = 0.0;// v.set(i,0.0);//v[i] = 0.0;
\r
1022 a_vec_k[k] = 1;// v.set(k,1);//v[k] = 1;
\r