3d gaussian bidang acak python

Ini adalah versi kode yang memasukkan saran kompilasi dari acl

fftIndgen[n_] :=  Flatten[{Range[0., n/2.], -Reverse[Range[1., n/2. - 1]]}]

Clear[GaussianRandomField];
GaussianRandomField::usage = " GaussianRandomField[size,dim,Pk] 
returns a Gaussian random field of size size (default 256)
and dimensions dim (default 2) with a powerspectrum Pk default k^(-3))";
GaussianRandomField[size_: 256, dim_: 2, Pk_: Function[k, k^-3]] := 
Module[{noise, amplitude, Pk1, Pk2, Pk3,Pk4,kx,ky,kz,ku},
Which[
dim == 1,
Pk1 = Compile[{{kx, _Real}}, 
 If[kx == 0 , 0, Sqrt[Abs[Pk[kx]]]]]; (*define sqrt powerspectra*)
 noise = Fourier[RandomVariate[NormalDistribution[], {size}]]; (*generate white noise*)
 amplitude = Map[Pk1, fftIndgen[size], 1]; (*amplitude for all frequels*)
InverseFourier[noise*amplitude]//Chop, (*convolve and inverse fft*)
dim == 2,
Pk2 = Compile[{{kx, _Real}, {ky, _Real}},If[kx == 0 && ky == 0, 0,
  Sqrt[Pk[Sqrt[kx^2 + ky^2]]]]];
noise = Fourier[RandomVariate[NormalDistribution[], {size, size}]];
amplitude = Map[Pk2 @@ # &, Outer[List, fftIndgen[size], fftIndgen[size]], {2}];
InverseFourier[noise*amplitude]//Chop,
dim == 3,
Pk3 = Compile[{{kx, _Real}, {ky, _Real}, {kz, _Real}},
 If[kx == 0 && ky == 0 && kz == 0, 0, Sqrt[Pk[Sqrt[kx^2 + ky^2 + kz^2]]]]];
noise = 
Fourier[RandomVariate[NormalDistribution[], {size, size, size}]];
amplitude = Map[Pk3 @@ # &, 
 Outer[List,fftIndgen[size],fftIndgen[size],fftIndgen[size]], {3}];
InverseFourier[noise*amplitude]//Chop,
dim == 4,
Pk4 = Compile[{{kx, _Real}, {ky, _Real}, {kz, _Real}, {ku,_Real}},If[
kx == 0 && ky == 0 && kz == 0 && ku == 0, 0,  Sqrt[Pk[Sqrt[kx^2 + ky^2 + kz^2 + ku^2]]]]];
noise = 
Fourier[RandomVariate[NormalDistribution[], {size, size, size, size}]];
amplitude = 
Map[Pk4 @@ # &, 
 Outer[List, fftIndgen[size], fftIndgen[size], fftIndgen[size], 
  fftIndgen[size]], {4}];
InverseFourier[noise*amplitude]//Chop,
dim > 4, "Not supported"]
]

Kami dapat memeriksa apakah GRF memiliki spektrum daya yang benar melalui perintah

lm = {Range[128], 
  Map[Mean, 
    Table[Fourier[GaussianRandomField[256, 1, #^(-3/2) &]] // 
        Abs // #^2 &, {5}] // Transpose] // 
   Take[#, {2, 256/2 + 1}] &} // Transpose // Log // 
LinearModelFit[#, {1, x}, x] &;
lm["ParameterTable"]
_

Sebuah contoh

GaussianRandomField[] // MatrixPlot

3d gaussian bidang acak python

Itu juga dapat digunakan untuk menghasilkan gambar seperti awan

u = GaussianRandomField[] // GaussianFilter[#, 1] &;Image[u] // ImageAdjust

3d gaussian bidang acak python

Akhirnya Contoh 3D

GaussianRandomField[16, 3] // Chop // ListContourPlot3D
_

3d gaussian bidang acak python

Dalam hal kinerja yang kami miliki

GaussianRandomField[128, 3]; // AbsoluteTiming
{7.169987,Null}

Komit ini bukan milik cabang mana pun di repositori ini, dan mungkin milik garpu di luar repositori

Anda tidak dapat melakukan tindakan tersebut saat ini

Anda masuk dengan tab atau jendela lain. Muat ulang untuk menyegarkan sesi Anda. Anda keluar di tab atau jendela lain. Muat ulang untuk menyegarkan sesi Anda

Dalam postingan hampir tiga tahun lalu, saya membahas generator bidang acak berkorelasi spasial berbasis python berdasarkan interpolasi pembobotan jarak terbalik dan "titik virtual" yang digunakan untuk menetapkan nilai bidang ke titik benih. Saat populasi seed point bertambah dengan setiap iterasi, dampak dari seed point virtual berikutnya akan berkurang secara bertahap, berdasarkan jarak offset yang ditentukan pengguna. Algoritme tersebut memiliki beberapa kelemahan, termasuk waktu pemrosesan yang lama (terutama untuk masalah 3-D) dan kecenderungan untuk menghasilkan noise/hotspot acak lokal yang tidak menyenangkan secara estetika dan tampaknya tidak masuk akal secara fisik. Baru-baru ini, saya memutuskan untuk meninjau kembali masalah bidang acak berkorelasi 3-D, dengan tujuan menghasilkan bidang dengan cara yang lebih kuat dan konsisten untuk membantu sejumlah proyek konsultasi saat ini. Seperti sebelumnya, saya ingin tetap menggunakan python dan rangkaian alat ilmiah pendukungnya untuk tugas ini, dan saya ingin membuat skripnya sangat singkat sehingga mudah dipahami dan/atau dimodifikasi. Kode yang dihasilkan sekarang ada di repo GitHub saya;

Pendekatan Komputasi

Peningkatan yang ditambahkan untuk skrip baru meliputi. (1) lebih menekankan pada operasi vektorisasi untuk meningkatkan kecepatan eksekusi, (2) beralih ke interpolasi berbasis fungsi basis radial untuk pembuatan benih, (3) mengisi sel kisi secara langsung sebagai titik benih baru dalam iterasi, sebagai lawan dari memperlakukan . Fraksi yang terkait dengan item terakhir – proporsi sel kisi dengan nilai bidang yang ditentukan dengan menempatkan nilai seed yang diambil dari distribusi Gaussian, berlawanan dengan interpolasi di seluruh titik seed lokal – merupakan faktor utama yang menentukan waktu eksekusi serta kelancaran

Secara singkat, algoritme didasarkan pada skema berikut

  1. Berikan satu set titik benih awal (x, y, z, nilai);
  2. Tetapkan nilai titik seed awal ke subset sel kisi yang sesuai, berdasarkan lokasi
  3. Melangkah secara acak melalui subset sel kisi dengan nilai yang belum ditetapkan dan menempatkan nilai bidang, menggunakan interpolasi fungsi basis radial di antara titik benih terdekat untuk menemukan nilai rata-rata dan kemudian menambahkan derau Gaussian
  4. Isi sisa kisi menggunakan untuk kecepatan dan untuk menghaluskan bidang yang dihasilkan yang diwakili oleh seluruh kisi

Fitur tambahan termasuk (1) faktor penskalaan anisotropi terarah, dan (2) pengurangan metodis dalam radius pencarian interpolasi karena lebih banyak sel kisi diisi dengan nilai bidang untuk mengurangi beban komputasi pada interpolator fungsi basis radial

Berikut adalah contoh bidang konduktivitas hidrolik 3-D (berskala log), dihasilkan pada kisi 80 x 100 x 10 x-y-z