home *** CD-ROM | disk | FTP | other *** search
- n,i_max); */
- i_min = i_max + 1;
- continue; /* outer while loop */
- }
-
- /* printf("# i_min = %d, i_max = %d\n",i_min,i_max); */
-
- /* repeatedly perform QR method until matrix splits */
- split = FALSE;
- while ( ! split ) /* inner while loop */
- {
-
- /* find Wilkinson shift */
- d = (a_ve[i_max-1] - a_ve[i_max])/2;
- b_sqr = b_ve[i_max-1]*b_ve[i_max-1];
- mu = a_ve[i_max] - b_sqr/(d + sgn(d)*sqrt(d*d+b_sqr));
- /* printf("# Wilkinson shift = %g\n",mu); */
-
- /* initial Givens' rotation */
- givens(a_ve[i_min]-mu,b_ve[i_min],&c,&s);
- s = -s;
- /* printf("# c = %g, s = %g\n",c,s); */
- if ( fabs(c) < SQRT2 )
- { c2 = c*c; s2 = 1-c2; }
- else
- { s2 = s*s; c2 = 1-s2; }
- cs = c*s;
- ak1 = c2*a_ve[i_min]+s2*a_ve[i_min+1]-2*cs*b_ve[i_min];
- bk1 = cs*(a_ve[i_min]-a_ve[i_min+1]) +
- (c2-s2)*b_ve[i_min];
- ak2 = s2*a_ve[i_min]+c2*a_ve[i_min+1]+2*cs*b_ve[i_min];
- bk2 = ( i_min < i_max-1 ) ? c*b_ve[i_min+1] : 0.0;
- z = ( i_min < i_max-1 ) ? -s*b_ve[i_min+1] : 0.0;
- a_ve[i_min] = ak1;
- a_ve[i_min+1] = ak2;
- b_ve[i_min] = bk1;
- if ( i_min < i_max-1 )
- b_ve[i_min+1] = bk2;
- if ( Q )
- rot_cols(Q,i_min,i_min+1,c,-s,Q);
- /* printf("# z = %g\n",z); */
- /* printf("# a [temp1] =\n"); v_output(a); */
- /* printf("# b [temp1] =\n"); v_output(b); */
-
- for ( i = i_min+1; i < i_max; i++ )
- {
- /* get Givens' rotation for sub-block -- k == i-1 */
- givens(b_ve[i-1],z,&c,&s);
- s = -s;
- /* printf("# c = %g, s = %g\n",c,s); */
-
- /* perform Givens' rotation on sub-block */
- if ( fabs(c) < SQRT2 )
- { c2 = c*c; s2 = 1-c2; }
- else
- { s2 = s*s; c2 = 1-s2; }
- cs = c*s;
- bk = c*b_ve[i-1] - s*z;
- ak1 = c2*a_ve[i]+s2*a_ve[i+1]-2*cs*b_ve[i];
- bk1 = cs*(a_ve[i]-a_ve[i+1]) +
- (c2-s2)*b_ve[i];
- ak2 = s2*a_ve[i]+c2*a_ve[i+1]+2*cs*b_ve[i];
- bk2 = ( i+1 < i_max ) ? c*b_ve[i+1] : 0.0;
- z = ( i+1 < i_max ) ? -s*b_ve[i+1] : 0.0;
- a_ve[i] = ak1; a_ve[i+1] = ak2;
- b_ve[i] = bk1;
- if ( i < i_max-1 )
- b_ve[i+1] = bk2;
- if ( i > i_min )
- b_ve[i-1] = bk;
- if ( Q )
- rot_cols(Q,i,i+1,c,-s,Q);
- /* printf("# a [temp2] =\n"); v_output(a); */
- /* printf("# b [temp2] =\n"); v_output(b); */
- }
-
- /* test to see if matrix should be split */
- for ( i = i_min; i < i_max; i++ )
- if ( fabs(b_ve[i]) < MACHEPS*
- (fabs(a_ve[i])+fabs(a_ve[i+1])) )
- { b_ve[i] = 0.0; split = TRUE; }
-
- /* printf("# a =\n"); v_output(a); */
- /* printf("# b =\n"); v_output(b); */
- }
- }
-
- return a;
- }
-
- /* symmeig -- computes eigenvalues of a dense symmetric matrix
- -- A **must** be symmetric on entry
- -- eigenvalues stored in out
- -- Q contains orthogonal matrix of eigenvectors
- -- returns vector of eigenvalues */
- VEC *symmeig(A,Q,out)
- MAT *A, *Q;
- VEC *out;
- {
- int i;
- static MAT *tmp = MNULL;
- static VEC *b = VNULL, *diag = VNULL, *beta = VNULL;
-
- if ( ! A )
- error(E_NULL,"symmeig");
- if ( A->m != A->n )
- error(E_SQUARE,"symmeig");
- if ( ! out || out->dim != A->m )
- out = v_resize(out,A->m);
-
- tmp = m_copy(A,tmp);
- b = v_resize(b,A->m - 1);
- diag = v_resize(diag,(u_int)A->m);
- beta = v_resize(beta,(u_int)A->m);
- MEM_STAT_REG(tmp,TYPE_MAT);
- MEM_STAT_REG(b,TYPE_VEC);
- MEM_STAT_REG(diag,TYPE_VEC);
- MEM_STAT_REG(beta,TYPE_VEC);
-
- Hfactor(tmp,diag,beta);
- if ( Q )
- makeHQ(tmp,diag,beta,Q);
-
- for ( i = 0; i < A->m - 1; i++ )
- {
- out->ve[i] = tmp->me[i][i];
- b->ve[i] = tmp->me[i][i+1];
- }
- out->ve[i] = tmp->me[i][i];
- trieig(out,b,Q);
-
- return out;
- }
-
- FileDataŵtorture %n Eÿÿÿó8ö ªÜ
- /**************************************************************************
- **
- ** Copyright (C) 1993 - expand row by means of realloc()
- -- type must be TYPE_SPMAT if r is a row of a SPMAT structure,
- otherwise it must be TYPE_SPROW
- -- returns r */
- SPROW *sprow_xpd(r,n,type)
- SPROW *r;
- int n,type;
- {
- int newlen;
-
- if ( ! r ) {
- r = NEW(SPROW);
- if (! r )
- error(E_MEM,"sprow_xpd");
- else if ( mem_info_is_on()) {
- if (type != TYPE_SPMAT && type != TYPE_SPROW)
- warning(WARN_WRONG_TYPE,"sprow_xpd");
- mem_bytes(type,0,sizeof(SPROW));
- if (type == TYPE_SPROW)
- mem_numvar(type,1);
- }
- }
-
- if ( ! r->elt )
- {
- r->elt = NEW_A((unsigned)n,row_elt);
- if ( ! r->elt )
- error(E_MEM,"sprow_xpd");
- else if (mem_info_is_on()) {
- mem_bytes(type,0,n*sizeof(row_elt));
- }
- r->len = 0;
- r->maxlen = n;
- return r;
- }
- if ( n <= r->len )
- newlen = max(2*r->len + 1,MINROWLEN);
- else
- newlen = n;
- if ( newlen <= r->maxlen )
- {
- MEM_ZERO((char *)(&(r->elt[r->len])),
- (newlen-r->len)*sizeof(row_elt));
- r->len = newlen;
- }
- else
- {
- if (mem_info_is_on()) {
- mem_bytes(type,r->maxlen*sizeof(row_elt),
- newlen*sizeof(row_elt));
- }
- r->elt = RENEW(r->elt,newlen,row_elt);
- if ( ! r->elt )
- error(E_MEM,"sprow_xpd");
- r->maxlen = newlen;
- r->len = newlen;
- }
-
- return r;
- }
-
- /* sprow_resize -- resize a SPROW variable by means of realloc()
- -- n is a new size
- -- returns r */
- SPROW *sprow_resize(r,n,type)
- SPROW *r;
- int n,type;
- {
- if (n < 0)
- error(E_NEG,"sprow_resize");
-
- if ( ! r )
- return sprow_get(n);
-
- if (n == r->len)
- return r;
-
- if ( ! r->elt )
- {
- r->elt = NEW_A((unsigned)n,row_elt);
- if ( ! r->elt )
- error(E_MEM,"sprow_resize");
- else if (mem_info_is_on()) {
- mem_bytes(type,0,n*sizeof(row_elt));
- }
- r->maxlen = r->len = n;
- return r;
- }
-
- if ( n <= r->maxlen )
- r->len = n;
- else
- {
- if (mem_info_is_on()) {
- mem_bytes(type,r->maxlen*sizeof(row_elt),
- n*sizeof(row_elt));
- }
- r->elt = RENEW(r->elt,n,row_elt);
- if ( ! r->elt )
- error(E_MEM,"sprow_resize");
- r->maxlen = r->len = n;
- }
-
- return r;
- }
-
-
- /* release a row of a matrix */
- int sprow_free(r)
- SPROW *r;
- {
- if ( ! r )
- return -1;
-
- if (mem_info_is_on()) {
- mem_bytes(TYPE_SPROW,sizeof(SPROW),0);
- mem_numvar(TYPE_SPROW,-1);
- }
-
- if ( r->elt )
- {
- if (mem_info_is_on()) {
- mem_bytes(TYPE_SPROW,r->maxlen*sizeof(row_elt),0);
- }
- free((char *)r->elt);
- }
- free((char *)r);
- return 0;
- }
-
-
- /* sprow_merge -- merges r1 and r2 into r_out
- -- cannot be done in-situ
- -- type must be SPMAT or SPROW depending on
- whether r_out is a row of a SPMAT structure
- or a SPROW variable
- -- returns r_out */
- SPROW *sprow_merge(r1,r2,r_out,type)
- SPROW *r1, *r2, *r_out;
- int type;
- {
- int idx1, idx2, idx_out, len1, len2, len_out;
- row_elt *elt1, *elt2, *elt_out;
-
- if ( ! r1 || ! r2 )
- error(E_NULL,"sprow_merge");
- if ( ! r_out )
- r_out = sprow_get(MINROWLEN);
- if ( r1 == r_out || r2 == r_out )
- error(E_INSITU,"sprow_merge");
-
- /* Initialise */
- len1 = r1->len; len2 = r2->len; len_out = r_out->maxlen;
- idx1 = idx2 = idx_out = 0;
- elt1 = r1->elt; elt2 = r2->elt; elt_out = r_out->elt;
-
- while ( idx1 < len1 || idx2 < len2 )
- {
- if ( idx_out >= len_out )
- { /* r_out is too small */
- r_out->len = idx_out;
- r_out = sprow_xpd(r_out,0,type);
- len_out = r_out->len;
- elt_out = &(r_out->elt[idx_out]);
- }
- if ( idx2 >= len2 || (idx1 < len1 && elt1->col <= elt2->col) )
- {
- elt_out->col = elt1->col;
- elt_out->val = elt1->val;
- if ( elt1->col == elt2->col && idx2 < len2 )
- { elt2++; idx2++; }
- elt1++; idx1++;
- }
- else
- {
- elt_out->col = elt2->col;
- elt_out->val = elt2->val;
- elt2++; idx2++;
- }
- elt_out++; idx_out++;
- }
- r_out->len = idx_out;
-
- return r_out;
- }
-
- /* sprow_copy -- copies r1 and r2 into r_out
- -- cannot be done in-situ
- -- type must be SPMAT or SPROW depending on
- whether r_out is a row of a SPMAT structure
- or a SPROW variable
- -- returns r_out */
- SPROW *sprow_copy(r1,r2,r_out,type)
- SPROW *r1, *r2, *r_out;
- int type;
- {
- int idx1, idx2, idx_out, len1, len2, len_out;
- row_elt *elt1, *elt2, *elt_out;
-
- if ( ! r1 || ! r2 )
- error(E_NULL,"sprow_copy");
- if ( ! r_out )
- r_out = sprow_get(MINROWLEN);
- if ( r1 == r_out || r2 == r_out )
- error(E_INSITU,"sprow_copy");
-
- /* Initialise */
- len1 = r1->len; len2 = r2->len; len_out = r_out->maxlen;
- idx1 = idx2 = idx_out = 0;
- elt1 = r1->elt; elt2 = r2->elt; elt_out = r_out->elt;
-
- while ( idx1 < len1 || idx2 < len2 )
- {
- while ( idx_out >= len_out )
- { /* r_out is too small */
- r_out->len = idx_out;
- r_out = sprow_xpd(r_out,0,type);
- len_out = r_out->maxlen;
- elt_out = &(r_out->elt[idx_out]);
- }
- if ( idx2 >= len2 || (idx1 < len1 && elt1->col <= elt2->col) )
- {
- elt_out->col = elt1->col;
- elt_out->val = elt1->val;
- if ( elt1->col == elt2->col && idx2 < len2 )
- { elt2++; idx2++; }
- elt1++; idx1++;
- }
- else
- {
- elt_out->col = elt2->col;
- elt_out->val = 0.0;
- elt2++; idx2++;
- }
- elt_out++; idx_out++;
- }
- r_out->len = idx_out;
-
- return r_out;
- }
-
- /* sprow_mltadd -- sets r_out <- r1 + alpha.r2
- -- cannot be in situ
- -- only for columns j0, j0+1, ...
- -- type must be SPMAT or SPROW depending on
- whether r_out is a row of a SPMAT structure
- or a SPROW variable
- -- returns r_out */
- SPROW *sprow_mltadd(r1,r2,alpha,j0,r_out,type)
- SPROW *r1, *r2, *r_out;
- double alpha;
- int j0, type;
- {
- int idx1, idx2, idx_out, len1, len2, len_out;
- row_elt *elt1, *elt2, *elt_out;
-
- if ( ! r1 || ! r2 )
- error(E_NULL,"sprow_mltadd");
- if ( r1 == r_out || r2 == r_out )
- error(E_INSITU,"sprow_mltadd");
- if ( j0 < 0 )
- error(E_BOUNDS,"sprow_mltadd");
- if ( ! r_out )
- r_out = sprow_get(MINROWLEN);
-
- /* Initialise */
- len1 = r1->len; len2 = r2->len; len_out = r_out->maxlen;
- /* idx1 = idx2 = idx_out = 0; *