Viewing contents of file '../idllib/astron/contrib/varosi/vlibm/allpro/fractal_synth.pro'
;+
; NAME:
; fractal_synth
; PURPOSE:
; Synthesize a fractal embedded in either 2-D (a fractal curve)
; or in 3-D (a fractal surface) using power-law spectral technique.
; CALLING:
; function fractal_synth, Hpar, ft
; INPUTS:
; Hpar = H parameter determining the theoretical fractal dimension D,
; should normally be in the range 0 to 1 so that D = E - H,
; where E = embedding dimension (2 or 3). The theoretical fractal
; dimension is approached as number of frequencies goes infinite.
; The power-law exponent of power spectral density = -(2*H+E-1).
; Statistically, the average variance of points on the fractal
; scales as the distance between the points to the power 2*H.
; KEYWORDS:
; EDIM = embedding dimension E, default=3, giving fractal surface (image).
; NFREQ = number of frequencies to use in spectral synthesis, default=64.
; STD = optional st.dev. of random noise added to amplitudes, default=0.
; PHASE = optional input/output, random phases between 0 and 2*!pi.
; Keyword can be used to keep the same phases while changing H.
; OUTPUTS:
; ft = optional, Fourier spectrum used to generate the synthesized image.
;
; Function returns a vector of size = 2 * NFREQ,
; or image of size = ( 2 * NFREQ, 2 * NFREQ ).
; EXAMPLES:
; display 128x128 image of dimension 2.5 :
; tvscl, fractal_synth()
;
; display 512x512 image of dim = 2.3 :
; tvscl, fractal_synth( 0.7, NF=256 )
;
; plot 512 pnt. curve of dim = 1.9 (and save phases into p) :
; plot, fractal_synth( 0.1, E=2, NF=256, PH=p )
;
; overplot curves with range of fractal dimensions from 1 to 2 :
; for i=0,10 do oplot, fractal_synth( i/10., E=2, NF=256, PH=p )
;
; EXTERNAL CALLS:
; function rfftinv (inverse FFT giving a real-valued function).
; COMMON BLOCKS:
; common fractal_synth, su,sn (internal use, seeds of randomu & randomn)
; PROCEDURE:
; Generate 1D/2D spectral amplitudes with power-law exponent -(2*H+E-1)/2
; and distribute the phases uniformly from 0 to 2*!pi, then inverse FFT.
; HISTORY:
; Written: Frank Varosi, HSTX @ NASA/GSFC, 1995.
;-
function fractal_synth, Hpar, ft, EDIM=edim, NFREQ=nfreq, STD=std, PHASE=phase
common fractal_synth, su,sn
if N_elements( edim ) NE 1 then edim = 3
ndim = edim-1
if N_elements( nfreq ) LE 0 then nfreq = 64
if N_elements( nfreq ) NE ndim then nfreq = replicate( nfreq(0), ndim )
if N_elements( Hpar ) NE 1 then Hpar = 0.5
CASE edim OF
2: BEGIN
message,"fractal dimension = " + $
strtrim( ((edim-hpar)>1)<2, 2 ),/INFO
power = -( Hpar + 0.5 )
fa = ( indgen( nfreq+1 ) > 1 )^power
fa(0) = 0
nf = N_elements( fa )
if keyword_set( std ) then begin
fa = ( fa + randomn( sn, nf ) * std ) > 0
fa(0) = 0
endif
if N_elements( phase ) NE nf then phase = randomu( su, nf )
fc = fa * exp( 2*!PI * complex(0,1) * phase )
ft = [ fc(0:nfreq-1), rotate( conj( fc(1:*) ), 2 ) ]
return, float( fft( ft, 1 ) )
END
3: BEGIN
message,"fractal dimension = " + $
strtrim( ((edim-hpar)>2)<3, 2 ),/INFO
nf = nfreq + 1
fa = total( gridxy( nf(0), nf(1), POWER=2 ), 3 ) ;squared
fa(0,0) = 1
fa = fa^( -0.5 * ( Hpar + 1 ) ) ;square-root included.
fa(0,0) = 0
fa = [ rotate( fa(1:*,*), 5 ), fa(0:nfreq(0)-1,*) ]
sz = size( fa )
if keyword_set( std ) then begin
fa = ( fa + randomn( sn, sz(1), sz(2) ) * std ) > 0
fa(sz(1)/2,0) = 0
endif
if N_elements( phase ) NE N_elements( fa ) then $
phase = randomu( su, sz(1), sz(2) )
fc = fa * exp( 2*!PI * complex(0,1) * phase )
return, rfftinv( fc, ft, /CENTER, /FORCE_REAL )
END
else: BEGIN
message,"case not implemented",/INFO
return,(0)
END
ENDCASE
end