00001
00020 #include "newutil.h"
00021 #include <algorithm>
00022 #include <cassert>
00023
00024 MyReturnMatrix sqrt(const MyMatrix &mat) {
00025 Real *v_mat = mat.Store();
00026 int n = mat.Storage();
00027 Matrix result(mat.Nrows(),mat.Ncols());
00028 Real v_result[n];
00029
00030 std::transform(v_mat, v_mat+n, v_result, sqrt_double);
00031 result <<v_result;
00032 result.Release();
00033 return result;
00034 }
00035
00036 double log_double(double x) {
00037 return log(x);
00038 }
00039
00040
00041 MyReturnMatrix log(const MyMatrix &mat) {
00042 Real *v_mat = mat.Store();
00043 int n = mat.Storage();
00044 Matrix result(mat.Nrows(),mat.Ncols());
00045 Real v_result[n];
00046
00047 std::transform(v_mat, v_mat+n, v_result, log_double);
00048 result <<v_result;
00049 result.Release();
00050 return result;
00051 }
00052
00053 MyReturnMatrix pow(const ColumnVector &mat, double exp) {
00054 int n=mat.Nrows();
00055 ColumnVector result(n);
00056 int i;
00057
00058 for (i = 0; i < n; i++) {
00059 result[i] = pow(mat[i], exp);
00060 }
00061
00062 result.Release();
00063 return result;
00064 }
00065
00066 MyReturnMatrix pow2_m(const MyMatrix &mat) {
00067 Real *v_mat = mat.Store();
00068 int n = mat.Storage();
00069 Matrix result(mat.Nrows(),mat.Ncols());
00070 Real v_result[n];
00071
00072 std::transform(v_mat, v_mat+n, v_result, pow2_double);
00073 result <<v_result;
00074 result.Release();
00075 return result;
00076 }
00077
00078 MyReturnMatrix DotDivide(const MyMatrix &elem1, const MyMatrix &elem2) {
00079 Real *v_elem1 = elem1.Store();
00080 Real *v_elem2 = elem2.Store();
00081 int n = elem1.Storage();
00082 Matrix result(elem1.Nrows(),elem1.Ncols());
00083 Real v_result[n];
00084
00085 for (int i = 0; i < n; i++) {
00086 v_result[i] = v_elem1[i]/v_elem2[i];
00087 }
00088
00089 result <<v_result;
00090 result.Release();
00091 return result;
00092 }
00093
00094
00095
00096
00097 Real mean(const ColumnVector &mat) {
00098 int i, n=mat.Nrows();
00099 Real sum;
00100
00101 if (n == 0) {
00102 return 0;
00103 }
00104
00105 for (i = 0, sum = 0; i < n; i++) {
00106 sum += mat[i];
00107 }
00108
00109 return sum/n;
00110 }
00111
00112 Real median(const ColumnVector &mat) {
00113 int n=mat.Nrows();
00114
00115 if ( (n % 2) == 1) {
00116 return mat[n/2];
00117 }
00118 else {
00119 return (mat[n/2-1]+mat[n/2])/2;
00120 }
00121 }
00122
00123 Real median(const RowVector &mat) {
00124 int n=mat.Ncols();
00125
00126 if ( (n % 2) == 1) {
00127 return mat[n/2];
00128 }
00129 else {
00130 return (mat[n/2-1]+mat[n/2])/2;
00131 }
00132 }
00133
00134
00135 static Matrix *mat_sort;
00136
00137 void set_sort_matrix(Matrix *mat) {
00138 mat_sort = mat;
00139 }
00140
00141 bool sort_index_matrix(int i, int j) {
00142 Real val1, val2;
00143
00144 val1 = (*mat_sort)[0][i-1];
00145 val2 = (*mat_sort)[0][j-1];
00146
00147 if (val1 < val2) {
00148 return true;
00149 }
00150 else {
00151 return false;
00152 }
00153 }
00154
00155
00156 MyReturnMatrix myprctile(RowVector &inar, int *perc, int nperc) {
00157 int N = inar.Ncols();
00158
00159 int arindex[N];
00160 RowVector result(nperc);
00161 int i;
00162
00163 range(1, N, arindex);
00164
00165 mat_sort = &inar;
00166 sort(arindex, arindex+N, sort_index_matrix);
00167
00168 for (i = 0; i < nperc; i++) {
00169 int p = perc[i];
00170
00171 if (p <= 100*(0.5/N)) {
00172 result[i] = inar[arindex[0]-1];
00173 }
00174 else if (p >= 100*((N-0.5)/N)) {
00175 result[i] = inar[arindex[N-1]-1];
00176 }
00177 else {
00178 int pos = N*p/100;
00179 result[i] = inar[arindex[pos]-1];
00180 }
00181 }
00182
00183 return result;
00184 }
00185
00186
00187
00188 Real mean_diag(const DiagonalMatrix &mat) {
00189 int i, n=mat.Nrows();
00190 Real sum;
00191
00192 if (n == 0) {
00193 return 0;
00194 }
00195
00196 for (i = 0, sum = 0; i < n; i++) {
00197 sum += mat[i];
00198 }
00199
00200 return sum/n;
00201 }
00202
00203 double pow2_double(double x) {
00204 return pow2(x);
00205 }
00206
00207 double pow2(double x) {
00208 return x*x;
00209 }
00210
00211 double sqrt_double(double x) {
00212 return sqrt(x);
00213 }
00214
00215
00216 void copyRow(queue<Real> num, RowVector &row) {
00217 Real val;
00218 int i=0;
00219
00220 do {
00221 val = num.front();
00222 num.pop();
00223 row[i] = val;
00224 i += 1;
00225 } while (num.size() > 0);
00226 }
00227
00228 MyReturnMatrix DotVectors(ColumnVector &A, const ColumnVector &B) {
00229 int N = A.Nrows();
00230 ColumnVector col(N);
00231 int i;
00232
00233 for (i = 0; i < N; i++) {
00234 col[i] = A[i]*B[i];
00235 }
00236
00237 col.Release();
00238 return col;
00239 }
00240
00241 MyReturnMatrix DivVectors(ColumnVector &A, const ColumnVector &B) {
00242 int N = A.Nrows();
00243 ColumnVector col(N);
00244 int i;
00245
00246 for (i = 0; i < N; i++) {
00247 col[i] = A[i]/B[i];
00248 }
00249
00250 col.Release();
00251 return col;
00252 }
00253
00254
00255 void copyColumn(DiagonalMatrix diag, ColumnVector &row) {
00256 int n = diag.Nrows();
00257 int i;
00258
00259 for (i = 0; i < n; i++) {
00260 row[i] = diag[i];
00261 }
00262 }
00263
00264 void copyFromColumn(ColumnVector &row, DiagonalMatrix &diag) {
00265 int n = row.Nrows();
00266 int i;
00267
00268 for (i = 0; i < n; i++) {
00269 diag[i] = row[i];
00270 }
00271 }
00272
00273 Real min_positive(ColumnVector &num) {
00274 unsigned N = num.Ncols();
00275 Real minvalue;
00276
00277 assert(N != 0);
00278 minvalue = -1;
00279
00280 for (unsigned i = 1; i <= N; i++) {
00281 if (num[i] == 0) {
00282 continue;
00283 }
00284 else {
00285 if (minvalue < 0 || num[i] < minvalue) {
00286 minvalue = num[i];
00287 }
00288
00289 }
00290
00291 }
00292
00293 assert(minvalue > 0);
00294 return minvalue;
00295 }
00296
00297
00298 Real min_positive(queue<Real> num) {
00299 Real result, val;
00300 int init=1;
00301
00302 result = -1;
00303
00304 do {
00305 val = num.front();
00306 num.pop();
00307
00308 if (val > 0 && (val < result || init) ) {
00309 result = val;
00310 init = 0;
00311 }
00312
00313 } while (num.size() > 0);
00314
00315 if (init == 1) {
00316 throw string("Error, min_positive no encontr�valor != 0");
00317 }
00318 else {
00319 return result;
00320 }
00321 }
00322
00323 void range(int min, int max, int *Rang) {
00324 int i, value;
00325 int num=max-min+1;
00326
00327 for (i =0, value=min; i < num; i++) {
00328 Rang[i] = value;
00329 value += 1;
00330 }
00331
00332 }
00333
00334 void getColumns(Matrix &m, int *cols, int num, Matrix &result) {
00335 int i, value;
00336
00337 for (i = 0; i < num; i++) {
00338 value=cols[i];
00339 result.Column(i+1) = m.Column(value);
00340 }
00341 }
00342
00343 double norm(const MyMatrix &mat) {
00344 DiagonalMatrix D;
00345
00346 SVD(mat,D);
00347 return D.Maximum();
00348 }
00349
00350 MyReturnMatrix eye(int N) {
00351 MyMatrix A(N,N);
00352 IdentityMatrix I(N);
00353 A << I;
00354 A.Release();
00355 return A;
00356 }
00357
00358 MyReturnMatrix pow2(ColumnVector &weights) {
00359 int N = weights.Nrows();
00360 ColumnVector col(N);
00361 int i;
00362
00363 for (i = 0; i < N; i++) {
00364 col[i] = pow2(weights[i]);
00365 }
00366
00367 col.Release();
00368 return col;
00369 }
00370
00371 MyReturnMatrix pow2(RowVector &weights) {
00372 int N = weights.Nrows();
00373 ColumnVector col(N);
00374 int i;
00375
00376 for (i = 0; i < N; i++) {
00377 col[i] = pow2(weights[i]);
00378 }
00379
00380 col.Release();
00381 return col;
00382 }
00383
00384
00385 Real min(ColumnVector &mat) {
00386 return mat.Minimum();
00387 }
00388
00389 Real max(ColumnVector &mat) {
00390 return mat.Maximum();
00391 }
00392
00399 void checkDiag(Matrix &C, DiagonalMatrix &Diag) {
00400 Real min_d, max_d;
00401 int N = Diag.Nrows();
00402 int i;
00403 ColumnVector D(N);
00404
00405 copyColumn(Diag, D);
00406
00407
00408 for (i = 0; i < N; i++) {
00409 if (D[i] <= 0) {
00410 D[i] = 0;
00411 }
00412 }
00413
00414 min_d = min(D);
00415 max_d = max(D);
00416
00417
00418 if (min_d == 0) {
00419 Real tmp = max_d/1e14;
00420 C = C + tmp*eye(N); D = D + tmp*eye(N);
00421 max_d = max(D);
00422 min_d = min(D);
00423 }
00424
00425
00426 if (max_d > 1e14*min_d) {
00427 cout <<"CMAESC: condition of C at upper limit" <<endl;
00428 Real tmp = max_d/1e14 - min_d;
00429 ColumnVector increm(N);
00430 increm = tmp;
00431 C = C + tmp*eye(N);
00432 D = D + increm;
00433 }
00434
00435 copyFromColumn(D, Diag);
00436 }
00437
00438 void checkAxis(ColumnVector &xmean, Real ccov, Real cs, Real damps, int countiter, ColumnVector &sigma, Matrix &C, Matrix &BD) {
00439 int N = xmean.Nrows();
00440 ColumnVector D(N);
00441 int i;
00442
00443 DiagonalMatrix DiagC(N);
00444 DiagC <<C;
00445 copyColumn(DiagC, D);
00446
00447 bool too_low = false;
00448
00449
00450 for (i = 0; i < N; i++) {
00451 if (xmean[i] == xmean[i] + 0.2*sigma[i]*D[i]) {
00452 C = C + ccov * D[i];
00453 too_low = true;
00454 }
00455 }
00456
00457 if (too_low) {
00458 sigma *= exp(0.05+cs/damps);
00459 }
00460
00461
00462 int posi = 1+countiter % N;
00463 ColumnVector BD_i = BD.Column(posi);
00464 bool axis_too_low = true;
00465
00466 for (i = 0; i < N && axis_too_low; i++) {
00467 if (xmean[i] != xmean[i] + 0.1*sigma[i]*BD_i[i]) {
00468 axis_too_low = false;
00469 posi = i;
00470 }
00471 }
00472
00473 if (axis_too_low) {
00474 cout <<"CMAESC: an axis standard deviation " <<sigma[posi]*D[posi] <<" has no effect" <<endl;
00475 sigma = sigma * exp(0.2+cs/damps);
00476 }
00477
00478 }
00479
00480 double log(int x) {
00481 double dx = x;
00482 return log(dx);
00483 }
00484
00485 double sqrt(int x) {
00486 double dx = x;
00487 return sqrt(dx);
00488 }
00489
00490 void copyColumnVector(long double *vector, unsigned N, ColumnVector *column) {
00491 Real data[N];
00492
00493 for (unsigned i = 0; i < N; ++i) {
00494 data[i] = vector[i];
00495 }
00496
00497 *column << data;
00498 }
00499
00500 void copyToColumn(tReal *vector, unsigned N, ColumnVector *column) {
00501 Real data[N];
00502
00503 for (unsigned i = 0; i < N; ++i) {
00504 data[i] = vector[i];
00505 }
00506
00507 *column << data;
00508 }
00509
00510 void copyToColumn(vector<tReal> array, ColumnVector *column) {
00511 copyToColumn(&array[0], array.size(), column);
00512 }