home *** CD-ROM | disk | FTP | other *** search
- >elt[idx1].nxt_row = tmp_e->nxt_row;
- r1->elt[idx1].nxt_idx = tmp_e->nxt_idx;
- tmp_e->nxt_row = i1;
- tmp_e->nxt_idx = idx1;
- }
- }
- else if ( r1->elt[idx1].col != j1 )
- error(E_INTERN,"bkp_swap_elt");
- if ( idx2 < 0 )
- {
- idx2 = r2->len;
- if ( idx2 >= r2->maxlen )
- { tracecatch(sprow_xpd(r2,2*r2->maxlen+1,TYPE_SPMAT),
- "bkp_swap_elt"); }
-
- r2->len = idx2+1;
- r2->elt[idx2].col = j2;
- r2->elt[idx2].val = 0.0;
- /* now patch up column access path */
- tmp_row = -1; tmp_idx = j2;
- chase_col(A,j2,&tmp_row,&tmp_idx,i2-1);
- if ( tmp_row < 0 )
- {
- r2->elt[idx2].nxt_row = A->start_row[j2];
- r2->elt[idx2].nxt_idx = A->start_idx[j2];
- A->start_row[j2] = i2;
- A->start_idx[j2] = idx2;
- }
- else
- {
- row_elt *tmp_e;
-
- tmp_e = &(A->row[tmp_row].elt[tmp_idx]);
- r2->elt[idx2].nxt_row = tmp_e->nxt_row;
- r2->elt[idx2].nxt_idx = tmp_e->nxt_idx;
- tmp_e->nxt_row = i2;
- tmp_e->nxt_idx = idx2;
- }
- }
- else if ( r2->elt[idx2].col != j2 )
- error(E_INTERN,"bkp_swap_elt");
-
- e1 = &(r1->elt[idx1]); e2 = &(r2->elt[idx2]);
-
- tmp = e1->val;
- e1->val = e2->val;
- e2->val = tmp;
-
- return A;
- }
-
- /* bkp_bump_col -- bumps row and idx to next entry in column j */
- row_elt *bkp_bump_col(A, j, row, idx)
- SPMAT *A;
- int j, *row, *idx;
- {
- SPROW *r;
- row_elt *e;
-
- if ( *row < 0 )
- {
- *row = A->start_row[j];
- *idx = A->start_idx[j];
- }
- else
- {
- r = &(A->row[*row]);
- e = &(r->elt[*idx]);
- if ( e->col != j )
- error(E_INTERN,"bkp_bump_col");
- *row = e->nxt_row;
- *idx = e->nxt_idx;
- }
- if ( *row < 0 )
- return (row_elt *)NULL;
- else
- return &(A->row[*row].elt[*idx]);
- }
-
- /* bkp_interchange -- swap rows/cols i and j (symmetric pivot)
- -- uses just the upper triangular part */
- SPMAT *bkp_interchange(A, i1, i2)
- SPMAT *A;
- int i1, i2;
- {
- int tmp_row, tmp_idx;
- int row1, row2, idx1, idx2, tmp_row1, tmp_idx1, tmp_row2, tmp_idx2;
- SPROW *r1, *r2;
- row_elt *e1, *e2;
- IVEC *done_list = IVNULL;
-
- if ( ! A )
- error(E_NULL,"bkp_interchange");
- if ( i1 < 0 || i1 >= A->n || i2 < 0 || i2 >= A->n )
- error(E_BOUNDS,"bkp_interchange");
- if ( A->m != A->n )
- error(E_SQUARE,"bkp_interchange");
-
- if ( i1 == i2 )
- return A;
- if ( i1 > i2 )
- { tmp_idx = i1; i1 = i2; i2 = tmp_idx; }
-
- done_list = iv_resize(done_list,A->n);
- for ( tmp_idx = 0; tmp_idx < A->n; tmp_idx++ )
- done_list->ive[tmp_idx] = FALSE;
- row1 = -1; idx1 = i1;
- row2 = -1; idx2 = i2;
- e1 = bkp_bump_col(A,i1,&row1,&idx1);
- e2 = bkp_bump_col(A,i2,&row2,&idx2);
-
- while ( (row1 >= 0 && row1 < i1) || (row2 >= 0 && row2 < i1) )
- /* Note: "row2 < i1" not "row2 < i2" as we must stop before the
- "knee bend" */
- {
- if ( row1 >= 0 && row1 < i1 && ( row1 < row2 || row2 < 0 ) )
- {
- tmp_row1 = row1; tmp_idx1 = idx1;
- e1 = bkp_bump_col(A,i1,&tmp_row1,&tmp_idx1);
- if ( ! done_list->ive[row1] )
- {
- if ( row1 == row2 )
- bkp_swap_elt(A,row1,i1,idx1,row1,i2,idx2);
- else
- bkp_swap_elt(A,row1,i1,idx1,row1,i2,-1);
- done_list->ive[row1] = TRUE;
- }
- row1 = tmp_row1; idx1 = tmp_idx1;
- }
- else if ( row2 >= 0 && row2 < i1 && ( row2 < row1 || row1 < 0 ) )
- {
- tmp_row2 = row2; tmp_idx2 = idx2;
- e2 = bkp_bump_col(A,i2,&tmp_row2,&tmp_idx2);
- if ( ! done_list->ive[row2] )
- {
- if ( row1 == row2 )
- bkp_swap_elt(A,row2,i1,idx1,row2,i2,idx2);
- else
- bkp_swap_elt(A,row2,i1,-1,row2,i2,idx2);
- done_list->ive[row2] = TRUE;
- }
- row2 = tmp_row2; idx2 = tmp_idx2;
- }
- else if ( row1 == row2 )
- {
- tmp_row1 = row1; tmp_idx1 = idx1;
- e1 = bkp_bump_col(A,i1,&tmp_row1,&tmp_idx1);
- tmp_row2 = row2; tmp_idx2 = idx2;
- e2 = bkp_bump_col(A,i2,&tmp_row2,&tmp_idx2);
- if ( ! done_list->ive[row1] )
- {
- bkp_swap_elt(A,row1,i1,idx1,row2,i2,idx2);
- done_list->ive[row1] = TRUE;
- }
- row1 = tmp_row1; idx1 = tmp_idx1;
- row2 = tmp_row2; idx2 = tmp_idx2;
- }
- }
-
- /* ensure we are **past** the first knee */
- while ( row2 >= 0 && row2 <= i1 )
- e2 = bkp_bump_col(A,i2,&row2,&idx2);
-
- /* at/after 1st "knee bend" */
- r1 = &(A->row[i1]);
- idx1 = 0;
- e1 = &(r1->elt[idx1]);
- while ( row2 >= 0 && row2 < i2 )
- {
- /* used for update of e2 at end of loop */
- tmp_row = row2; tmp_idx = idx2;
- if ( ! done_list->ive[row2] )
- {
- r2 = &(A->row[row2]);
- bkp_bump_col(A,i2,&tmp_row,&tmp_idx);
- done_list->ive[row2] = TRUE;
- tmp_idx1 = unord_get_idx(r1,row2);
- tracecatch(bkp_swap_elt(A,row2,i2,idx2,i1,row2,tmp_idx1),
- "bkp_interchange");
- }
-
- /* update e1 and e2 */
- row2 = tmp_row; idx2 = tmp_idx;
- e2 = ( row2 >= 0 ) ? &(A->row[row2].elt[idx2]) : (row_elt *)NULL;
- }
-
- idx1 = 0;
- e1 = r1->elt;
- while ( idx1 < r1->len )
- {
- if ( e1->col >= i2 || e1->col <= i1 )
- {
- idx1++;
- e1++;
- continue;
- }
- if ( ! done_list->ive[e1->col] )
- {
- tmp_idx2 = unord_get_idx(&(A->row[e1->col]),i2);
- tracecatch(bkp_swap_elt(A,i1,e1->col,idx1,e1->col,i2,tmp_idx2),
- "bkp_interchange");
- done_list->ive[e1->col] = TRUE;
- }
- idx1++;
- e1++;
- }
-
- /* at/after 2nd "knee bend" */
- idx1 = 0;
- e1 = &(r1->elt[idx1]);
- r2 = &(A->row[i2]);
- idx2 = 0;
- e2 = &(r2->elt[idx2]);
- while ( idx1 < r1->len )
- {
- if ( e1->col <= i2 )
- {
- idx1++; e1++;
- continue;
- }
- if ( ! done_list->ive[e1->col] )
- {
- tmp_idx2 = unord_get_idx(r2,e1->col);
- tracecatch(bkp_swap_elt(A,i1,e1->col,idx1,i2,e1->col,tmp_idx2),
- "bkp_interchange");
- done_list->ive[e1->col] = TRUE;
- }
- idx1++; e1++;
- }
-
- idx2 = 0; e2 = r2->elt;
- while ( idx2 < r2->len )
- {
- if ( e2->col <= i2 )
- {
- idx2++; e2++;
- continue;
- }
- if ( ! done_list->ive[e2->col] )
- {
- tmp_idx1 = unord_get_idx(r1,e2->col);
- traceca
-
- #ifndef ANSI_C
- static void hhldr3(x,y,z,nu1,beta,newval)
- double x, y, z;
- Real *nu1, *beta, *newval;
- #else
- static void hhldr3(double x, double y, double z,
- Real *nu1, Real *beta, Real *newval)
- #endif
- {
- Real alpha;
-
- if ( x >= 0.0 )
- alpha = sqrt(x*x+y*y+z*z);
- else
- alpha = -sqrt(x*x+y*y+z*z);
- *nu1 = x + alpha;
- *beta = 1.0/(alpha*(*nu1));
- *newval = alpha;
- }
-
- #ifndef ANSI_C
- static void hhldr3cols(A,k,j0,beta,nu1,nu2,nu3)
- MAT *A;
- int k, j0;
- double beta, nu1, nu2, nu3;
- #else
- static void hhldr3cols(MAT *A, int k, int j0, double beta,
- double nu1, double nu2, double nu3)
- #endif
- {
- Real **A_me, ip, prod;
- int j, n;
-
- if ( k < 0 || k+3 > A->m || j0 < 0 )
- error(E_BOUNDS,"hhldr3cols");
- A_me = A->me; n = A->n;
-
- /* printf("hhldr3cols:(l.%d) j0 = %d, k = %d, A at 0x%lx, m = %d, n = %d\n",
- __LINE__, j0, k, (long)A, A->m, A->n); */
- /* printf("hhldr3cols: A (dumped) =\n"); m_dump(stdout,A); */
-
- for ( j = j0; j < n; j++ )
- {
- /*****
- ip = nu1*A_me[k][j] + nu2*A_me[k+1][j] + nu3*A_me[k+2][j];
- prod = ip*beta;
- A_me[k][j] -= prod*nu1;
- A_me[k+1][j] -= prod*nu2;
- A_me[k+2][j] -= prod*nu3;
- *****/
- /* printf("hhldr3cols: j = %d\n", j); */
-
- ip = nu1*m_entry(A,k,j)+nu2*m_entry(A,k+1,j)+nu3*m_entry(A,k+2,j);
- prod = ip*beta;
- /*****
- m_set_val(A,k ,j,m_entry(A,k ,j) - prod*nu1);
- m_set_val(A,k+1,j,m_entry(A,k+1,j) - prod*nu2);
- m_set_val(A,k+2,j,m_entry(A,k+2,j) - prod*nu3);
- *****/
- m_add_val(A,k ,j,-prod*nu1);
- m_add_val(A,k+1,j,-prod*nu2);
- m_add_val(A,k+2,j,-prod*nu3);
-
- }
- /* printf("hhldr3cols:(l.%d) j0 = %d, k = %d, m = %d, n = %d\n",
- __LINE__, j0, k, A->m, A->n); */
- /* putc('\n',stdout); */
- }
-
- #ifndef ANSI_C
- static void hhldr3rows(A,k,i0,beta,nu1,nu2,nu3)
- MAT *A;
- int k, i0;
- double beta, nu1, nu2, nu3;
- #else
- static void hhldr3rows(MAT *A, int k, int i0, double beta,
- double nu1, double nu2, double nu3)
- #endif
- {
- Real **A_me, ip, prod;
- int i, m;
-
- /* printf("hhldr3rows:(l.%d) A at 0x%lx\n", __LINE__, (long)A); */
- /* printf("hhldr3rows: k = %d\n", k); */
- if ( k < 0 || k+3 > A->n )
- error(E_BOUNDS,"hhldr3rows");
- A_me = A->me; m = A->m;
- i0 = min(i0,m-1);
-
- for ( i = 0; i <= i0; i++ )
- {
- /****
- ip = nu1*A_me[i][k] + nu2*A_me[i][k+1] + nu3*A_me[i][k+2];
- prod = ip*beta;
- A_me[i][k] -= prod*nu1;
- A_me[i][k+1] -= prod*nu2;
- A_me[i][k+2] -= prod*nu3