MAT *bifactor(MAT *A, MAT *U, MAT *V) #endif { int k; STATIC VEC *tmp1=VNULL, *tmp2=VNULL, *w=VNULL; Real beta; if ( ! A ) error(E_NULL,"bifactor"); if ( ( U && ( U->m != U->n ) ) || ( V && ( V->m != V->n ) ) ) error(E_SQUARE,"bifactor"); if ( ( U && U->m != A->m ) || ( V && V->m != A->n ) ) error(E_SIZES,"bifactor"); tmp1 = v_resize(tmp1,A->m); tmp2 = v_resize(tmp2,A->n); w = v_resize(w, max(A->m,A->n)); MEM_STAT_REG(tmp1,TYPE_VEC); MEM_STAT_REG(tmp2,TYPE_VEC); MEM_STAT_REG(w, TYPE_VEC); if ( A->m >= A->n ) for ( k = 0; k < A->n; k++ ) { get_col(A,k,tmp1); hhvec(tmp1,k,&beta,tmp1,&(A->me[k][k])); _hhtrcols(A,k,k+1,tmp1,beta,w); if ( U ) _hhtrcols(U,k,0,tmp1,beta,w); if ( k+1 >= A->n ) continue; get_row(A,k,tmp2); hhvec(tmp2,k+1,&beta,tmp2,&(A->me[k][k+1])); hhtrrows(A,k+1,k+1,tmp2,beta); if ( V ) _hhtrcols(V,k+1,0,tmp2,beta,w); } else for ( k = 0; k < A->m; k++ ) { get_row(A,k,tmp2); hhvec(tmp2,k,&beta,tmp2,&(A->me[k][k])); hhtrrows(A,k+1,k,tmp2,beta); if ( V ) _hhtrcols(V,k,0,tmp2,beta,w); if ( k+1 >= A->m ) continue; get_col(A,k,tmp1); hhvec(tmp1,k+1,&beta,tmp1,&(A->me[k+1][k])); _hhtrcols(A,k+1,k+1,tmp1,beta,w); if ( U ) _hhtrcols(U,k+1,0,tmp1,beta,w); } #ifdef THREADSAFE V_FREE(tmp1); V_FREE(tmp2); #endif return A; }
MAT *Hfactor(MAT *A, VEC *diag, VEC *beta) #endif { STATIC VEC *hh = VNULL, *w = VNULL; int k, limit; if ( ! A || ! diag || ! beta ) error(E_NULL,"Hfactor"); if ( diag->dim < A->m - 1 || beta->dim < A->m - 1 ) error(E_SIZES,"Hfactor"); if ( A->m != A->n ) error(E_SQUARE,"Hfactor"); limit = A->m - 1; hh = v_resize(hh,A->m); w = v_resize(w,A->n); MEM_STAT_REG(hh,TYPE_VEC); MEM_STAT_REG(w, TYPE_VEC); for ( k = 0; k < limit; k++ ) { /* compute the Householder vector hh */ get_col(A,(unsigned int)k,hh); /* printf("the %d'th column = "); v_output(hh); */ hhvec(hh,k+1,&beta->ve[k],hh,&A->me[k+1][k]); /* diag->ve[k] = hh->ve[k+1]; */ v_set_val(diag,k,v_entry(hh,k+1)); /* printf("H/h vector = "); v_output(hh); */ /* printf("from the %d'th entry\n",k+1); */ /* printf("beta = %g\n",beta->ve[k]); */ /* apply Householder operation symmetrically to A */ _hhtrcols(A,k+1,k+1,hh,v_entry(beta,k),w); hhtrrows(A,0 ,k+1,hh,v_entry(beta,k)); /* printf("A = "); m_output(A); */ } #ifdef THREADSAFE V_FREE(hh); V_FREE(w); #endif return (A); }
MAT *Hfactor(MAT *A, VEC *diag, VEC *beta) #endif { char MatrixTempBuffer[ 2000 ]; /*STATIC */VEC *hh = VNULL, *w = VNULL; int k, limit; if ( ! A || ! diag || ! beta ) error(E_NULL,"Hfactor"); if ( diag->dim < A->m - 1 || beta->dim < A->m - 1 ) error(E_SIZES,"Hfactor"); if ( A->m != A->n ) error(E_SQUARE,"Hfactor"); limit = A->m - 1; if( SET_VEC_SIZE( A->m ) < 1000 ) { vec_get( &hh, (void *)MatrixTempBuffer, A->m ); } else { hh = v_get( A->m ); } if( SET_VEC_SIZE( A->n ) < 1000 ) { vec_get( &w, (void *)(MatrixTempBuffer + 1000), A->n ); } else { w = v_get( A->n ); } /*hh = v_resize(hh,A->m); w = v_resize(w,A->n); MEM_STAT_REG(hh,TYPE_VEC); MEM_STAT_REG(w, TYPE_VEC);*/ for ( k = 0; k < limit; k++ ) { /* compute the Householder vector hh */ get_col(A,(unsigned int)k,hh); /* printf("the %d'th column = "); v_output(hh); */ hhvec(hh,k+1,&beta->ve[k],hh,&A->me[k+1][k]); /* diag->ve[k] = hh->ve[k+1]; */ v_set_val(diag,k,v_entry(hh,k+1)); /* printf("H/h vector = "); v_output(hh); */ /* printf("from the %d'th entry\n",k+1); */ /* printf("beta = %g\n",beta->ve[k]); */ /* apply Householder operation symmetrically to A */ _hhtrcols(A,k+1,k+1,hh,v_entry(beta,k),w); hhtrrows(A,0 ,k+1,hh,v_entry(beta,k)); /* printf("A = "); m_output(A); */ } /* #ifdef THREADSAFE V_FREE(hh); V_FREE(w); #endif */ if( hh != (VEC *)(MatrixTempBuffer ) ) // память выделялась, надо освободить V_FREE(hh); if( w != (VEC *)(MatrixTempBuffer + 1000) ) // память выделялась, надо освободить V_FREE(w); return (A); }