IllCondDetector.cpp
Go to the documentation of this file.
2 
3 // mapping from two-dim index to packed 'Up' column major layout storage
4 #define MAP(i,j,N) (i*N + j)
5 
7 {
8  debug_ = false;
9 }
10 
11 
13 {
14  debug_ = false;
15  EigenLap(K);
16 }
17 
19 {
20  if (A_ != NULL)
21  {
22  free(A_);
23  }
24 }
25 
27 {
28  // Convert Eigen library storage into LAPACK storage
29 
30  N_ = K.cols();
31  A_ = (double*)calloc(N_ * N_, sizeof(double));
32 
33  for (int i = 0; i < N_; i++)
34  {
35  for (int j = 0; j < N_; j++)
36  {
37  A_[MAP(i, j, N_)] = K.coeff(i, j);
38  }
39  }
40 
41  // 1-norm computing
42  std::vector<double> tmp;
43  for (int i = 0; i < N_; i++)
44  {
45  double sum = 0;
46  for (int j = 0; j < N_; j++)
47  {
48  sum += A_[MAP(i, j, N_)];
49  }
50  tmp.push_back(sum);
51  }
52  auto max = std::max_element(tmp.begin(), tmp.end());
53  Anorm_ = *max;
54 }
55 
56 void IllCondDetector::SetParm(int _ns, int _nl, int _condthres, int _gap)
57 {
58  assert(_ns > 0 || _nl > 0 || _condthres > 1 || _gap > 0);
59  ns_ = _ns;
60  nl_ = _nl;
61  cond_thres_ = _condthres;
62  gap_ = _gap;
63 }
64 
66 {
67  // rank checking
68  char *jobu = "N"; // No colums of U are computed
69  char *jobvt = "N"; // No rows of V**T are computed
70  int lda = N_; // Leading dimension
71 
72  double *A_copy = (double*)malloc(N_ * N_ * sizeof(double));
73  for (int i = 0; i < N_ * N_; i++)
74  {
75  A_copy[i] = A_[i];
76  }
77 
78  double *S = (double*)malloc(N_ * sizeof(double)); // The singular values of A
79  double *U = (double*)malloc(N_ * N_*sizeof(double));
80  double *Vt = (double*)malloc(N_ * N_*sizeof(double));
81  int lwork = 5 * N_;
82  double *work = (double*)malloc(lwork*sizeof(double));
83  int info = 1;
84 
85  dgesvd_(jobu, jobvt, &N_, &N_, A_copy, &lda, S, U, &N_, Vt, &N_, work, &lwork, &info);
86 
87  if (0 == info)
88  {
89  /* succeed */
90  printf("svd decomposition succeed in IllConditionDetecter.\n");
91  }
92  else
93  {
94  printf("svd decomposition fails in IllConditionDetecter.");
95  }
96 
97  assert(0 == info);
98 
99  int rank = 0;
100  std::vector<double> compare;
101  double max_tmp = 0;
102 
103  for (int i = 0; i < N_; i++)
104  {
105  compare.push_back(S[i]);
106  if (S[i] > max_tmp)
107  {
108  max_tmp = S[i];
109  }
110  }
111  double max = *std::max_element(compare.begin(), compare.end());
112 
113  cout << "Ill Condition Detector Rank Stat" << endl;
114  for (int i = 0; i < compare.size(); i++)
115  {
116  if (10e-15 * max < compare[i])
117  {
118  rank++;
119  }
120  }
121 
122  Statistics s_svd("SVD_IllCond", compare);
123  s_svd.GenerateStdVecFile();
124 
125  std::cout << "Rank of K_ : " << rank << std::endl;
126  std::cout << "ColN of K_ : " << N_ << std::endl;
127 
128  char uplo[] = "U";
129 
130  // Since a mechanism results in a singular stiffness matrix, an attempt to find its Cholesky factor
131  // is likely to break down and hence signal the problem.
132  dpotrf_(uplo, &N_, A_, &lda, &info);
133 
134  assert(info == 0);
135 
136  double *workcon = (double*)malloc(3 * N_ * sizeof(double));
137  int *lworkcon = (int*)malloc(N_ * sizeof(int));
138  dpocon_(uplo, &N_, A_, &lda, &Anorm_, &rcond_num_, workcon, lworkcon, &info);
139 
140  if (0 == info)
141  {
142  /* succeed */
143  printf("condition number calculation succeed in IllConditionDetecter.\n");
144  cout << "Condition Number: " << 1 / rcond_num_ << endl;
145  }
146  else
147  {
148  printf("condition number calculation failed in IllConditionDetecter.");
149  getchar();
150  exit;
151  }
152 
153  assert(info == 0);
154 
155  free(A_copy);
156  free(S);
157  free(U);
158  free(Vt);
159  free(work);
160  free(workcon);
161  free(lworkcon);
162 
163  return (1 / rcond_num_);
164 }
165 
166 double IllCondDetector::EquilibriumError(EigenSp const &K, VX const &D, VX const &F)
167 {
168  VX dF = K*D;
169  dF -= F;
170  return (dF.norm() / F.norm());
171 }
172 
174 {
175  /* 3x3 matrix A
176  * 76 25 11
177  * 27 89 51
178  * 18 60 32
179  */
180  double A[9] = { 76, 27, 18, 25, 89, 60, 11, 51, 32 };
181  double b[3] = { 10, 7, 43 };
182 
183  int N = 3;
184  int nrhs = 1;
185  int lda = 3;
186  int ipiv[3];
187  int ldb = 3;
188  int info;
189 
190  //dgesv_(&N, &nrhs, A, &lda, ipiv, b, &ldb, &info);
191 
192  //if (info == 0) /* succeed */
193  // printf("The solution is %lf %lf %lf\n", b[0], b[1], b[2]);
194  //else
195  // fprintf(stderr, "dgesv_ fails %d\n", info);
196  char uplo[] = "U";
197 
198  dpotrf_(uplo, &N, A, &lda, &info);
199 
200  if (0 == info)
201  {
202  cout << "cholesky succeed." << endl;
203  }
204  else
205  {
206  cout << "cholesky dead." << endl;
207  }
208 
209  double *workcon = (double*)malloc(3 * N * sizeof(double));
210  int *lworkcon = (int*)malloc(N * sizeof(int));
211 
212  dpocon_(uplo, &N, A, &lda, &Anorm_, &rcond_num_, workcon, lworkcon, &info);
213 
214  if (0 == info)
215  {
216  /* succeed */
217  printf("condition number calculation succeed in IllConditionDetecter.\n");
218  cout << "Condition number: " << 1 / rcond_num_ << endl;
219  }
220  else
221  {
222  printf("condition number calculation in IllConditionDetecter.");
223  }
224 
225  assert(info == 0);
226 
227 }
Eigen::VectorXd VX
void SetParm(int _ns, int _nl, int _condthres, int _gap)
void dgesvd_(const char *JOBU, const char *JOBVT, const int *M, const int *N, double *A, const int *LDA, double *S, double *U, const int *LDU, double *VT, const int *LDVT, double *WORK, const int *LWORK, int *info)
void dpocon_(const char *UPLO, const int *N, const double *AP, const int *lda, const double *ANORM, double *RCOND, double *WORK, int *LWORK, int *INFO)
double EquilibriumError(EigenSp const &K, VX const &D, VX const &F)
GLboolean GLboolean GLboolean b
void GenerateStdVecFile()
Definition: Statistics.cpp:117
void dpotrf_(const char *UPLO, const int *N, double *A, const int *LDA, int *info)
Eigen::SparseMatrix< double > EigenSp
#define MAP(i, j, N)
void EigenLap(EigenSp const &K)


choreo_task_sequence_planner
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 04:03:14