1 /** 2 Ported to dlang 2015 by Laeeth Isharc 3 */ 4 /** 5 This is a work in progress and does not yet compile 6 */ 7 8 module kaleidic.api.mathgl.data; 9 /+ 10 /// Class for working with data array 11 class MglData 12 { 13 //public : using MglDataA : : Momentum; 14 long nx; ///< number of points in 1st dimensions ('x' dimension) 15 long ny; ///< number of points in 2nd dimensions ('y' dimension) 16 long nz; ///< number of points in 3d dimensions ('z' dimension) 17 mreal* a; ///< data array 18 string id; ///< column (or slice) names 19 bool useLink; ///< use external data (i.e. don't free it) 20 21 /// Initiate by other MglData variable 22 this(const MglData* d) 23 { 24 a = 0; 25 mgl_data_set(this, & d); 26 } // NOTE: must be constructor for MglData& to exclude copy one 27 28 static if(HaveRval) 29 { 30 this(MglData** d) 31 { 32 this.nx=d.nx; 33 this.ny=d.ny; 34 this.nz=d.nz; 35 thia.a=d.a; 36 this.id=d.id; 37 this.useLink=d.useLink; 38 //this. s = d.s; 39 //this.temp = d.temp; 40 this.func = d.func; 41 this.o = d.o; 42 d.a = 0; 43 d.func = 0; 44 } 45 } 46 47 this(const MglDataA* d) 48 { 49 a = 0; 50 if (d) 51 mgl_data_set(this, d); 52 else 53 mgl_data_create(this, 1, 1, 1); 54 } 55 56 this(MglData * d) // NOTE: Variable d will be deleted!!! 57 { 58 if (d is null) 59 { 60 nx = d.nx; 61 ny = d.ny; 62 nz = d.nz; 63 a = d.a; 64 d.a = 0; 65 temp = d.temp; 66 func = d.func; 67 o = d.o; 68 s = d.s; 69 id = d.id; 70 useLink = d.useLink; 71 delete d; 72 } 73 else 74 { 75 a = 0; 76 create(1); 77 } 78 } 79 80 /// Initiate by flat array 81 this(int size, const float * d) 82 { 83 a = 0; 84 set(d, size); 85 } 86 this(int rows, int cols, const float * d) 87 { 88 a = 0; 89 set(d, cols, rows); 90 } 91 this(int size, const double * d) 92 { 93 a = 0; 94 set(d, size); 95 } 96 this(int rows, int cols, const double * d) 97 { 98 a = 0; 99 set(d, cols, rows); 100 } 101 this(const double * d, int size) 102 { 103 a = 0; 104 set(d, size); 105 } 106 this(const double * d, int rows, int cols) 107 { 108 a = 0; 109 set(d, cols, rows); 110 } 111 this(const float * d, int size) 112 { 113 a = 0; 114 set(d, size); 115 } 116 this(const float * d, int rows, int cols) 117 { 118 a = 0; 119 set(d, cols, rows); 120 } 121 /// Read data from file 122 this(string fname) 123 { 124 a = 0; 125 Read(fname); 126 } 127 /// allocate the memory for data array and initialize it zero 128 this(long xx = 1, long yy = 1, long zz = 1) 129 { 130 a = 0; 131 create(xx, yy, zz); 132 } 133 134 /// Delete the array 135 ~this() 136 { 137 //if (!useLink && a) 138 // delete[] a; 139 } 140 141 mreal getVal(long i, long j = 0, long k = 0) const 142 { 143 return mgl_data_get_value(this, i, j, k); 144 } 145 146 void setVal(mreal f, long i, long j = 0, long k = 0) 147 { 148 mgl_data_set_value(this, f, i, j, k); 149 } 150 151 /// Get sizes 152 long getNx() const 153 { 154 return nx; 155 } 156 157 long getNy() const 158 { 159 return ny; 160 } 161 162 long getNz() const 163 { 164 return nz; 165 } 166 167 /// Link external data array (don't delete it at exit) 168 void link(mreal* A, long NX, long NY = 1, long NZ = 1) 169 { 170 mgl_data_link(this, A, NX, NY, NZ); 171 } 172 173 void link(MglData* d) 174 { 175 link(d.a, d.nx, d.ny, d.nz); 176 } 177 /// allocate memory and copy the data from the gsl_vector 178 void set(gsl_vector* m) 179 { 180 mgl_data_set_vector(this, m); 181 } 182 183 /// allocate memory and copy the data from the gsl_matrix 184 void set(gsl_matrix* m) 185 { 186 mgl_data_set_matrix(this, m); 187 } 188 189 /// allocate memory and copy the data from the (float *) array 190 void set(in float* A, long NX, long NY = 1, long NZ = 1) 191 { 192 mgl_data_set_float(this, A, NX, NY, NZ); 193 } 194 195 /// allocate memory and copy the data from the (double *) array 196 void set(const double* A, long NX, long NY = 1, long NZ = 1) 197 { 198 mgl_data_set_double(this, A, NX, NY, NZ); 199 } 200 201 /// allocate memory and copy the data from the (float **) array 202 void set(in float** A, long N1, long N2) 203 { 204 mgl_data_set_float2(this, A, N1, N2); 205 } 206 /// allocate memory and copy the data from the (double **) array 207 void set(in double** A, long N1, long N2) 208 { 209 mgl_data_set_double2(this, A, N1, N2); 210 } 211 /// allocate memory and copy the data from the (float ***) array 212 void set(in float** A, long N1, long N2, long N3) 213 { 214 mgl_data_set_float3(this, A, N1, N2, N3); 215 } 216 /// allocate memory and copy the data from the (double ***) array 217 void set(in double** A, long N1, long N2, long N3) 218 { 219 mgl_data_set_double3(this, A, N1, N2, N3); 220 } 221 /// allocate memory and scanf the data from the string 222 void set(string str, long NX, long NY = 1, long NZ = 1) 223 { 224 mgl_data_set_values(this, str.toStringz, NX, NY, NZ); 225 } 226 227 /// Import data from abstract type 228 void set(HCDT dat) 229 { 230 mgl_data_set(this, dat); 231 } 232 233 void set(const MglDataA* dat) 234 { 235 mgl_data_set(this, & dat); 236 } 237 /// allocate memory and copy data from std::vector<T> 238 void set(int[] d) 239 { 240 if (d.length < 1) 241 return; 242 create(d.length); 243 for (long i = 0; i < nx; i++) 244 a[i] = d[i]; 245 } 246 void set(float[] d) 247 { 248 if (d.length < 1) 249 return; 250 create(d.length); 251 foreach(i;0..nx) 252 a[i] = d[i]; 253 } 254 void set(double[] d) 255 { 256 if (d.length < 1) 257 return; 258 create(d.length); 259 foreach(i;0..nx) 260 a[i] = d[i]; 261 } 262 263 /// create or recreate the array with specified size and fill it by zero 264 void create(long mx, long my = 1, long mz = 1) 265 { 266 mgl_data_create(this, mx, my, mz); 267 } 268 269 /// Rearange data dimensions 270 void rearrange(long mx, long my = 0, long mz = 0) 271 { 272 mgl_data_rearrange(this, mx, my, mz); 273 } 274 275 /// Transpose dimensions of the data (generalization of Transpose) 276 void transpose(string dim = "yx") 277 { 278 mgl_data_transpose(this, dim); 279 } 280 281 /// Extend data dimensions 282 void extend(long n1, long n2 = 0) 283 { 284 mgl_data_extend(this, n1, n2); 285 } 286 287 /// Reduce size of the data 288 void squeeze(long rx, long ry = 1, long rz = 1, bool smooth = false) 289 { 290 mgl_data_squeeze(this, rx, ry, rz, smooth); 291 } 292 293 /// Crop the data 294 void crop(long n1, long n2, char dir = 'x') 295 { 296 mgl_data_crop(this, n1, n2, dir); 297 } 298 299 /// Insert data rows/columns/slices 300 void insert(char dir, long at = 0, long num = 1) 301 { 302 mgl_data_insert(this, dir, at, num); 303 } 304 305 /// Delete data rows/columns/slices 306 void deleteItems(char dir, long at = 0, long num = 1) 307 { 308 mgl_data_delete(this, dir, at, num); 309 } 310 311 /// Remove rows with duplicate values in column id 312 void clean(long id) 313 { 314 mgl_data_clean(this, id); 315 } 316 317 /// Join with another data array 318 void join(const MglDataA* d) 319 { 320 mgl_data_join(this, *d); 321 } 322 323 /// Modify the data by specified formula 324 void modify(string eq, long dim = 0) 325 { 326 mgl_data_modify(this, eq.toStringz, dim); 327 } 328 329 /// Modify the data by specified formula 330 void modify(string eq, in MglDataA* vdat, in MglDataA* wdat) 331 { 332 mgl_data_modify_vw(this, eq.to!stringz, *vdat, * wdat); 333 } 334 /// Modify the data by specified formula 335 void modify(string eq, const MglDataA* vdat) 336 { 337 mgl_data_modify_vw(this, eq.toStringz, *vdat, 0); 338 } 339 /// Modify the data by specified formula assuming x,y,z in range [r1,r2] 340 void fill(HMGL gr, string eq, string opt = "") 341 { 342 mgl_data_fill_eq(gr, this, eq.toStringz, 0, 0, opt); 343 } 344 345 void fill(HMGL gr, string eq, const MglDataA* vdat, string opt = "") 346 { 347 mgl_data_fill_eq(gr, this, eq.toStringz, *vdat, 0, opt.toStringz); 348 } 349 350 void fill(HMGL gr, string eq, const MglDataA* vdat, const MglDataA* wdat, string opt = "") 351 { 352 mgl_data_fill_eq(gr, this, eq.toStringz, *vdat, * wdat, opt.toStringz); 353 } 354 /// Equidistantly fill the data to range [x1,x2] in direction dir 355 void fill(mreal x1, mreal x2 = mglNaN, char dir = 'x') 356 { 357 mgl_data_fill(this, x1, x2, dir); 358 } 359 360 /// fill the data by interpolated values of vdat parametrically depended on xdat,ydat,zdat for x,y,z in range [p1,p2] using global spline 361 void refillGS(in MglDataA* xdat, const MglDataA* vdat, mreal x1, mreal x2, 362 long sl = - 1) 363 { 364 mgl_data_refill_gs(this, *xdat, & vdat, x1, x2, sl); 365 } 366 /// fill the data by interpolated values of vdat parametrically depended on xdat,ydat,zdat for x,y,z in range [p1,p2] 367 void refill(in MglDataA* xdat, in MglDataA* vdat, mreal x1, mreal x2, long sl = - 1) 368 { 369 mgl_data_refill_x(this, *xdat, & vdat, x1, x2, sl); 370 } 371 void refill(in MglDataA* xdat, in MglDataA* vdat, MglPoint p1, MglPoint p2, 372 long sl = - 1) 373 { 374 mgl_data_refill_x(this, *xdat, & vdat, p1.x, p2.x, sl); 375 } 376 void refill(in MglDataA* xdat, in MglDataA* ydat, in MglDataA* vdat, 377 MglPoint p1, MglPoint p2, long sl = - 1) 378 { 379 mgl_data_refill_xy(this, *xdat, & ydat, & vdat, p1.x, p2.x, p1.y, p2.y, 380 sl); 381 } 382 void refill(in MglDataA* xdat, in MglDataA* ydat, in MglDataA* zdat, 383 in MglDataA* vdat, MglPoint p1, MglPoint p2) 384 { 385 mgl_data_refill_xyz(this, *xdat, & ydat, & zdat, & vdat, p1.x, p2.x, 386 p1.y, p2.y, p1.z, p2.z); 387 } 388 /// fill the data by interpolated values of vdat parametrically depended on xdat,ydat,zdat for x,y,z in axis range of gr 389 void refill(HMGL gr, in MglDataA* xdat, in MglDataA* vdat, 390 long sl = - 1, string opt = "") 391 { 392 mgl_data_refill_gr(gr, this, *xdat, 0, 0, & vdat, sl, opt); 393 } 394 void refill(HMGL gr, in MglDataA* xdat, in MglDataA* ydat, 395 in MglDataA* vdat, long sl = - 1, string opt = "") 396 { 397 mgl_data_refill_gr(gr, this, *xdat, & ydat, 0, & vdat, sl, opt); 398 } 399 void refill(HMGL gr, in MglDataA* xdat, in MglDataA* ydat, 400 in MglDataA* zdat, in MglDataA* vdat, string opt = "") 401 { 402 mgl_data_refill_gr(gr, this, *xdat, & ydat, & zdat, & vdat, - 1, opt); 403 } 404 /// set the data by triangulated surface values assuming x,y,z in axis range of gr 405 void grid(HMGL gr, in MglDataA* x, in MglDataA* y, in MglDataA* z, string opt = "") 406 { 407 mgl_data_grid(gr, this, *x, *y, *z, opt.toStringz); 408 } 409 /// set the data by triangulated surface values assuming x,y,z in range [p1, p2] 410 void grid(in MglDataA* xdat, in MglDataA* ydat, in MglDataA* vdat, 411 MglPoint p1, MglPoint p2) 412 { 413 mgl_data_grid_xy(this, *xdat, & ydat, & vdat, p1.x, p2.x, p1.y, p2.y); 414 } 415 /// Put value to data element(s) 416 void put(mreal val, long i = -1, long j = -1, long k = -1) 417 { 418 mgl_data_put_val(this, val, i, j, k); 419 } 420 421 /// Put array to data element(s) 422 void put(in MglDataA* dat, long i = - 1, long j = - 1, long k = - 1) 423 { 424 mgl_data_put_dat(this, & dat, i, j, k); 425 } 426 /// set names for columns (slices) 427 void setColumnId(string ids) 428 { 429 mgl_data_set_id(this, ids); 430 } 431 432 /// Make new id 433 void newId() 434 { 435 id.clear(); 436 } 437 438 /// Read data from tab-separated text file with auto determining size 439 bool read(string fname) 440 { 441 return mgl_data_read(this, fname); 442 } 443 444 /// Read data from text file with specifeid size 445 bool read(string fname, long mx, long my = 1, long mz = 1) 446 { 447 return mgl_data_read_dim(this, fname.toStringz, mx, my, mz); 448 } 449 450 /// Import data array from PNG file according color scheme 451 void importData(string fname, string scheme, mreal v1 = 0, mreal v2 = 1) 452 { 453 mgl_data_import(this, fname.toStringz, scheme.toStringz, v1, v2); 454 } 455 456 /// Read data from tab-separated text files with auto determining size which filenames are result of sprintf(fname,templ,t) where t=from:step:to 457 bool readRange(string templ, double from, double to, double step = 1, bool as_slice = false) 458 { 459 return mgl_data_read_range(this, templ.toStringz, from, to, step, as_slice); 460 } 461 462 /// Read data from tab-separated text files with auto determining size which filenames are satisfied to template (like "t_*.dat") 463 bool readall(string templ, bool as_slice = false) 464 { 465 return mgl_data_read_all(this, templ.toStringz, as_slice); 466 } 467 468 /// Read data from text file with size specified at beginning of the file 469 bool readMat(string fname, long dim = 2) 470 { 471 return mgl_data_read_mat(this, fname.toStringz, dim); 472 } 473 474 /// Read data array from HDF file (parse HDF4 and HDF5 files) 475 int readHDF(string fname, ubyte[] data) 476 { 477 return mgl_data_read_hdf(this, fname.toStringz, data.ptr); 478 } 479 480 /// Get column (or slice) of the data filled by formulas of named columns 481 MglData Column(string eq) const 482 { 483 return MglData(true, mgl_data_column(this, eq.toStringz)); 484 } 485 486 /// Get momentum (1D-array) of data along direction 'dir'. String looks like "x1" for median in x-direction, "x2" for width in x-dir and so on. 487 MglData Momentum(char dir, string how) const 488 { 489 return MglData(true, mgl_data_momentum(this, dir, how.toStringz)); 490 } 491 492 /// Get sub-array of the data with given fixed indexes 493 MglData SubData(long xx, long yy = -1, long zz = -1) const 494 { 495 return MglData(true, mgl_data_subdata(this, xx, yy, zz)); 496 } 497 498 MglData SubData(in MglDataA* xx, in MglDataA* yy, in MglDataA* zz) const 499 { 500 return MglData(true, mgl_data_subdata_ext(this, & xx, & yy, & zz)); 501 } 502 MglData SubData(in MglDataA* xx, in MglDataA* yy) const 503 { 504 return MglData(true, mgl_data_subdata_ext(this, & xx, & yy, 0)); 505 } 506 MglData subData(in MglDataA* xx) const 507 { 508 return MglData(true, mgl_data_subdata_ext(this, & xx, 0, 0)); 509 } 510 /// Get trace of the data array 511 MglData trace() const 512 { 513 return MglData(true, mgl_data_trace(this)); 514 } 515 516 /// create n-th points distribution of this data values in range [v1, v2] 517 MglData hist(long n, mreal v1 = 0, mreal v2 = 1, long nsub = 0) const 518 { 519 return MglData(true, mgl_data_hist(this, n, v1, v2, nsub)); 520 } 521 522 /// create n-th points distribution of this data values in range [v1, v2] with weight w 523 MglData hist(in MglDataA* w, long n, mreal v1 = 0, mreal v2 = 1, long nsub = 0) const 524 { 525 return MglData(true, mgl_data_hist_w(this, & w, n, v1, v2, nsub)); 526 } 527 /// Get array which is result of summation in given direction or directions 528 MglData sum(string dir) const 529 { 530 return MglData(true, mgl_data_sum(this, dir)); 531 } 532 533 /// Get array which is result of maximal values in given direction or directions 534 MglData max(string dir) const 535 { 536 return MglData(true, mgl_data_max_dir(this, dir)); 537 } 538 539 /// Get array which is result of minimal values in given direction or directions 540 MglData min(string dir) const 541 { 542 return MglData(true, mgl_data_min_dir(this, dir)); 543 } 544 545 /// Get the data which is direct multiplication (like, d[i,j] = this[i]*a[j] and so on) 546 MglData combine(in MglDataA* dat) const 547 { 548 return MglData(true, mgl_data_combine(this, & dat)); 549 } 550 /// Resize the data to new size of box [x1,x2]*[y1,y2]*[z1,z2] 551 MglData resize(long mx, long my = 0, long mz = 0, mreal x1 = 0, mreal x2 = 1, 552 mreal y1 = 0, mreal y2 = 1, mreal z1 = 0, mreal z2 = 1) const 553 { 554 return MglData(true, mgl_data_resize_box(this, mx, my, mz, x1, x2, y1, y2, 555 z1, z2)); 556 } 557 558 /// Get array which values is result of interpolation this for coordinates from other arrays 559 MglData evaluate(in MglData* idat, bool norm = true) const 560 { 561 return MglData(true, mgl_data_evaluate(this, & idat, 0, 0, norm)); 562 } 563 MglData evaluate(in MglData* idat, in MglData* jdat, bool norm = true) const 564 { 565 return MglData(true, mgl_data_evaluate(this, & idat, & jdat, 0, norm)); 566 } 567 MglData evaluate(in MglData* idat, in MglData* jdat, in MglData* kdat, 568 bool norm = true) const 569 { 570 return MglData(true, mgl_data_evaluate(this, & idat, & jdat, & kdat, norm)); 571 } 572 /// Find roots for set of nonlinear equations defined by textual formula 573 MglData roots(string func, char var = 'x') const 574 { 575 return MglData(true, mgl_data_roots(func, this, var)); 576 } 577 578 /// Find correlation with another data arrays 579 MglData correl(in MglDataA* dat, string dir) const 580 { 581 return MglData(true, mgl_data_correl(this, & dat, dir)); 582 } 583 /// Find auto correlation function 584 MglData autoCorrel(string dir) const 585 { 586 return MglData(true, mgl_data_correl(this, this, dir)); 587 } 588 589 /// Cumulative summation the data in given direction or directions 590 void cumSum(string dir) 591 { 592 mgl_data_cumsum(this, dir); 593 } 594 595 /// Integrate (cumulative summation) the data in given direction or directions 596 void integral(string dir) 597 { 598 mgl_data_integral(this, dir); 599 } 600 601 /// Differentiate the data in given direction or directions 602 void diff(string dir) 603 { 604 mgl_data_diff(this, dir); 605 } 606 607 /// Differentiate the parametrically specified data along direction v1 with v2=const 608 void diff(ref MglDataA v1, ref MglDataA v2) 609 { 610 mgl_data_diff_par(this, v1, v2, 0); 611 } 612 /// Differentiate the parametrically specified data along direction v1 with v2,v3=const 613 void diff(ref MglDataA v1,ref MglDataA v2, ref MglDataA v3) 614 { 615 mgl_data_diff_par(this, v1, v2, v3); 616 } 617 /// Double-differentiate (like Laplace operator) the data in given direction 618 void Diff2(string dir) 619 { 620 mgl_data_diff2(this, dir); 621 } 622 623 /// Swap left and right part of the data in given direction (useful for Fourier spectrum) 624 void Swap(string dir) 625 { 626 mgl_data_swap(this, dir); 627 } 628 629 /// Roll data along direction dir by num slices 630 void Roll(char dir, long num) 631 { 632 mgl_data_roll(this, dir, num); 633 } 634 635 /// Mirror the data in given direction (useful for Fourier spectrum) 636 void Mirror(string dir) 637 { 638 mgl_data_mirror(this, dir); 639 } 640 641 /// Sort rows (or slices) by values of specified column 642 void Sort(long idx, long idy = -1) 643 { 644 mgl_data_sort(this, idx, idy); 645 } 646 647 /// set as the data envelop 648 void Envelop(char dir = 'x') 649 { 650 mgl_data_envelop(this, dir); 651 } 652 653 /// Remove phase jump 654 void Sew(string dirs = "xyz", mreal da = 2 * mglPi) 655 { 656 mgl_data_sew(this, dirs, da); 657 } 658 659 /// Smooth the data on specified direction or directions 660 void Smooth(string dirs = "xyz", mreal delta = 0) 661 { 662 mgl_data_smooth(this, dirs, delta); 663 } 664 665 /// Normalize the data to range [v1,v2] 666 void Norm(mreal v1 = 0, mreal v2 = 1, bool sym = false, long dim = 0) 667 { 668 mgl_data_norm(this, v1, v2, sym, dim); 669 } 670 671 /// Normalize the data to range [v1,v2] slice by slice 672 void NormSl(mreal v1 = 0, mreal v2 = 1, char dir = 'z', bool keep_en = true, bool sym = false) 673 { 674 mgl_data_norm_slice(this, v1, v2, dir, keep_en, sym); 675 } 676 677 /// Apply Hankel transform 678 void Hankel(string dir) 679 { 680 mgl_data_hankel(this, dir); 681 } 682 683 /// Apply Sin-Fourier transform 684 void SinFFT(string dir) 685 { 686 mgl_data_sinfft(this, dir); 687 } 688 689 /// Apply Cos-Fourier transform 690 void CosFFT(string dir) 691 { 692 mgl_data_cosfft(this, dir); 693 } 694 695 /// fill data by 'x'/'k' samples for Hankel ('h') or Fourier ('f') transform 696 void fillSample(string how) 697 { 698 mgl_data_fill_sample(this, how); 699 } 700 701 /// Return an approximated x-value (root) when dat(x) = val 702 mreal Solve(mreal val, bool use_spline = true, long i0 = 0) const 703 { 704 return mgl_data_solve_1d(this, val, use_spline, i0); 705 } 706 707 /// Return an approximated value (root) when dat(x) = val 708 MglData solve(mreal val, char dir, bool norm = true) const 709 { 710 return MglData(true, mgl_data_solve(this, val, dir, 0, norm)); 711 } 712 713 MglData solve(mreal val, char dir, in MglData* i0, bool norm = true) const 714 { 715 return MglData(true, mgl_data_solve(this, val, dir, & i0, norm)); 716 } 717 718 /// Interpolate by cubic spline the data to given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1] 719 mreal spline(mreal x, mreal y = 0, mreal z = 0) const 720 { 721 return mgl_data_spline(this, x, y, z); 722 } 723 724 /// Interpolate by cubic spline the data to given point x,\a y,\a z which normalized in range [0, 1] 725 mreal spline1(mreal x, mreal y = 0, mreal z = 0) const 726 { 727 return mgl_data_spline(this, x * (nx - 1), y * (ny - 1), z * (nz - 1)); 728 } 729 730 /// Interpolate by linear function the data to given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1] 731 mreal linear(mreal x, mreal y = 0, mreal z = 0) const 732 { 733 return mgl_data_linear(this, x, y, z); 734 } 735 736 /// Interpolate by line the data to given point x,\a y,\a z which normalized in range [0, 1] 737 mreal linear1(mreal x, mreal y = 0, mreal z = 0) const 738 { 739 return mgl_data_linear(this, x * (nx - 1), y * (ny - 1), z * (nz - 1)); 740 } 741 742 /// Interpolate by cubic spline the data and return its derivatives at given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1] 743 mreal spline(ref MglPoint dif, mreal x, mreal y = 0, mreal z = 0) const 744 { 745 return mgl_data_spline_ext(this, x, y, z, & (dif.x), & (dif.y), & (dif.z)); 746 } 747 /// Interpolate by cubic spline the data and return its derivatives at given point x,\a y,\a z which normalized in range [0, 1] 748 mreal spline1(ref MglPoint dif, mreal x, mreal y = 0, mreal z = 0) const 749 { 750 mreal res = mgl_data_spline_ext(this, x * (nx - 1), y * (ny - 1), 751 z * (nz - 1), &(dif.x), &(dif.y), &(dif.z)); 752 dif.x *= nx > 1 ? nx - 1 : 1; 753 dif.y *= ny > 1 ? ny - 1 : 1; 754 dif.z *= nz > 1 ? nz - 1 : 1; 755 return res; 756 } 757 /// Interpolate by linear function the data and return its derivatives at given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1] 758 mreal linear(ref MglPoint dif, mreal x, mreal y = 0, mreal z = 0) const 759 { 760 return mgl_data_linear_ext(this, x, y, z, & (dif.x), & (dif.y), & (dif.z)); 761 } 762 /// Interpolate by line the data and return its derivatives at given point x,\a y,\a z which normalized in range [0, 1] 763 mreal linear1(ref MglPoint dif, mreal x, mreal y = 0, mreal z = 0) const 764 { 765 mreal res = mgl_data_linear_ext(this, x * (nx - 1), y * (ny - 1), 766 z * (nz - 1), &(dif.x), &(dif.y), &(dif.z)); 767 dif.x *= nx > 1 ? nx - 1 : 1; 768 dif.y *= ny > 1 ? ny - 1 : 1; 769 dif.z *= nz > 1 ? nz - 1 : 1; 770 return res; 771 } 772 /** 773 /// Copy data from other MglData variable 774 in MglDataA* operator = (in MglDataA* d) 775 { 776 if (this != & d) 777 mgl_data_set(this, & d); 778 return d; 779 } 780 in MglData* operator = (in MglData* d) 781 { 782 if (this != & d) 783 mgl_data_set(this, & d); 784 return d; 785 } 786 mreal operator = (mreal val) 787 { 788 mgl_data_fill(this, val, val, 'x'); 789 return val; 790 } 791 /// Multiply the data by other one for each element 792 void operator *= (in MglDataA* d) 793 { 794 mgl_data_mul_dat(this, & d); 795 } 796 /// Divide the data by other one for each element 797 void operator /= (in MglDataA* d) 798 { 799 mgl_data_div_dat(this, & d); 800 } 801 /// Add the other data 802 void operator += (in MglDataA* d) 803 { 804 mgl_data_add_dat(this, & d); 805 } 806 /// Subtract the other data 807 void operator -= (in MglDataA* d) 808 { 809 mgl_data_sub_dat(this, & d); 810 } 811 /// Multiply each element by the number 812 void operator *= (mreal d) 813 { 814 mgl_data_mul_num(this, d); 815 } 816 /// Divide each element by the number 817 void operator /= (mreal d) 818 { 819 mgl_data_div_num(this, d); 820 } 821 /// Add the number 822 void operator += (mreal d) 823 { 824 mgl_data_add_num(this, d); 825 } 826 /// Subtract the number 827 void operator -= (mreal d) 828 { 829 mgl_data_sub_num(this, d); 830 } 831 #ifndef SWIG/// Direct access to the data cell 832 mreal & operator[](long i) 833 { 834 return a[i]; 835 } 836 // NOTE see 13.10 for operator(), operator[] -- m.b. I should add it ??? 837 #endif debug 838 { 839 /// Get the value in given cell of the data 840 mreal v(long i, long j = 0, long k = 0) const 841 { 842 return a[i + nx * (j + ny * k)]; 843 } 844 845 /// set the value in given cell of the data 846 void set_v(mreal val, long i, long j = 0, long k = 0) 847 { 848 a[i + nx * (j + ny * k)] = val; 849 } 850 } 851 else 852 { 853 /// Get the value in given cell of the data with border checking 854 mreal v(long i, long j = 0, long k = 0) const 855 { 856 return mgl_data_get_value(this, i, j, k); 857 } 858 859 /// set the value in given cell of the data 860 void set_v(mreal val, long i, long j = 0, long k = 0) 861 { 862 mgl_data_set_value(this, val, i, j, k); 863 } 864 } 865 */ 866 mreal vthr(long i) const 867 { 868 return a[i]; 869 } 870 871 // add for speeding up !!! 872 mreal dvx(long i, long j = 0, long k = 0) const 873 { 874 long i0 = i + nx * (j + ny * k); 875 return i > 0 ? (i < nx - 1 ? (a[i0 + 1] - a[i0 - 1]) / 2 : a[i0] - a[i0 - 1]) 876 : a[i0 + 1] - a[i0]; 877 } 878 879 mreal dvy(long i, long j = 0, long k = 0) const 880 { 881 long i0 = i + nx * (j + ny * k); 882 return j > 0 ? (j < ny - 1 ? (a[i0 + nx] - a[i0 - nx]) / 2 : a[i0] - a[i0 - nx]) 883 : a[i0 + nx] - a[i0]; 884 } 885 886 mreal dvz(long i, long j = 0, long k = 0) const 887 { 888 long i0 = i + nx * (j + ny * k), n = nx * ny; 889 return k > 0 ? (k < nz - 1 ? (a[i0 + n] - a[i0 - n]) / 2 : a[i0] - a[i0 - n]) 890 : a[i0 + n] - a[i0]; 891 } 892 }; 893 //----------------------------------------------------------------------------- 894 static if (!SWIG) 895 { 896 /* 897 MglData operator * (in MglDataA* b, in MglDataA* d) 898 { 899 MglData a( & b); 900 a *= d; 901 return a; 902 } 903 MglData operator * (mreal b, in MglDataA* d) 904 { 905 MglData a( & d); 906 a *= b; 907 return a; 908 } 909 MglData operator * (in MglDataA* d, mreal b) 910 { 911 MglData a( & d); 912 a *= b; 913 return a; 914 } 915 MglData operator - (in MglDataA* b, in MglDataA* d) 916 { 917 MglData a( & b); 918 a -= d; 919 return a; 920 } 921 MglData operator - (mreal b, in MglDataA* d) 922 { 923 MglData a( & d); 924 a -= b; 925 return a; 926 } 927 MglData operator - (in MglDataA* d, mreal b) 928 { 929 MglData a( & d); 930 a -= b; 931 return a; 932 } 933 MglData operator + (in MglDataA* b, in MglDataA* d) 934 { 935 MglData a( & b); 936 a += d; 937 return a; 938 } 939 MglData operator + (mreal b, in MglDataA* d) 940 { 941 MglData a( & d); 942 a += b; 943 return a; 944 } 945 MglData operator + (in MglDataA* d, mreal b) 946 { 947 MglData a( & d); 948 a += b; 949 return a; 950 } 951 MglData operator / (in MglDataA* b, in MglDataA* d) 952 { 953 MglData a( & b); 954 a /= d; 955 return a; 956 } 957 MglData operator / (in MglDataA* d, mreal b) 958 { 959 MglData a( & d); 960 a /= b; 961 return a; 962 } 963 bool operator == (in MglData* b, in MglData* d) 964 { 965 if (b.nx != d.nx || b.ny != d.ny || b.nz != d.nz) 966 return false; 967 return !memcmp(b.a, d.a, b.nx * b.ny * b.nz * sizeof(mreal)); 968 } 969 bool operator < (in MglDataA* b, in MglDataA* d) 970 { 971 return b.maximal() < d.maximal(); 972 } 973 bool operator > (in MglDataA* b, in MglDataA* d) 974 { 975 return b.minimal() > d.minimal(); 976 } 977 978 */ 979 980 mreal mglLinear(const mreal * a, long nx, long ny, long nz, mreal x, mreal y, mreal z); 981 mreal mglSpline3(const mreal * a, long nx, long ny, long nz, mreal x, mreal y, mreal z, mreal * dx = 0, mreal * dy = 0, mreal * dz = 0); 982 mreal mglSpline3s(const mreal * a, long nx, long ny, long nz, mreal x, mreal y, mreal z); 983 } 984 985 /// Integral data transformation (like Fourier 'f' or 'i', Hankel 'h' or None 'n') for amplitude and phase 986 MglData mglTransformA(in MglDataA* am, in MglDataA* ph, string tr) 987 { 988 return MglData(true, mgl_transform_a( & am, & ph, tr)); 989 } 990 /// Integral data transformation (like Fourier 'f' or 'i', Hankel 'h' or None 'n') for real and imaginary parts 991 MglData mglTransform(in MglDataA* re, in MglDataA* im, string tr) 992 { 993 return MglData(true, mgl_transform( & re, & im, tr)); 994 } 995 996 /// Apply Fourier transform for the data and save result into it 997 void mglFourier(ref MglData re, ref MglData im, string dir) 998 { 999 mgl_data_fourier(re, im, dir); 1000 } 1001 1002 /// Short time Fourier analysis for real and imaginary parts. Output is amplitude of partial Fourier (result will have size {dn, floor(nx/dn), ny} for dir='x' 1003 MglData mglSTFA(ref MglDataA re, ref MglDataA im, long dn, char dir = 'x') 1004 { 1005 return MglData(true, mgl_data_stfa(re,im, dn, dir)); 1006 } 1007 1008 //----------------------------------------------------------------------------- 1009 /// Saves result of PDE solving (|u|^2) for "Hamiltonian" ham with initial conditions ini 1010 MglData mglPDE(HMGL gr, string ham, ref MglDataA* ini_re, 1011 ref MglDataA* ini_im, mreal dz = 0.1, mreal k0 = 100, string opt = "") 1012 { 1013 return MglData(true, mgl_pde_solve(gr, ham, & ini_re, &ini_im, dz, k0, opt)); 1014 } 1015 1016 /// Saves result of PDE solving for "Hamiltonian" ham with initial conditions ini along a curve ray (must have nx>=7 - x,y,z,px,py,pz,tau or nx=5 - x,y,px,py,tau) 1017 MglData mglQO2d(string ham, in MglDataA* ini_re, in MglDataA* ini_im, 1018 in MglDataA* ray, mreal r = 1, mreal k0 = 100) 1019 { 1020 return MglData(true, mgl_qo2d_solve(ham, & ini_re, & ini_im, & ray, r, k0, 0, 1021 0)); 1022 } 1023 1024 MglData mglQO2d(string ham, in MglDataA* ini_re, in MglDataA* ini_im, 1025 in MglDataA* ray, ref MglData xx, ref MglData yy, mreal r = 1, mreal k0 = 100) 1026 { 1027 return MglData(true, mgl_qo2d_solve(ham, & ini_re, & ini_im, & ray, r, k0, & xx, 1028 & yy)); 1029 } 1030 /// Saves result of PDE solving for "Hamiltonian" ham with initial conditions ini along a curve ray (must have nx>=7 - x,y,z,px,py,pz,tau or nx=5 - x,y,px,py,tau) 1031 1032 MglData mglQO3d(string ham, in MglDataA* ini_re, in MglDataA* ini_im, 1033 in MglDataA* ray, mreal r = 1, mreal k0 = 100) 1034 { 1035 return MglData(true, mgl_qo3d_solve(ham, & ini_re, & ini_im, & ray, r, k0, 0, 1036 0, 0)); 1037 } 1038 1039 MglData mglQO3d(string ham, ref MglDataA ini_re, ref MglDataA ini_im, 1040 ref MglDataA ray, ref MglData xx, ref MglData yy, ref MglData zz, mreal r = 1, mreal k0 = 100) 1041 { 1042 return MglData(true, mgl_qo3d_solve(ham, & ini_re, & ini_im, & ray, r, 1043 k0, & xx, & yy, & zz)); 1044 } 1045 /// Finds ray with starting point r0, p0 (and prepares ray data for mglQO2d) 1046 MglData mglRay(string ham, MglPoint r0, MglPoint p0, mreal dt = 0.1, mreal tmax = 10) 1047 { 1048 return MglData(true, mgl_ray_trace(ham, r0.x, r0.y, r0.z, p0.x, p0.y, p0.z, dt, 1049 tmax)); 1050 } 1051 1052 /// Saves result of ODE solving (|u|^2) for "Hamiltonian" ham with initial conditions ini 1053 MglData mglODE(string df, string var, in MglDataA* ini, mreal dt = 0.1, 1054 mreal tmax = 10) 1055 { 1056 return MglData(true, mgl_ode_solve_str(df, var, & ini, dt, tmax)); 1057 } 1058 /// Calculate Jacobian determinant for D{x(u,v), y(u,v)} = dx/du*dy/dv-dx/dv*dy/du 1059 MglData mglJacobian(in MglDataA* x, in MglDataA* y) 1060 { 1061 return MglData(true, mgl_jacobian_2d( & x, & y)); 1062 } 1063 /// Calculate Jacobian determinant for D{x(u,v,w), y(u,v,w), z(u,v,w)} 1064 MglData mglJacobian(in MglDataA* x, in MglDataA* y, in MglDataA* z) 1065 { 1066 return MglData(true, mgl_jacobian_3d( & x, & y, & z)); 1067 } 1068 /// Do something like Delone triangulation 1069 MglData mglTriangulation(in MglDataA* x, in MglDataA* y, in MglDataA* z) 1070 { 1071 return MglData(true, mgl_triangulation_3d( & x, & y, & z)); 1072 } 1073 MglData mglTriangulation(in MglDataA* x, in MglDataA* y) 1074 { 1075 return MglData(true, mgl_triangulation_2d( & x, & y)); 1076 } 1077 //----------------------------------------------------------------------------- 1078 /// Get sub-array of the data with given fixed indexes 1079 MglData mglSubData(in MglDataA* dat, long xx, long yy = - 1, long zz = - 1) 1080 { 1081 return MglData(true, mgl_data_subdata( & dat, xx, yy, zz)); 1082 } 1083 MglData mglSubData(in MglDataA* dat, in MglDataA* xx, in MglDataA* yy, 1084 in MglDataA* zz) 1085 { 1086 return MglData(true, mgl_data_subdata_ext( & dat, & xx, & yy, & zz)); 1087 } 1088 MglData mglSubData(in MglDataA* dat, in MglDataA* xx, in MglDataA* yy) 1089 { 1090 return MglData(true, mgl_data_subdata_ext( & dat, & xx, & yy, 0)); 1091 } 1092 MglData mglSubData(in MglDataA* dat, in MglDataA* xx) 1093 { 1094 return MglData(true, mgl_data_subdata_ext( & dat, & xx, 0, 0)); 1095 } 1096 //----------------------------------------------------------------------------- 1097 /// Prepare coefficients for global spline interpolation 1098 MglData mglGSplineInit(in MglDataA* xdat, in MglDataA* ydat) 1099 { 1100 return MglData(true, mgl_gspline_init(*xdat, & ydat)); 1101 } 1102 /// Evaluate global spline (and its derivatives d1, d2 if not NULL) using prepared coefficients \a coef 1103 mreal mglGSpline(in MglDataA* coef, mreal dx, mreal * d1 = 0, mreal * d2 = 0) 1104 { 1105 return mgl_gspline( & coef, dx, d1, d2); 1106 } 1107 //----------------------------------------------------------------------------- 1108 /// Wrapper class for expression evaluating 1109 class MglExpr 1110 { 1111 HMEX ex; 1112 1113 // copying is not allowed 1114 1115 this(string expr) 1116 { 1117 ex = mgl_create_expr(expr.toStringz); 1118 } 1119 1120 static if(HaveRval) 1121 { 1122 this(MglExpr** d) 1123 { 1124 ex=d.ex; 1125 d.ex = 0; 1126 } 1127 } 1128 1129 ~this() 1130 { 1131 mgl_delete_expr(ex); 1132 } 1133 1134 /// Return value of expression for given x,y,z variables 1135 double eval(double x, double y = 0, double z = 0) 1136 { 1137 return mgl_expr_eval(ex, x, y, z); 1138 } 1139 1140 /// Return value of expression differentiation over variable dir for given x,y,z variables 1141 double diff(char dir, double x, double y = 0, double z = 0) 1142 { 1143 return mgl_expr_diff(ex, dir, x, y, z); 1144 } 1145 1146 static if(!SWIG) 1147 { 1148 // Return value of expression for given variables 1149 double Eval(mreal var[26]) 1150 { 1151 return mgl_expr_eval_v(ex, var); 1152 } 1153 1154 /// Return value of expression differentiation over variable dir for given variables 1155 double Diff(char dir, mreal var[26]) 1156 { 1157 return mgl_expr_diff_v(ex, dir, var); 1158 } 1159 } 1160 } 1161 1162 // Class which presents variable as data array 1163 class MglDataV : MglDataA 1164 { 1165 long nx; ///< number of points in 1st dimensions ('x' dimension) 1166 long ny; ///< number of points in 2nd dimensions ('y' dimension) 1167 long nz; ///< number of points in 3d dimensions ('z' dimension) 1168 mreal di, dj, dk, a0; 1169 1170 this(long xx = 1, long yy = 1, long zz = 1, mreal x1 = 0, mreal x2 = mglNaN, char dir = 'x') 1171 { 1172 this.nx=xx; 1173 this.ny=ny; 1174 this.nz=nz; 1175 fill(x1, x2, dir); 1176 } 1177 1178 this(MglDataV d) 1179 { 1180 this.nx=d.nx; 1181 this.ny=d.ny; 1182 this.nz=d.nz; 1183 this.di=d.di; 1184 this.dj=d.dj; 1185 this.dk=d.dk; 1186 this.a0=d.ao; 1187 } 1188 1189 static if(HaveRval) 1190 { 1191 this(MglDataV d) 1192 { 1193 this.nx=d.nx; 1194 this.ny=d.ny; 1195 this.nz=d.nz; 1196 this.di=d.di; 1197 this.dj=d.dj; 1198 this.dk=d.dk; 1199 this.a0=d.ao; 1200 s = d.s; 1201 temp = d.temp; 1202 func = d.func; 1203 o = d.o; 1204 d.func = 0; 1205 } 1206 } 1207 1208 /// Get sizes 1209 long getNx() const 1210 { 1211 return nx; 1212 } 1213 1214 long getNy() const 1215 { 1216 return ny; 1217 } 1218 1219 long getNz() const 1220 { 1221 return nz; 1222 } 1223 1224 /// create or recreate the array with specified size and fill it by zero 1225 void create(long mx, long my = 1, long mz = 1) 1226 { 1227 di = mx > 1 ? di * (nx - 1) / (mx - 1) : 0; 1228 dj = my > 1 ? dj * (ny - 1) / (my - 1) : 0; 1229 dk = mz > 1 ? dk * (nz - 1) / (mz - 1) : 0; 1230 nx = mx; 1231 ny = my; 1232 nz = mz; 1233 } 1234 1235 /// For going throw all elements 1236 void all() 1237 { 1238 di = dj = dk = 1; 1239 a0 = 0; 1240 } 1241 1242 /// Equidistantly fill the data to range [x1,x2] in direction dir 1243 void fill(mreal x1, mreal x2 = mglNaN, char dir = 'x') 1244 { 1245 di = dj = dk = 0; 1246 a0 = x1; 1247 if (mgl_isnum(x2)) 1248 { 1249 if (dir == 'x' && nx > 1) 1250 di = (x2 - x1) / (nx - 1); 1251 if (dir == 'y' && ny > 1) 1252 dj = (x2 - x1) / (ny - 1); 1253 if (dir == 'z' && nz > 1) 1254 dk = (x2 - x1) / (nz - 1); 1255 } 1256 } 1257 1258 mreal maximal() const 1259 { 1260 return a0 + mgl_max(mgl_max(di * (nx - 1), dj * (ny - 1)), mgl_max(dk * (nz - 1), 1261 0)); 1262 } 1263 1264 mreal minimal() const 1265 { 1266 return a0 + mgl_min(mgl_min(di * (nx - 1), dj * (ny - 1)), mgl_min(dk * (nz - 1), 1267 0)); 1268 } 1269 1270 /* 1271 /// Copy data from other MglDataV variable 1272 const MglDataV & operator = (const MglDataV & d) 1273 { 1274 nx = d.nx; 1275 ny = d.ny; 1276 nz = d.nz; 1277 a0 = d.a0; 1278 di = d.di; 1279 dj = d.dj; 1280 dk = d.dk; 1281 return d; 1282 } 1283 mreal operator = (mreal val) 1284 { 1285 di = dj = dk = 0; 1286 a0 = val; 1287 return val; 1288 } 1289 */ 1290 1291 /// Get the value in given cell of the data without border checking 1292 mreal value(mreal x, mreal y, mreal z, mreal * dx = 0, mreal * dy = 0, mreal * dz = 0) const 1293 { 1294 if (dx) 1295 * dx = di; 1296 if (dy) 1297 * dy = dj; 1298 if (dz) 1299 * dz = dk; 1300 return a0 + di * x + dj * y + dk * z; 1301 } 1302 mreal v(long i, long j = 0, long k = 0) const 1303 { 1304 return a0 + di * i + dj * j + dk * k; 1305 } 1306 1307 mreal vthr(long ii) const 1308 { 1309 long i = ii % nx, j = (ii / nx) % ny, k = ii / (nx * ny); 1310 return a0 + di * i + dj * j + dk * k; 1311 } 1312 1313 // add for speeding up !!! 1314 mreal dvx(long, long = 0, long = 0) const 1315 { 1316 return di; 1317 } 1318 1319 mreal dvy(long, long = 0, long = 0) const 1320 { 1321 return dj; 1322 } 1323 1324 mreal dvz(long, long = 0, long = 0) const 1325 { 1326 return dk; 1327 } 1328 }; 1329 //----------------------------------------------------------------------------- 1330 /// Class which present FFT frequency as data array 1331 class MglDataW : MglDataA 1332 { 1333 long nx; ///< number of points in 1st dimensions ('x' dimension) 1334 long ny; ///< number of points in 2nd dimensions ('y' dimension) 1335 long nz; ///< number of points in 3d dimensions ('z' dimension) 1336 mreal di, dj, dk; 1337 1338 this(long xx = 1, long yy = 1, long zz = 1, mreal dp = 0, char dir = 'x') 1339 { 1340 this.nx=xx; 1341 this.ny=yy; 1342 this.nz=zz; 1343 freq(dp, dir); 1344 } 1345 1346 this(const MglDataW d) 1347 { 1348 this.nx=d.nx; 1349 this.ny=d.ny; 1350 this.nz=d.nz; 1351 this.di=d.di; 1352 this.dj=d.dj; 1353 this.dk=d.dk; 1354 } 1355 1356 static if (HaveRval) 1357 { 1358 this(MglDataW* d) 1359 { 1360 this.nx=d.nx; 1361 this.ny=d.ny; 1362 this.nz=d.nz; 1363 this.di=d.di; 1364 this.dj=d.dj; 1365 this.dk=d.dk; 1366 s = d.s; 1367 temp = d.temp; 1368 func = d.func; 1369 o = d.o; 1370 d.func = 0; 1371 } 1372 } 1373 1374 /// Get sizes 1375 long getNx() const 1376 { 1377 return nx; 1378 } 1379 1380 long getNy() const 1381 { 1382 return ny; 1383 } 1384 1385 long getNz() const 1386 { 1387 return nz; 1388 } 1389 1390 /// create or recreate the array with specified size and fill it by zero 1391 void create(long mx, long my = 1, long mz = 1) 1392 { 1393 nx = mx; 1394 ny = my; 1395 nz = mz; 1396 } 1397 1398 /// For going throw all elements 1399 void all() 1400 { 1401 di = dj = dk = 1; 1402 } 1403 1404 /// Equidistantly fill the data to range [x1,x2] in direction dir 1405 void Freq(mreal dp, char dir = 'x') 1406 { 1407 di = dj = dk = 0; 1408 if (dir == 'x') 1409 di = dp; 1410 if (dir == 'y') 1411 dj = dp; 1412 if (dir == 'z') 1413 dk = dp; 1414 } 1415 1416 mreal maximal() const 1417 { 1418 return mgl_max(mgl_max(di * (nx - 1), dj * (ny - 1)), mgl_max(dk * (nz - 1), 1419 0)); 1420 } 1421 1422 mreal minimal() const 1423 { 1424 return mgl_min(mgl_min(di * (nx - 1), dj * (ny - 1)), mgl_min(dk * (nz - 1), 1425 0)); 1426 } 1427 /* 1428 /// Copy data from other MglDataV variable 1429 const MglDataW & operator = (const MglDataW & d) 1430 { 1431 nx = d.nx; 1432 ny = d.ny; 1433 nz = d.nz; 1434 di = d.di; 1435 dj = d.dj; 1436 dk = d.dk; 1437 return d; 1438 } 1439 */ 1440 /// Get the value in given cell of the data without border checking 1441 mreal value(mreal x, mreal y, mreal z, mreal* dx = 0, mreal* dy = 0, mreal* dz = 0) const 1442 { 1443 if (dx) 1444 *dx = di; 1445 if (dy) 1446 *dy = dj; 1447 if (dz) 1448 *dz = dk; 1449 return di * (x < nx / 2 ? x : nx - x) + dj * (y < ny / 2 ? y : ny - y) + dk * ( 1450 z < nz / 2 ? z : nz - z); 1451 } 1452 1453 mreal v(long i, long j = 0, long k = 0) const 1454 { 1455 return di * (i < nx / 2 ? i : nx - i) + dj * (j < ny / 2 ? j : ny - j) + dk * ( 1456 k < nz / 2 ? k : nz - k); 1457 } 1458 1459 mreal vthr(long ii) const 1460 { 1461 long i = ii % nx, j = (ii / nx) % ny, k = ii / (nx * ny); 1462 return di * (i < nx / 2 ? i : nx - i) + dj * (j < ny / 2 ? j : ny - j) + dk * ( 1463 k < nz / 2 ? k : nz - k); 1464 } 1465 1466 // add for speeding up !!! 1467 mreal dvx(long, long = 0, long = 0) const 1468 { 1469 return di; 1470 } 1471 1472 mreal dvy(long, long = 0, long = 0) const 1473 { 1474 return dj; 1475 } 1476 1477 mreal dvz(long, long = 0, long = 0) const 1478 { 1479 return dk; 1480 } 1481 } 1482 1483 // Class which presents variable as data array 1484 class MglDataF : MglDataA 1485 { 1486 long nx; ///< number of points in 1st dimensions ('x' dimension) 1487 long ny; ///< number of points in 2nd dimensions ('y' dimension) 1488 long nz; ///< number of points in 3d dimensions ('z' dimension) 1489 string str; ///< function as string 1490 MglPoint v1, v2; ///< ranges for coordinates 1491 HMEX ex; ///< parsed variant 1492 mreal dx, dy, dz; 1493 void setD() 1494 { 1495 dx = nx > 1 ? (v2.x - v1.x) / (nx - 1) : 0; 1496 dy = ny > 1 ? (v2.y - v1.y) / (ny - 1) : 0; 1497 dz = nz > 1 ? (v2.z - v1.z) / (nz - 1) : 0; 1498 } 1499 1500 mreal function(mreal i, mreal j, mreal k, void * par) func; 1501 void* par; 1502 1503 this(long xx = 1, long yy = 1, long zz = 1) 1504 { 1505 this.nx=xx; 1506 this.ny=yy; 1507 this.nz=zz; 1508 this.dfunc=0; 1509 this.par=0; 1510 ex = 0; 1511 v2 = MglPoint(1, 1, 1); 1512 setD(); 1513 } 1514 1515 this(MglDataF d) 1516 { 1517 this.nx=d.nx; 1518 this.ny=d.ny; 1519 this.nz=d.nz; 1520 this.str=d.str; 1521 this.v1=d.v1; 1522 this.v2=d.v2; 1523 this.dx=d.dx; 1524 this.dy=d.dy; 1525 this.dz=d.dz; 1526 this.dfunc=d.dfunc; 1527 this.par=d.par; 1528 ex = mgl_create_expr(str.c_str()); 1529 } 1530 1531 static if(HaveRval) 1532 { 1533 this(MglDataF d) 1534 { 1535 this.nx=d.nx; 1536 this.ny=d.ny; 1537 this.nz=d.nz; 1538 this.str=d.str; 1539 this.v1=d.v1; 1540 this.v2=d.v2; 1541 this.dx=d.dx; 1542 this.dy=d.dy; 1543 this.dz=d.dz; 1544 this.dfunc=d.dfunc; 1545 this.par=d.par; 1546 s = d.s; 1547 temp = d.temp; 1548 func = d.func; 1549 o = d.o; 1550 d.ex = 0; 1551 d.func = 0; 1552 } 1553 } 1554 1555 ~this() 1556 { 1557 mgl_delete_expr(ex); 1558 } 1559 1560 /// Get sizes 1561 long getNx() const 1562 { 1563 return nx; 1564 } 1565 1566 long getNy() const 1567 { 1568 return ny; 1569 } 1570 1571 long getNz() const 1572 { 1573 return nz; 1574 } 1575 1576 /// create or recreate the array with specified size and fill it by zero 1577 void create(long mx, long my = 1, long mz = 1) 1578 { 1579 nx = mx; 1580 ny = my; 1581 nz = mz; 1582 setD(); 1583 } 1584 1585 void setRanges(MglPoint p1, MglPoint p2) 1586 { 1587 v1 = p1; 1588 v2 = p2; 1589 setD(); 1590 } 1591 1592 /// set formula to be used as dfunction 1593 void setFormula(string eq) 1594 { 1595 mgl_delete_expr(ex); 1596 dfunc = 0; 1597 par = 0; 1598 if (eq && *eq) 1599 { 1600 ex = mgl_create_expr(eq); 1601 str = eq; 1602 } 1603 else 1604 { 1605 ex = 0; 1606 str = ""; 1607 } 1608 } 1609 1610 /// set dfunction and coordinates range [r1,r2] 1611 void setFunc(mreal function(mreal, mreal, mreal, void * ) f, void * p = NULL) 1612 { 1613 mgl_delete_expr(ex); 1614 ex = 0; 1615 dfunc = f; 1616 par = p; 1617 } 1618 1619 mreal value(mreal i, mreal j = 0, mreal k = 0, mreal* di = 0, mreal* dj = 0, mreal* dk = 0) const 1620 { 1621 mreal res = 0, x = v1.x + dx * i, y = v1.y + dy * j, z = v1.z + dz * k; 1622 if (di) 1623 *di = 0; 1624 if (dj) 1625 *dj = 0; 1626 if (dk) 1627 *dk = 0; 1628 if (dfunc) 1629 { 1630 res = dfunc(x, y, z, par); 1631 if (di) 1632 *di = dfunc(x + dx, y, z, par) - res; 1633 if (dj) 1634 *dj = dfunc(x, y + dy, z, par) - res; 1635 if (dk) 1636 *dk = dfunc(x, y, z + dz, par) - res; 1637 } 1638 else if (ex) 1639 { 1640 if (di) 1641 *di = mgl_expr_diff(ex, 'x', x, y, z) * dx; 1642 if (dj) 1643 *dj = mgl_expr_diff(ex, 'y', x, y, z) * dy; 1644 if (dk) 1645 *dk = mgl_expr_diff(ex, 'z', x, y, z) * dz; 1646 res = mgl_expr_eval(ex, x, y, z); 1647 } 1648 return res; 1649 } 1650 /* 1651 /// Copy data from other MglDataV variable 1652 const MglDataF & operator = (const MglDataF & d) 1653 { 1654 nx = d.nx; 1655 ny = d.ny; 1656 nz = d.nz; 1657 v1 = d.v1; 1658 v2 = d.v2; 1659 setD(); 1660 str = d.str; 1661 ex = mgl_create_expr(str.c_str()); 1662 dfunc = d.dfunc; 1663 par = d.par; 1664 return d; 1665 } 1666 */ 1667 /// Get the value in given cell of the data without border checking 1668 mreal v(long i, long j = 0, long k = 0) const 1669 { 1670 mreal res = 0, x = v1.x + dx * i, y = v1.y + dy * j, z = v1.z + dz * k; 1671 if (dfunc) 1672 res = dfunc(x, y, z, par); 1673 else if (ex) 1674 res = mgl_expr_eval(ex, x, y, z); 1675 return res; 1676 } 1677 1678 mreal vthr(long i) const 1679 { 1680 mreal res = 0, x = v1.x + dx * (i % nx), y = v1.y + dy * ((i / nx) % ny), 1681 z = v1.z + dz * (i / (nx * ny)); 1682 if (dfunc) 1683 res = dfunc(x, y, z, par); 1684 else if (ex) 1685 res = mgl_expr_eval(ex, x, y, z); 1686 return res; 1687 } 1688 1689 // add for speeding up !!! 1690 mreal dvx(long i, long j = 0, long k = 0) const 1691 { 1692 mreal res = 0, x = v1.x + dx * i, y = v1.y + dy * j, z = v1.z + dz * k; 1693 if (dfunc) 1694 res = dfunc(x + dx, y, z, par) - dfunc(x, y, z, par); 1695 else if (ex) 1696 res = mgl_expr_eval(ex, x + dx, y, z) - mgl_expr_eval(ex, x, y, z); 1697 return res; 1698 } 1699 1700 mreal dvy(long i, long j = 0, long k = 0) const 1701 { 1702 mreal res = 0, x = v1.x + dx * i, y = v1.y + dy * j, z = v1.z + dz * k; 1703 if (dfunc) 1704 res = dfunc(x, y + dy, z, par) - dfunc(x, y, z, par); 1705 else if (ex) 1706 res = mgl_expr_eval(ex, x, y + dy, z) - mgl_expr_eval(ex, x, y, z); 1707 return res; 1708 } 1709 1710 mreal dvz(long i, long j = 0, long k = 0) const 1711 { 1712 mreal res = 0, x = v1.x + dx * i, y = v1.y + dy * j, z = v1.z + dz * k; 1713 if (dfunc) 1714 res = dfunc(x, y, z + dz, par) - dfunc(x, y, z, par); 1715 else if (ex) 1716 res = mgl_expr_eval(ex, x, y, z + dz) - mgl_expr_eval(ex, x, y, z); 1717 return res; 1718 } 1719 } 1720 1721 // Class which present variable as data array 1722 class MglDataT : MglDataA 1723 { 1724 MglDataA* dat; 1725 long ind; 1726 1727 this(const MglDataT d) 1728 { 1729 this.dat=d.dat; 1730 this.ind=d.ind; 1731 s = d.s; 1732 } 1733 1734 this(in MglDataA* d, long col = 0) 1735 { 1736 this.dat=d; 1737 this.ind=col; 1738 } 1739 1740 static if(HaveRval) 1741 { 1742 this(MglDataT* d) 1743 { 1744 this.dat=d.dat; 1745 this.ind=d.ind; 1746 s = d.s; 1747 temp = d.temp; 1748 func = d.func; 1749 o = d.o; 1750 d.func = 0; 1751 } 1752 } 1753 1754 ~this() 1755 { 1756 } 1757 1758 /// Get sizes 1759 long getNx() const 1760 { 1761 return dat.getNy(); 1762 } 1763 1764 long getNy() const 1765 { 1766 return dat.getNz(); 1767 } 1768 1769 long getNz() const 1770 { 1771 return 1; 1772 } 1773 1774 mreal maximal() const 1775 { 1776 return mglSubData(dat, ind).maximal(); 1777 } 1778 1779 mreal minimal() const 1780 { 1781 return mglSubData(dat, ind).minimal(); 1782 } 1783 1784 void setInd(long i, const wchar_t* name) 1785 { 1786 ind = i; 1787 s = name; 1788 } 1789 1790 void setInd(long i, wchar_t name) 1791 { 1792 ind = i; 1793 s = name; 1794 } 1795 1796 /// Get the value in given cell of the data without border checking 1797 mreal v(long i, long j = 0, long = 0) const 1798 { 1799 return dat.v(ind, i, j); 1800 } 1801 1802 mreal vthr(long i) const 1803 { 1804 return dat.vthr(ind + dat.getNx() * i); 1805 } 1806 1807 // add for speeding up !!! 1808 mreal dvx(long i, long j = 0, long = 0) const 1809 { 1810 return dat.dvy(ind, i, j); 1811 } 1812 1813 mreal dvy(long i, long j = 0, long = 0) const 1814 { 1815 return dat.dvz(ind, i, j); 1816 } 1817 1818 mreal dvz(long, long = 0, long = 0) const 1819 { 1820 return 0; 1821 } 1822 } 1823 1824 class MglDataR : MglDataA 1825 { 1826 MglDataA* dat; 1827 long ind; 1828 1829 this(const MglDataR d) 1830 { 1831 this.dat=d.dat; 1832 this.ind=d.ind; 1833 s=d.s; 1834 } 1835 1836 this(in MglDataA d, long row = 0) 1837 { 1838 this.dat=d; 1839 this.ind=row; 1840 } 1841 1842 static if(HaveRval) 1843 { 1844 this(MglDataR* d) 1845 { 1846 this.dat=d.dat; 1847 this.ind=d.ind; 1848 s = d.s; 1849 temp = d.temp; 1850 func = d.func; 1851 o = d.o; 1852 d.func = 0; 1853 } 1854 } 1855 ~this() 1856 { 1857 1858 } 1859 1860 /// Get sizes 1861 long getNx() const 1862 { 1863 return dat.getNx(); 1864 } 1865 1866 long getNy() const 1867 { 1868 return 1; 1869 } 1870 1871 long getNz() const 1872 { 1873 return 1; 1874 } 1875 1876 mreal maximal() const 1877 { 1878 return mglSubData(dat, -1, ind).maximal(); 1879 } 1880 1881 mreal minimal() const 1882 { 1883 return mglSubData(dat, -1, ind).minimal(); 1884 } 1885 1886 void setInd(long i, const wchar_t* name) 1887 { 1888 ind = i; 1889 s = name; 1890 } 1891 1892 void setInd(long i, wchar_t name) 1893 { 1894 ind = i; 1895 s = name; 1896 } 1897 1898 /// Get the value in given cell of the data without border checking 1899 mreal v(long i, long j= 0, long k= 0) const 1900 { 1901 return dat.v(i, ind, 0); 1902 } 1903 1904 mreal vthr(long i) const 1905 { 1906 return dat.vthr(i + dat.getNx() * ind); 1907 } 1908 1909 // add for speeding up !!! 1910 mreal dvx(long i, long j = 0, long k= 0) const 1911 { 1912 return dat.dvx(i, ind, 0); 1913 } 1914 1915 mreal dvy(long i, long j = 0, long k= 0) const 1916 { 1917 return 0; 1918 } 1919 1920 mreal dvz(long i, long j= 0, long k = 0) const 1921 { 1922 return 0; 1923 } 1924 } 1925 1926 1927 auto mgl2() 1928 { 1929 return mreal(2); 1930 } 1931 1932 auto mgl3() 1933 { 1934 return mreal(3); 1935 } 1936 1937 auto mgl4() 1938 { 1939 return mreal(4); 1940 } 1941 1942 1943 /// Class for working with complex data array 1944 class MglDataC:MglDataA 1945 { 1946 //public : using MglDataA : : Momentum; 1947 long nx; ///< number of points in 1st dimensions ('x' dimension) 1948 long ny; ///< number of points in 2nd dimensions ('y' dimension) 1949 long nz; ///< number of points in 3d dimensions ('z' dimension) 1950 dual* a; ///< data array 1951 string id; ///< column (or slice) names 1952 bool useLink; ///< use external data (i.e. don't free it) 1953 1954 /// Initiate by other MglDataC variable 1955 this(in MglDataC* d) 1956 { 1957 a = 0; 1958 mgl_datac_set(this, & d); 1959 } // NOTE: must be constructor for MglDataC& to exclude copy one 1960 1961 this(in MglDataA* d) 1962 { 1963 a = 0; 1964 mgl_datac_set(this, & d); 1965 } 1966 1967 static if(HaveRval) 1968 { 1969 this(MglDataC** d) 1970 { 1971 this.nx=d.nx; 1972 this.ny=d.ny; 1973 this.nz=d.nz; 1974 this.a=d.a; 1975 this.id=d.id; 1976 this.useLink=d.useLink; 1977 //this.s = d.s; 1978 //this.temp = d.temp; 1979 func = d.func; 1980 //this.o = d.o; 1981 d.a = 0; 1982 d.func = 0; 1983 } 1984 } 1985 1986 this(in MglDataA* re, in MglDataA* im) 1987 { 1988 a = 0; 1989 mgl_datac_set_ri(this, & re, *im); 1990 } 1991 1992 this(HCDT d) 1993 { 1994 a = 0; 1995 mgl_datac_set(this, d); 1996 } 1997 1998 this(HCDT re, HCDT im) 1999 { 2000 a = 0; 2001 mgl_datac_set_ri(this, re, im); 2002 } 2003 2004 this(bool, MglDataC * d) // NOTE: Variable d will be deleted!!! 2005 { 2006 if (d) 2007 { 2008 nx = d.nx; 2009 ny = d.ny; 2010 nz = d.nz; 2011 a = d.a; 2012 d.a = 0; 2013 temp = d.temp; 2014 func = d.func; 2015 o = d.o; 2016 s = d.s; 2017 id = d.id; 2018 useLink = d.useLink; 2019 delete d; 2020 } 2021 else 2022 { 2023 a = 0; 2024 Create(1); 2025 } 2026 } 2027 2028 /// Initiate by flat array 2029 this(int size, const dual * d) 2030 { 2031 a = 0; 2032 set(d, size); 2033 } 2034 this(int rows, int cols, const dual * d) 2035 { 2036 a = 0; 2037 set(d, cols, rows); 2038 } 2039 this(int size, const double * d) 2040 { 2041 a = 0; 2042 set(d, size); 2043 } 2044 this(int rows, int cols, const double * d) 2045 { 2046 a = 0; 2047 set(d, cols, rows); 2048 } 2049 this(int size, const float * d) 2050 { 2051 a = 0; 2052 set(d, size); 2053 } 2054 this(int rows, int cols, const float * d) 2055 { 2056 a = 0; 2057 set(d, cols, rows); 2058 } 2059 this(in dual * d, int size) 2060 { 2061 a = 0; 2062 set(d, size); 2063 } 2064 this(in dual * d, int rows, int cols) 2065 { 2066 a = 0; 2067 set(d, cols, rows); 2068 } 2069 this(in double * d, int size) 2070 { 2071 a = 0; 2072 set(d, size); 2073 } 2074 this(in double * d, int rows, int cols) 2075 { 2076 a = 0; 2077 set(d, cols, rows); 2078 } 2079 this(in float * d, int size) 2080 { 2081 a = 0; 2082 set(d, size); 2083 } 2084 this(in float * d, int rows, int cols) 2085 { 2086 a = 0; 2087 set(d, cols, rows); 2088 } 2089 /// read data from file 2090 this(string fname) 2091 { 2092 a = 0; 2093 read(fname); 2094 } 2095 /// Allocate the memory for data array and initialize it zero 2096 this(long xx = 1, long yy = 1, long zz = 1) 2097 { 2098 a = 0; 2099 Create(xx, yy, zz); 2100 } 2101 /// Delete the array 2102 ~this() 2103 { 2104 //if (!useLink && a) 2105 // delete[] a; 2106 } 2107 2108 dual getVal(long i, long j = 0, long k = 0) const 2109 { 2110 return mgl_datac_get_value(this, i, j, k); 2111 } 2112 2113 void setVal(dual f, long i, long j = 0, long k = 0) 2114 { 2115 mgl_datac_set_value(this, f, i, j, k); 2116 } 2117 2118 /// get sizes 2119 long getNx() const 2120 { 2121 return nx; 2122 } 2123 2124 long getNy() const 2125 { 2126 return ny; 2127 } 2128 2129 long getNz() const 2130 { 2131 return nz; 2132 } 2133 2134 /// Link external data array (don't delete it at exit) 2135 void link(dual* A, long NX, long NY = 1, long NZ = 1) 2136 { 2137 mgl_datac_link(this, A, NX, NY, NZ); 2138 } 2139 2140 void link(MglDataC* d) 2141 { 2142 Link(d.a, d.nx, d.ny, d.nz); 2143 } 2144 /// Allocate memory and copy the data from the gsl_vector 2145 void set(gsl_vector* m) 2146 { 2147 mgl_datac_set_vector(this, m); 2148 } 2149 2150 /// Allocate memory and copy the data from the gsl_matrix 2151 void set(gsl_matrix* m) 2152 { 2153 mgl_datac_set_matrix(this, m); 2154 } 2155 2156 /// Allocate memory and copy the data from the (float *) array 2157 void set(const float* A, long NX, long NY = 1, long NZ = 1) 2158 { 2159 mgl_datac_set_float(this, A, NX, NY, NZ); 2160 } 2161 2162 /// Allocate memory and copy the data from the (double *) array 2163 void set(const double* A, long NX, long NY = 1, long NZ = 1) 2164 { 2165 mgl_datac_set_double(this, A, NX, NY, NZ); 2166 } 2167 2168 /// Allocate memory and copy the data from the (complex *) array 2169 void set(const dual* A, long NX, long NY = 1, long NZ = 1) 2170 { 2171 mgl_datac_set_complex(this, A, NX, NY, NZ); 2172 } 2173 2174 /// Allocate memory and scanf the data from the string 2175 void set(string str, long NX, long NY = 1, long NZ = 1) 2176 { 2177 mgl_datac_set_values(this, str.toStringz, NX, NY, NZ); 2178 } 2179 2180 /// Import data from abstract type 2181 void set(HCDT dat) 2182 { 2183 mgl_datac_set(this, dat); 2184 } 2185 2186 void set(in MglDataA* dat) 2187 { 2188 mgl_datac_set(this, & dat); 2189 } 2190 void set(in MglDataA* re, in MglDataA* im) 2191 { 2192 mgl_datac_set_ri(this, & re, & im); 2193 } 2194 void set(HCDT re, HCDT im) 2195 { 2196 mgl_datac_set_ri(this, re, im); 2197 } 2198 2199 void setAmpl(in MglDataA* ampl, in MglDataA* phase) 2200 { 2201 mgl_datac_set_ap(this, & ampl, & phase); 2202 } 2203 /// Allocate memory and copy data from std::vector<T> 2204 void set(int[] d) 2205 { 2206 if (d.length < 1) 2207 return; 2208 Create(d.length()); 2209 foreach(i;0..nx) 2210 a[i] = d[i]; 2211 } 2212 void set(float[] d) 2213 { 2214 if (d.length < 1) 2215 return; 2216 create(d.length()); 2217 foreach(i;0..nx) 2218 a[i] = d[i]; 2219 } 2220 void set(double[] d) 2221 { 2222 if (d.length() < 1) 2223 return; 2224 Create(d.length); 2225 foreach(i;0..nx) 2226 a[i] = d[i]; 2227 } 2228 2229 void set(dual[] d) 2230 { 2231 if (d.length() < 1) 2232 return; 2233 create(d.length); 2234 foreach(i;0..nx) 2235 a[i] = d[i]; 2236 } 2237 2238 /// Create or recreate the array with specified size and fill it by zero 2239 void create(long mx, long my = 1, long mz = 1) 2240 { 2241 mgl_datac_create(this, mx, my, mz); 2242 } 2243 2244 /// Rearange data dimensions 2245 void rearrange(long mx, long my = 0, long mz = 0) 2246 { 2247 mgl_datac_rearrange(this, mx, my, mz); 2248 } 2249 2250 /// Transpose dimensions of the data (generalization of Transpose) 2251 void transpose(string dim = "yx") 2252 { 2253 mgl_datac_transpose(this, dim.toStringz); 2254 } 2255 2256 /// Extend data dimensions 2257 void extend(long n1, long n2 = 0) 2258 { 2259 mgl_datac_extend(this, n1, n2); 2260 } 2261 2262 /// Reduce size of the data 2263 void squeeze(long rx, long ry = 1, long rz = 1, bool smooth = false) 2264 { 2265 mgl_datac_squeeze(this, rx, ry, rz, smooth); 2266 } 2267 2268 /// Crop the data 2269 void crop(long n1, long n2, char dir = 'x') 2270 { 2271 mgl_datac_crop(this, n1, n2, dir); 2272 } 2273 2274 /// Insert data 2275 void insert(char dir, long at = 0, long num = 1) 2276 { 2277 mgl_datac_insert(this, dir, at, num); 2278 } 2279 2280 /// Delete data 2281 void deleteData(char dir, long at = 0, long num = 1) 2282 { 2283 mgl_datac_delete(this, dir, at, num); 2284 } 2285 2286 /// Join with another data array 2287 void join(in MglDataA* d) 2288 { 2289 mgl_datac_join(this, & d); 2290 } 2291 2292 /// Modify the data by specified formula 2293 void modify(string eq, long dim = 0) 2294 { 2295 mgl_datac_modify(this, eq, dim); 2296 } 2297 2298 /// Modify the data by specified formula 2299 void modify(const char * eq, in MglDataA* vdat, in MglDataA* wdat) 2300 { 2301 mgl_datac_modify_vw(this, eq, & vdat, & wdat); 2302 } 2303 /// Modify the data by specified formula 2304 void modify(const char * eq, in MglDataA* vdat) 2305 { 2306 mgl_datac_modify_vw(this, eq, & vdat, 0); 2307 } 2308 /// Modify the data by specified formula assuming x,y,z in range [r1,r2] 2309 void fill(mglBase* gr, string eq, string opt = "") 2310 { 2311 mgl_datac_fill_eq(gr, this, eq, 0, 0, opt); 2312 } 2313 2314 void fill(mglBase * gr, const char * eq, in MglDataA* vdat, string opt = "") 2315 { 2316 mgl_datac_fill_eq(gr, this, eq, & vdat, 0, opt.toStringz); 2317 } 2318 2319 void Fill(mglBase * gr, const char * eq, in MglDataA* vdat, in MglDataA* wdat,string opt = "") 2320 { 2321 mgl_datac_fill_eq(gr, this, eq, & vdat, & wdat, opt.toStringz); 2322 } 2323 /// Equidistantly fill the data to range [x1,x2] in direction dir 2324 void fill(dual x1, dual x2 = mglNaN, char dir = 'x') 2325 { 2326 mgl_datac_fill(this, x1, x2, dir); 2327 } 2328 2329 /// Put value to data element(s) 2330 void put(dual val, long i = -1, long j = -1, long k = -1) 2331 { 2332 mgl_datac_put_val(this, val, i, j, k); 2333 } 2334 2335 /// Put array to data element(s) 2336 void put(in MglDataA* dat, long i = - 1, long j = - 1, long k = - 1) 2337 { 2338 mgl_datac_put_dat(this, & dat, i, j, k); 2339 } 2340 2341 /// set names for columns (slices) 2342 void setColumnId(string ids) 2343 { 2344 mgl_datac_set_id(this, ids); 2345 } 2346 2347 /// Make new id 2348 void newId() 2349 { 2350 id.clear(); 2351 } 2352 2353 /// read data from tab-separated text file with auto determining size 2354 bool read(string fname) 2355 { 2356 return mgl_datac_read(this, fname.toStringz); 2357 } 2358 2359 /// read data from text file with specifeid size 2360 bool read(string fname, long mx, long my = 1, long mz = 1) 2361 { 2362 return mgl_datac_read_dim(this, fname.toStringz, mx, my, mz); 2363 } 2364 2365 /// save whole data array (for ns=-1) or only ns-th slice to text file 2366 void save(string fname, long ns = -1) const 2367 { 2368 mgl_datac_save(this, fname.toStringz, ns); 2369 } 2370 2371 /// read data from tab-separated text files with auto determining size which filenames are result of sprintf(fname,templ,t) where t=from:step:to 2372 bool readRange(string templ, double from, double to, 2373 double step = 1, bool as_slice = false) 2374 { 2375 return mgl_datac_read_range(this, templ.toStringz, from, to, step, as_slice); 2376 } 2377 2378 /// read data from tab-separated text files with auto determining size which filenames are satisfied to template (like "t_*.dat") 2379 bool readAll(string templ, bool as_slice = false) 2380 { 2381 return mgl_datac_read_all(this, templ.toStringz, as_slice); 2382 } 2383 2384 /// read data from text file with size specified at beginning of the file 2385 bool readMat(string fname, long dim = 2) 2386 { 2387 return mgl_datac_read_mat(this, fname.toStringz, dim); 2388 } 2389 2390 /// read data array from HDF file (parse HDF4 and HDF5 files) 2391 int readHDF(string fname, ubyte[] data) 2392 { 2393 return mgl_datac_read_hdf(this, fname, data.ptr); 2394 } 2395 2396 /// save data to HDF file 2397 void saveHDF(string fname, ubyte[] data, bool rewrite = false) const 2398 { 2399 mgl_datac_save_hdf(this, fname, data.ptr, rewrite); 2400 } 2401 2402 /// get real part of data values 2403 MglData getReal() const 2404 { 2405 return MglData(true, mgl_datac_real(this)); 2406 } 2407 /// get imaginary part of data values 2408 MglData getImag() const 2409 { 2410 return MglData(true, mgl_datac_imag(this)); 2411 } 2412 /// get absolute value of data values 2413 MglData getAbs() const 2414 { 2415 return MglData(true, mgl_datac_abs(this)); 2416 } 2417 /// get argument of data values 2418 MglData getArg() const 2419 { 2420 return MglData(true, mgl_datac_arg(this)); 2421 } 2422 2423 /// get column (or slice) of the data filled by formulas of named columns 2424 MglDataC getColumn(string eq) const 2425 { 2426 return MglDataC(true, mgl_datac_column(this, eq.toStringz)); 2427 } 2428 2429 /// get momentum (1D-array) of data along direction 'dir'. String looks like "x1" for median in x-direction, "x2" for width in x-dir and so on. 2430 MglDataC getMomentum(char dir, string how) const 2431 { 2432 return MglDataC(true, mgl_datac_momentum(this, dir, how.toStringz)); 2433 } 2434 /// get sub-array of the data with given fixed indexes 2435 MglDataC subData(long xx, long yy = - 1, long zz = - 1) const 2436 { 2437 return MglDataC(true, mgl_datac_subdata(this, xx, yy, zz)); 2438 } 2439 MglDataC subData(in MglDataA* xx, in MglDataA* yy, in MglDataA* zz) const 2440 { 2441 return MglDataC(true, mgl_datac_subdata_ext(this, & xx, & yy, & zz)); 2442 } 2443 MglDataC subData(in MglDataA* xx, in MglDataA* yy) const 2444 { 2445 return MglDataC(true, mgl_datac_subdata_ext(this, & xx, & yy, 0)); 2446 } 2447 MglDataC subData(in MglDataA* xx) const 2448 { 2449 return MglDataC(true, mgl_datac_subdata_ext(this, & xx, 0, 0)); 2450 } 2451 /// get trace of the data array 2452 MglDataC trace() const 2453 { 2454 return MglDataC(true, mgl_datac_trace(this)); 2455 } 2456 /// get array which is result of summation in given direction or directions 2457 MglDataC sum(string dir) const 2458 { 2459 return MglDataC(true, mgl_datac_sum(this, dir.toStringz)); 2460 } 2461 /// get the data which is direct multiplication (like, d[i,j] = this[i]*a[j] and so on) 2462 MglDataC combine(in MglDataA* dat) const 2463 { 2464 return MglDataC(true, mgl_datac_combine(this, & dat)); 2465 } 2466 /// Resize the data to new size of box [x1,x2]*[y1,y2]*[z1,z2] 2467 MglDataC resize(long mx, long my = 1, long mz = 1, mreal x1 = 0, 2468 mreal x2 = 1, mreal y1 = 0, mreal y2 = 1, mreal z1 = 0, mreal z2 = 1) const 2469 { 2470 return MglDataC(true, mgl_datac_resize_box(this, mx, my, mz, x1, x2, y1, y2, 2471 z1, z2)); 2472 } 2473 /// get array which values is result of interpolation this for coordinates from other arrays 2474 MglDataC evaluate(const MglData* idat, bool norm = true) const 2475 { 2476 return MglDataC(true, mgl_datac_evaluate(this, & idat, 0, 0, norm)); 2477 } 2478 MglDataC evaluate(const MglData* idat, const MglData* jdat, bool norm = true) const 2479 { 2480 return MglDataC(true, mgl_datac_evaluate(this, & idat, & jdat, 0, norm)); 2481 } 2482 MglDataC evaluate(const MglData* idat, const MglData* jdat, 2483 const MglData* kdat, bool norm = true) const 2484 { 2485 return MglDataC(true, mgl_datac_evaluate(this, & idat, & jdat, & kdat, norm)); 2486 } 2487 2488 /// Find correlation with another data arrays 2489 MglDataC correlation(const MglData* dat, const char * dir) const 2490 { 2491 return MglDataC(true, mgl_datac_correl(this, & dat, dir)); 2492 } 2493 /// Find auto correlation function 2494 MglDataC autoCorrelation(const char * dir) const 2495 { 2496 return MglDataC(true, mgl_datac_correl(this, this, dir)); 2497 } 2498 2499 /// Create n-th points distribution of this data values in range [v1, v2] 2500 MglData hist(long n, mreal v1 = 0, mreal v2 = 1, long nsub = 0) const 2501 { 2502 return MglData(true, mgl_data_hist(this, n, v1, v2, nsub)); 2503 } 2504 /// Create n-th points distribution of this data values in range [v1, v2] with weight w 2505 MglData hist(in MglDataA* w, long n, mreal v1 = 0, mreal v2 = 1, long nsub = 0) const 2506 { 2507 return MglData(true, mgl_data_hist_w(this, & w, n, v1, v2, nsub)); 2508 } 2509 /// get array which is result of maximal values in given direction or directions 2510 MglData max(const char * dir) const 2511 { 2512 return MglData(true, mgl_data_max_dir(this, dir.toStringz)); 2513 } 2514 /// get array which is result of minimal values in given direction or directions 2515 MglData min(const char * dir) const 2516 { 2517 return MglData(true, mgl_data_min_dir(this, dir.toStringz)); 2518 } 2519 2520 /// Cumulative summation the data in given direction or directions 2521 void cumSum(string dir) 2522 { 2523 mgl_datac_cumsum(this, dir.toStringz); 2524 } 2525 2526 /// Integrate (cumulative summation) the data in given direction or directions 2527 void integral(string dir) 2528 { 2529 mgl_datac_integral(this, dir.toStringz); 2530 } 2531 2532 /// Differentiate the data in given direction or directions 2533 void diff(string dir) 2534 { 2535 mgl_datac_diff(this, dir.toStringz); 2536 } 2537 2538 /// Double-differentiate (like laplace operator) the data in given direction 2539 void diff2(string dir) 2540 { 2541 mgl_datac_diff2(this, dir.toStringz); 2542 } 2543 2544 /// Swap left and right part of the data in given direction (useful for fourier spectrums) 2545 void swap(string dir) 2546 { 2547 mgl_datac_swap(this, dir.toStringz); 2548 } 2549 2550 /// Roll data along direction dir by num slices 2551 void roll(char dir, long num) 2552 { 2553 mgl_datac_roll(this, dir, num); 2554 } 2555 2556 /// Mirror the data in given direction (useful for fourier spectrums) 2557 void mirror(string dir) 2558 { 2559 mgl_datac_mirror(this, dir.toStringz); 2560 } 2561 2562 /// Smooth the data on specified direction or directions 2563 void smooth(string dirs = "xyz", mreal delta = 0) 2564 { 2565 mgl_datac_smooth(this, dirs, delta); 2566 } 2567 2568 /// Hankel transform 2569 void hankel(string dir) 2570 { 2571 mgl_datac_hankel(this, dir.toStringz); 2572 } 2573 2574 /// Fourier transform 2575 void fft(string dir) 2576 { 2577 mgl_datac_fft(this, dir.toStringz); 2578 } 2579 2580 /// Calculate one step of diffraction by finite-difference method with parameter q 2581 void diffraction(string how, mreal q) 2582 { 2583 mgl_datac_diffr(this, how, q); 2584 } 2585 2586 /// Interpolate by cubic spline the data to given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1] 2587 dual spline(mreal x, mreal y = 0, mreal z = 0) const 2588 { 2589 return mgl_datac_spline(this, x, y, z); 2590 } 2591 /// Interpolate by cubic spline the data to given point x,\a y,\a z which normalized in range [0, 1] 2592 dual spline1(mreal x, mreal y = 0, mreal z = 0) const 2593 { 2594 return mgl_datac_spline(this, x * (nx - 1), y * (ny - 1), z * (nz - 1)); 2595 } 2596 /// Interpolate by linear function the data to given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1] 2597 dual linear(mreal x, mreal y = 0, mreal z = 0) const 2598 { 2599 return mgl_datac_linear(this, x, y, z); 2600 } 2601 /// Interpolate by line the data to given point x,\a y,\a z which normalized in range [0, 1] 2602 dual linear1(mreal x, mreal y = 0, mreal z = 0) const 2603 { 2604 return mgl_datac_linear(this, x * (nx - 1), y * (ny - 1), z * (nz - 1)); 2605 } 2606 /// Interpolate by linear function the data and return its derivatives at given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1] 2607 dual linear(MglPoint* dif, mreal x, mreal y = 0, mreal z = 0) const 2608 { 2609 dual val, dx, dy, dz; 2610 val = mgl_datac_linear_ext(this, x, y, z, & dx, & dy, & dz); 2611 dif = MglPoint(dx.getReal, dy.getReal, dz.getReal); 2612 return val; 2613 } 2614 /// Interpolate by line the data and return its derivatives at given point x,\a y,\a z which normalized in range [0, 1] 2615 dual linear1(MglPoint* dif, mreal x, mreal y = 0, mreal z = 0) const 2616 { 2617 dual val, dx, dy, dz; 2618 val = mgl_datac_linear_ext(this, x, y, z, & dx, & dy, & dz); 2619 dif = MglPoint(dx.getReal, dy.getReal, dz.getReal); 2620 dif.x /= nx > 1 ? nx - 1 : 1; 2621 dif.y /= ny > 1 ? ny - 1 : 1; 2622 dif.z /= nz > 1 ? nz - 1 : 1; 2623 return val; 2624 } 2625 /// Return an approximated x-value (root) when dat(x) = val 2626 mreal solve(mreal val, bool use_spline = true, long i0 = 0) const 2627 { 2628 return mgl_data_solve_1d(this, val, use_spline, i0); 2629 } 2630 /// Return an approximated value (root) when dat(x) = val 2631 MglData solve(mreal val, char dir, bool norm = true) const 2632 { 2633 return MglData(true, mgl_data_solve(this, val, dir, 0, norm)); 2634 } 2635 MglData solve(mreal val, char dir, const MglData* i0, bool norm = true) const 2636 { 2637 return MglData(true, mgl_data_solve(this, val, dir, & i0, norm)); 2638 } 2639 2640 /// Copy data from other MglDataA variable 2641 MglDataA* opAssign(in MglDataA* d) 2642 { 2643 if (this != & d) 2644 set( & d); 2645 return d; 2646 2647 } 2648 auto opAssign(in MglDataC* d) 2649 { 2650 if (this != * d) 2651 this=*d; 2652 return d; 2653 } 2654 auto opAssign(dual val) 2655 { 2656 for (long i = 0; i < nx * ny * nz; i++) 2657 a[i] = val; 2658 return val; 2659 } 2660 auto opAssign(mreal val) 2661 { 2662 for (long i = 0; i < nx * ny * nz; i++) 2663 a[i] = val; 2664 return val; 2665 } 2666 static if ((!SWIG) && false) 2667 { 2668 // Direct access to the data cell 2669 /+ 2670 dual & operator[](long i) 2671 { 2672 return a[i]; 2673 } 2674 +/ 2675 2676 } 2677 2678 debug 2679 { 2680 // get the value in given cell of the data with border checking 2681 mreal v(long i, long j = 0, long k = 0) const 2682 { 2683 return mgl_abs(mgl_datac_get_value(this, i, j, k)); 2684 } 2685 /// set the value in given cell of the data 2686 void set_v(mreal val, long i, long j = 0, long k = 0) 2687 { 2688 mgl_datac_set_value(this, val, i, j, k); 2689 } 2690 } 2691 else 2692 { 2693 // get the value in given cell of the data 2694 mreal v(long i, long j = 0, long k = 0) const 2695 { 2696 return abs(a[i + nx * (j + ny * k)]); 2697 } 2698 /// set the value in given cell of the data 2699 void set_v(mreal val, long i, long j = 0, long k = 0) 2700 { 2701 a[i + nx * (j + ny * k)] = val; 2702 } 2703 } 2704 2705 mreal vthr(long i) const 2706 { 2707 return abs(a[i]); 2708 } 2709 2710 // add for speeding up !!! 2711 mreal dvx(long i, long j = 0, long k = 0) const 2712 { 2713 long i0 = i + nx * (j + ny * k); 2714 return i > 0 ? abs(i < nx - 1 ? (a[i0 + 1] - a[i0 - 1]) / mgl2 : a[i0] - a[i0 - 1]) : abs( 2715 a[i0 + 1] - a[i0]); 2716 } 2717 2718 mreal dvy(long i, long j = 0, long k = 0) const 2719 { 2720 long i0 = i + nx * (j + ny * k); 2721 return j > 0 ? abs(j < ny - 1 ? (a[i0 + nx] - a[i0 - nx]) / mgl2 : a[i0] - a[i0 - nx]) : abs( 2722 a[i0 + nx] - a[i0]); 2723 } 2724 2725 mreal dvz(long i, long j = 0, long k = 0) const 2726 { 2727 long i0 = i + nx * (j + ny * k), n = nx * ny; 2728 return k > 0 ? abs(k < nz - 1 ? (a[i0 + n] - a[i0 - n]) / mgl2 : a[i0] - a[i0 - n]) : abs( 2729 a[i0 + n] - a[i0]); 2730 } 2731 } 2732 static if(!SWIG) 2733 { 2734 dual mglLinearC(const dual * a, long nx, long ny, long nz, mreal x, mreal y, mreal z); 2735 dual mglSpline3C(const dual * a, long nx, long ny, long nz, mreal x, mreal y, mreal z, dual * dx = 0, dual * dy = 0, dual * dz = 0); 2736 dual mglSpline3Cs(const dual * a, long nx, long ny, long nz, mreal x, mreal y, mreal z); 2737 } 2738 2739 /// saves result of PDE solving (|u|^2) for "Hamiltonian" ham with initial conditions ini 2740 MglDataC mglPDEc(mglBase * gr, const char * ham, in MglDataA* ini_re, 2741 in MglDataA* ini_im, mreal dz = 0.1, mreal k0 = 100, string opt= "") 2742 { 2743 return MglDataC(true, mgl_pde_solve_c(gr, ham, & ini_re, & ini_im, dz, k0, opt.toStringz)); 2744 } 2745 /// saves result of PDE solving for "Hamiltonian" ham with initial conditions ini along a curve ray (must have nx>=7 - x,y,z,px,py,pz,tau or nx=5 - x,y,px,py,tau) 2746 MglDataC mglQO2dc(const char * ham, in MglDataA* ini_re, in MglDataA* ini_im, in MglDataA* ray, mreal r = 1, 2747 mreal k0 = 100) 2748 { 2749 return MglDataC(true, mgl_qo2d_solve_c(ham, & ini_re, & ini_im, & ray, r, k0, 0, 0)); 2750 } 2751 2752 MglDataC mglQO2dc(const char * ham, in MglDataA* ini_re, 2753 in MglDataA* ini_im, in MglDataA* ray, MglData* xx, MglData* yy, 2754 mreal r = 1, mreal k0 = 100) 2755 { 2756 return MglDataC(true, mgl_qo2d_solve_c(ham, & ini_re, & ini_im, & ray, r, k0, 2757 & xx, & yy)); 2758 } 2759 2760 /// saves result of PDE solving for "Hamiltonian" ham with initial conditions ini along a curve ray (must have nx>=7 - x,y,z,px,py,pz,tau or nx=5 - x,y,px,py,tau) 2761 MglDataC mglQO3dc(const char * ham, in MglDataA* ini_re, 2762 in MglDataA* ini_im, in MglDataA* ray, mreal r = 1, mreal k0 = 100) 2763 { 2764 return MglDataC(true, mgl_qo3d_solve_c(ham, & ini_re, & ini_im, & ray, r, k0, 2765 0, 0, 0)); 2766 } 2767 2768 MglDataC mglQO3dc(string ham, in MglDataA* ini_re, in MglDataA* ini_im, in MglDataA* ray, MglData* xx, MglData* yy, 2769 MglData* zz, mreal r = 1, mreal k0 = 100) 2770 { 2771 return MglDataC(true, mgl_qo3d_solve_c(ham.toStringz, & ini_re, & ini_im, & ray, r, 2772 k0, & xx, & yy, & zz)); 2773 } 2774 //----------------------------------------------------------------------------- 2775 /// Prepare coefficients for global spline interpolation 2776 MglDataC mglGSplineCInit(in MglDataA* xdat, in MglDataA* ydat) 2777 { 2778 return MglDataC(true, mgl_gsplinec_init( & xdat, & ydat)); 2779 } 2780 /// Evaluate global spline (and its derivatives d1, d2 if not NULL) using prepared coefficients \a coef 2781 dual mglGSplineC(in MglDataA* coef, mreal dx, dual * d1 = 0, dual * d2 = 0) 2782 { 2783 return mgl_gsplinec( & coef, dx, d1, d2); 2784 } 2785 auto _DN_(T)(T a) 2786 { 2787 return (cast(MglDataC * ) * (a)); 2788 } 2789 auto _DC_() 2790 { 2791 return (cast(MglDataC * ) * d); 2792 } 2793 2794 static if(!SWIG) 2795 { 2796 //Wrapper class for complex expression evaluating 2797 class mglExprC 2798 { 2799 HAEX ex; 2800 this(in mglExprC* inp) 2801 { 2802 } // copying is not allowed 2803 2804 const mglExprC* opAssign(const mglExprC* t) 2805 { 2806 return t; 2807 } 2808 2809 this(string expr) 2810 { 2811 ex = mgl_create_cexpr(expr.toStringz); 2812 } 2813 2814 ~ this() 2815 { 2816 mgl_delete_cexpr(ex); 2817 } 2818 2819 // Return value of expression for given x,y,z variables 2820 dual Eval(dual x, dual y = 0, dual z = 0) 2821 { 2822 return mgl_cexpr_eval(ex, x, y, z); 2823 } 2824 2825 // Return value of expression for given x,y,z,u,v,w variables 2826 dual Eval(dual x, dual y, dual z, dual u, dual v, dual w) 2827 { 2828 dual var[26]; 2829 var['x' - 'a'] = x; 2830 var['y' - 'a'] = y; 2831 var['z' - 'a'] = z; 2832 var['u' - 'a'] = u; 2833 var['v' - 'a'] = v; 2834 var['w' - 'a'] = w; 2835 return mgl_cexpr_eval_v(ex, var); 2836 } 2837 /// Return value of expression for given variables 2838 dual Eval(dual var[26]) 2839 { 2840 return mgl_cexpr_eval_v(ex, var); 2841 } 2842 } 2843 } 2844 2845 /*************************************************************************** 2846 * data.h is part of Math Graphic Library 2847 * Copyright (C) 2007-2014 Alexey Balakin <mathgl.abalakin@gmail.ru> * 2848 * * 2849 * This program is free software; you can redistribute it and/or modify * 2850 * it under the terms of the GNU Library General Public License as * 2851 * published by the Free Software Foundation; either version 3 of the * 2852 * License, or (at your option) any later version. * 2853 * * 2854 * This program is distributed in the hope that it will be useful, * 2855 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 2856 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 2857 * GNU General Public License for more details. * 2858 * * 2859 * You should have received a copy of the GNU Library General Public * 2860 * License along with this program; if not, write to the * 2861 * Free Software Foundation, Inc., * 2862 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 2863 ***************************************************************************/ 2864 +/