! bn_eof_simple
! Define a simple function with two known functions.
! decompose with EOFs.
! 7/2012 
! In version 6.8 (double precision), the old eof functions are not available
! Run the script calling eofsvd functions and exit, leaving old eof function calls.


! Define two locations.
def axis /X=1:2:1 xaxis
def axis /Y=1:1:1 yaxis

! Thinking of the time axis as number of months.
def axis /T=0.0:59.75:0.25 taxis
def grid /X=xaxis /Y=yaxis /T=taxis xytgrid
set grid xytgrid

! Make standing waves with a period of 12 months.
let cosT = cos(T * 3.141592653589793 / 6.0)
let sinT = sin(T * 3.141592653589793 / 6.0)

! Put a standing wave at each location.
! The two waves are orthonormal and zero-mean over time. 
let spacetime = if (i eq 1) then cosT else sinT + 1
show grid spacetime

show func eofsvd_stat
! Run each of the eof functions and show the results.
! Both are equally significant.  Eigenvalues should be 0.5.
! Other EOF descriptions do not divide the covariance
! matrix by the number of time values, in which case the
! the eigenvalues will be much larger, but still equal
! to each other.
list eofsvd_stat(spacetime)

show func eofsvd_space
! Ideally the vectors (0.0, sqrt(0.5)) and (sqrt(0.5), 0.0),
! but might be mixed by rotation.
! This is if the EOF functions are in units of the original data,
! thus the eigenvectors times the square-root of the eigenvalue.
! EOF vectors are always orthogonal to each other.
list eofsvd_space(spacetime)

show func eofsvd_tfunc
! Ideally sqrt(2.0) * (cosT, sinT), but may be mixed by rotation.  
! TAF vectors are always orthogonal to each other.
list eofsvd_tfunc(spacetime)

! The sum over all significant EOFs of the outer product of 
! EOF(i) and TAF(i) should return the zero-time-meaned data 
! (original data with the time-series mean subtracted to give 
! a zero mean for each time series).
! In this case, EOF(1) o TAF(1) + EOF(2) o TAF(2) = (cosT, sinT)

! Missing-data cases
!
! If there are locations where the timeseries is all missing or incomplete 
! (as in a dataset where missing data represents land), return a result 
! based only locations with complete timeseries.

def axis /X=1:3:1 xaxis
let spacetime = if (i eq 1) then cosT else sinT + 1
let space12 = if i ne 3 then spacetime

list eofsvd_stat(space12)
list eofsvd_space(space12)
list eofsvd_tfunc(space12)


! If there are no complete time series, the functions should bail with an error

let spacegap = if L ne 2 then spacetime

set mode ignore
list eofsvd_stat(spacegap)
list eofsvd_space(spacegap)
list eofsvd_tfunc(spacegap)

! clean-up
set mode/last ignore
can var spacetime
set grid abstract
can grid xytgrid
can axis taxis
can axis yaxis
can axis xaxis


exit/script
! -----------------------------------------------
! previous commands that called eof_space, eof_stat, eof_tfunc


! Define two locations.
def axis /X=1:2:1 xaxis
def axis /Y=1:1:1 yaxis

! Thinking of the time axis as number of months.
def axis /T=0.0:59.75:0.25 taxis
def grid /X=xaxis /Y=yaxis /T=taxis xytgrid
set grid xytgrid

! Make standing waves with a period of 12 months.
let cosT = cos(T * 3.141592653589793 / 6.0)
let sinT = sin(T * 3.141592653589793 / 6.0)

! Put a standing wave at each location.
! The two waves are orthonormal and zero-mean over time. 
let spacetime = if (i eq 1) then cosT else sinT + 1
show grid spacetime

show func eof_stat
! Run each of the eof functions and show the results.
! Both are equally significant.  Eigenvalues should be 0.5.
! Other EOF descriptions do not divide the covariance
! matrix by the number of time values, in which case the
! the eigenvalues will be much larger, but still equal
! to each other.
list eof_stat(spacetime, 1.0)

show func eof_space
! Ideally the vectors (0.0, sqrt(0.5)) and (sqrt(0.5), 0.0),
! but might be mixed by rotation.
! This is if the EOF functions are in units of the original data,
! thus the eigenvectors times the square-root of the eigenvalue.
! EOF vectors are always orthogonal to each other.
list eof_space(spacetime, 1.0)

show func eof_tfunc
! Ideally sqrt(2.0) * (cosT, sinT), but may be mixed by rotation.  
! TAF vectors are always orthogonal to each other.
list eof_tfunc(spacetime, 1.0)

! The sum over all significant EOFs of the outer product of 
! EOF(i) and TAF(i) should return the zero-time-meaned data 
! (original data with the time-series mean subtracted to give 
! a zero mean for each time series).
! In this case, EOF(1) o TAF(1) + EOF(2) o TAF(2) = (cosT, sinT)

! clean-up
can var spacetime
set grid abstract
can grid xytgrid
can axis taxis
can axis yaxis
can axis xaxis

