f08pbce.c

/* nag_lapackeig_dgeesx (f08pbc) Example Program.
 *
 * Copyright 2025 Numerical Algorithms Group.
 *
 * Mark 31.1, 2025.
 */
#include<math.h>
#include<nag.h>
#include<stdio.h>
#ifdef __cplusplus
extern"C"{
#endif
staticNag_BooleanNAG_CALLselect_fun(constdoublewr,constdoublewi);
#ifdef __cplusplus
}
#endif
intmain(void){
/* Scalars */
doublealpha,anorm,beta,eps,norm,rconde,rcondv;
Integeri,j,n,pda,pdc,pdd,pdvs,sdim;
Integerexit_status=0;
/* Arrays */
double*a=0,*c=0,*d=0,*vs=0,*wi=0,*wr=0;
/* Nag Types */
NagErrorfail;
Nag_OrderTypeorder;
#ifdef NAG_COLUMN_MAJOR
#define A(I, J) a[(J - 1) * pda + I - 1]
order=Nag_ColMajor;
#else
#define A(I, J) a[(I - 1) * pda + J - 1]
order=Nag_RowMajor;
#endif
INIT_FAIL(fail);
printf("nag_lapackeig_dgeesx (f08pbc) Example Program Results\n\n");
/* Skip heading in data file */
scanf("%*[^\n]");
scanf("%"NAG_IFMT"%*[^\n]",&n);
if(n<0){
printf("Invalid n\n");
exit_status=1;
returnexit_status;
}
pda=n;
pdc=n;
pdd=n;
pdvs=n;
/* Allocate memory */
if(!(a=NAG_ALLOC(n*n,double))||!(c=NAG_ALLOC(n*n,double))||
!(d=NAG_ALLOC(n*n,double))||!(vs=NAG_ALLOC(n*n,double))||
!(wi=NAG_ALLOC(n,double))||!(wr=NAG_ALLOC(n,double))){
printf("Allocation failure\n");
exit_status=-1;
gotoEND;
}
/* Read in the matrix A */
for(i=1;i<=n;++i)
for(j=1;j<=n;++j)
scanf("%lf",&A(i,j));
scanf("%*[^\n]");
/* Copy A to D: nag_blast_dge_copy (f16qfc),
 * real valued general matrix copy.
 */
nag_blast_dge_copy(order,Nag_NoTrans,n,n,a,pda,d,pdd,&fail);
if(fail.code!=NE_NOERROR){
printf("Error from nag_blast_dge_copy (f16qfc).\n%s\n",fail.message);
exit_status=1;
gotoEND;
}
/* nag_blast_dge_norm (f16rac): Find norm of matrix A for use later
 * in relative error test.
 */
nag_blast_dge_norm(order,Nag_OneNorm,n,n,a,pda,&anorm,&fail);
if(fail.code!=NE_NOERROR){
printf("Error from nag_blast_dge_norm (f16rac).\n%s\n",fail.message);
exit_status=1;
gotoEND;
}
/* nag_file_print_matrix_real_gen (x04cac): Print Matrix A. */
fflush(stdout);
nag_file_print_matrix_real_gen(order,Nag_GeneralMatrix,Nag_NonUnitDiag,n,
n,a,pda,"Matrix A",0,&fail);
printf("\n");
if(fail.code!=NE_NOERROR){
printf("Error from nag_file_print_matrix_real_gen (x04cac).\n%s\n",
fail.message);
exit_status=1;
gotoEND;
}
/* Find the Schur factorization of A using nag_lapackeig_dgeesx (f08pbc). */
nag_lapackeig_dgeesx(order,Nag_Schur,Nag_SortEigVals,select_fun,
Nag_RCondBoth,n,a,pda,&sdim,wr,wi,vs,pdvs,
&rconde,&rcondv,&fail);
if(fail.code!=NE_NOERROR&&fail.code!=NE_SCHUR_REORDER_SELECT){
printf("Error from nag_lapackeig_dgeesx (f08pbc).\n%s\n",fail.message);
exit_status=1;
gotoEND;
}
/* Reconstruct A from Schur Factorization Z*T*Trans(Z) where T is upper
 * triangular and stored in A. This can be done using the following steps:
 * i. C = Z*T (nag_blast_dgemm, f16yac),
 * ii. D = D-C*trans(Z) (nag_blast_dgemm, f16yac).
 */
alpha=1.0;
beta=0.0;
nag_blast_dgemm(order,Nag_NoTrans,Nag_NoTrans,n,n,n,alpha,vs,pdvs,a,
pda,beta,c,pdc,&fail);
if(fail.code!=NE_NOERROR){
printf("Error from nag_blast_dgemm (f16yac).\n%s\n",fail.message);
exit_status=1;
gotoEND;
}
/* nag_blast_dgemm (f16yac):
 * Compute D = A - C*Z^T.
 */
alpha=-1.0;
beta=1.0;
nag_blast_dgemm(order,Nag_NoTrans,Nag_Trans,n,n,n,alpha,c,pdc,vs,
pdvs,beta,d,pdd,&fail);
if(fail.code!=NE_NOERROR){
printf("Error from nag_blast_dgemm (f16yac).\n%s\n",fail.message);
exit_status=1;
gotoEND;
}
/* nag_blast_dge_norm (f16rac): Find norm of difference matrix D and print
 * warning if it is too large relative to norm of A.
 */
nag_blast_dge_norm(order,Nag_OneNorm,n,n,d,pdd,&norm,&fail);
if(fail.code!=NE_NOERROR){
printf("Error from nag_blast_dge_norm (f16rac).\n%s\n",fail.message);
exit_status=1;
gotoEND;
}
/* Get the machine precision, using nag_machine_precision (x02ajc) */
eps=nag_machine_precision;
if(norm>pow(eps,0.8)*MAX(anorm,1.0)){
printf("||A-(Z*T*Z^T)||/||A|| is larger than expected.\n"
"Schur factorization has failed.\n");
exit_status=1;
gotoEND;
}
/* Print details on eigenvalues */
printf("Number of eigenvalues for which select is true = %4"NAG_IFMT"\n\n",
sdim);
if(fail.code==NE_SCHUR_REORDER_SELECT){
printf(" ** Note that rounding errors mean that leading eigenvalues in the"
" Schur form\n no longer satisfy select(lambda) = Nag_TRUE\n\n");
}else{
printf("The selected eigenvalues are:\n");
for(i=0;i<sdim;i++)
printf("%3"NAG_IFMT" (%13.4e, %13.4e)\n",i+1,wr[i],wi[i]);
}
/* Print out the reciprocal condition numbers */
printf("\nReciprocal of projection norm onto the invariant subspace\n");
printf("%26sfor the selected eigenvalues rconde = %8.1e\n\n","",rconde);
printf("Reciprocal condition number for the invariant subspace rcondv = "
"%8.1e\n\n",
rcondv);
/* Compute the approximate asymptotic error bound on the average absolute
 * error of the selected eigenvalues given by eps*norm(A)/rconde.
 */
printf("Approximate asymptotic error bound for selected eigenvalues = "
"%8.1e\n\n",
eps*anorm/rconde);
/* Compute an approximate asymptotic bound on the maximum angular error in
 * the computed invariant subspace given by eps*norm(A)/rcondv
 */
printf("Approximate asymptotic error bound for the invariant subspace = "
"%8.1e\n",
eps*anorm/rcondv);
END:
NAG_FREE(a);
NAG_FREE(c);
NAG_FREE(d);
NAG_FREE(vs);
NAG_FREE(wi);
NAG_FREE(wr);
returnexit_status;
}
staticNag_BooleanNAG_CALLselect_fun(constdoublear,constdoubleai){
/* Boolean function select for use with nag_lapackeig_dgees (f08pac)
 * Returns the value Nag_TRUE if the eigenvalue is real and positive
 */
return(ar>0.0&&ai==0.0?Nag_TRUE:Nag_FALSE);
}

AltStyle によって変換されたページ (->オリジナル) /