DFunction¶
Discrete function with interpolation
User level function of the Quantarhei package. To be used as:
>>> import quantarhei as qr
>>> f = qr.DFunction()
Discrete representation of a function with several modes of interpolation. Once defined, the function values are obtained by the method at(x), which takes the function argument and optionally a specification of the interpolation type. See examples below.
The linear interpolation is the default initially. Once the function is interpolated by splines (which happens why you call it with approx=”spline”), the default switches to “spline”. You can always enforce the type of interpolation by specifying it explicitely by the approx argument.
Examples
>>> import numpy
>>> x = numpy.linspace(0.0,95.0,20)
>>> y = numpy.exp(-x/30.0)
>>> u = ValueAxis(0.0,len(x),x[1]-x[0])
>>> f = DFunction(u,y)
>>> "%.4f" % f.axis.step
'5.0000'
Values at the points where the function was defined are exact
>>> "%.4f" % f.at(0.0)
'1.0000'
>>> "%.4f" % f.at(5.0)
'0.8465'
This is the exact value between the discrete points on which the function was defined
>>> "%.4f" % numpy.exp(-2.0/30.0)
'0.9355'
Default linear approximation leads to a difference at the second digit
>>> "%.4f" % f.at(2.0)
'0.9386'
Spline approximation is much better
>>> "%.4f" % f.at(2.0,approx='spline')
'0.9355'
Fourier transform of a DFunction
>>> from .time import TimeAxis
>>> dt = 0.1; Ns = 10000
>>> t = TimeAxis(-(Ns//2)*dt,Ns,dt,atype="complete")
>>> gg = 1.0/30.0
>>> y = numpy.exp(-numpy.abs(t.data)*gg)
>>> f = DFunction(t,y)
>>> F = f.get_Fourier_transform()
>>> print(numpy.allclose(F.at(0.0,approx="spline"),2.0/gg,rtol=1.0e-5))
True
>>> print(numpy.allclose(F.at(1.0),2*gg/(gg**2 + 1.0**2),rtol=1.0e-3))
True
>>> print(numpy.allclose(F.at(0.15),2*gg/(gg**2 + 0.15**2),rtol=1.0e-4))
True
>>> t = TimeAxis(0,Ns,dt)
>>> print(t.atype == "upper-half")
True
>>> gg = 1.0/30.0
>>> y = numpy.exp(-numpy.abs(t.data)*gg)
>>> f = DFunction(t,y)
>>> F = f.get_Fourier_transform()
>>> print(numpy.allclose(F.at(0.0,approx="spline"),2.0/gg,rtol=1.0e-5))
True
>>> print(numpy.allclose(F.at(1.0),2*gg/(gg**2 + 1.0**2),rtol=1.0e-3))
True
>>> print(numpy.allclose(F.at(0.15),2*gg/(gg**2 + 0.15**2),rtol=1.0e-4))
True
DFunction can be complex valued
>>> y = numpy.sin(t.data/10.0) + 1j*numpy.cos(t.data/10.0)
>>> fi = DFunction(t,y)
>>> print(numpy.allclose(fi.at(13.2,approx="spline"), (numpy.sin(13.2/10.0) + 1j*numpy.cos(13.2/10.0)),rtol=1.0e-7))
True
Only “linear” and “spline” approximations are available >>> fval = fi.at(11.2, approx=”quadratic”) Traceback (most recent call last):
…
Exception: Unknown interpolation type
Class Details¶
-
class
quantarhei.core.dfunction.
DFunction
(x=None, y=None)[source]¶ Discrete function with interpolation
Parameters: - x (ValueAxis (such as TimeAxis, FrequencyAxis etc.)) – Array of the values of the argument of the discrete function
- y (numpy.ndarray) – Array of the function values
Examples
How not to create the DFunction:
First argument of the DFunction must be a ValueAxis
>>> x1 = numpy.array([0.0, 1.0, 2.0], dtype=REAL) >>> y1 = numpy.array([0.0, 12.0, 24.0], dtype=REAL) >>> f = DFunction(x=x1, y=y1) Traceback (most recent call last): ... Exception: First argument has to be of a ValueAxis type
Second argument must by a numpy array
>>> x1 = ValueAxis(0.0, 2, 1.0) >>> y1 = [0.0, 12.0, 24.0] >>> f = DFunction(x=x1, y=y1) Traceback (most recent call last): ... Exception: Second argument has to be one-dimensional numpy.ndarray
The two arguments have to have the same size (number of elements)
>>> x1 = ValueAxis(0.0, 2, 1.0) >>> y1 = numpy.array([0.0, 12.0, 24.0, 36.0], dtype=REAL) >>> f = DFunction(x=x1, y=y1) Traceback (most recent call last): ... Exception: Wrong number of elements in 1D numpy.ndarray
>>> x1 = ValueAxis(0.0, 2, 1.0) >>> y1 = numpy.array([[0.0, 12.0, 24.0], [36.0, 48.0, 60.0]], dtype=REAL) >>> f = DFunction(x=x1, y=y1) Traceback (most recent call last): ... Exception: Second argument has to be one-dimensional numpy.ndarray
Methods
apply_to_data
(func)Applies a submitted function to the data at
(x[, approx])Returns the function value at the argument x change_axis
(axis)Replaces the axis object with a compatible one, zero pads or trims the values copy
()Returns a shallow copy of the self deepcopy
()Returns a deep copy of the self fit_exponential
([guess])Exponential fit of the function fit_gaussian
([N, guess, Nsvf])Performs a Gaussian fit of the spectrum based on an initial guess get_Fourier_transform
([window])Returns Fourier transform of the DFunction get_inverse_Fourier_transform
()Returns inverse Fourier transform of the DFunction load
(filename[, test])Loads an object from a file and returns it load_data
(name[, with_axis])Loads the data in a format determined by the file name extension loaddir
(dirname)Returns a directory of objects saved into a directory plot
([fig, title, title_font, axis, vmax, …])Plotting of the DFunction’s data against the ValueAxis. save
(filename[, comment, test])Saves the object with all its content into a file save_data
(name[, with_axis])Saves the data into a format determined by the file name extension savedir
(dirname[, tag, comment, test])Saves an object into directory containing a file with unique name savefig
(filename)Saves current figure into a file scopy
()Creates a copy of the object by saving and loading it set_data_protected
()Implement this method to put protections on data property set_data_writable
()Implement this method to lift existing protection of data property -
apply_to_data
(func)[source]¶ Applies a submitted function to the data
>>> x = TimeAxis(0.0, 314, 0.001) >>> f1 = DFunction(x, x.data) >>> f2 = DFunction(x, numpy.cos(x.data)) >>> f1.data[100] == f2.data[100] False
>>> f1.apply_to_data(numpy.cos) >>> f1.data[100] == f2.data[100] True
>>> f1.data[160] == f2.data[160] True
-
at
(x, approx='default')[source]¶ Returns the function value at the argument x
Returns the value of the function at a given value of argument x. The default interpolation is linear, until the spline interpolation is initialized by calling the method with approx = “spline”. From then on, the default is spline.
Parameters: - x (number) – Function argument
- approx (string {"default","linear","spline"}) – Type of interpolation
Examples
>>> time = TimeAxis(0.0, 100, 10.0) >>> vals = numpy.cos(2.0*numpy.pi*time.data/300.0) >>> fce = DFunction(time, vals) >>> print("%.8f" % fce.at(213.4)) -0.23949089
>>> print("%.8f" % fce.at(213.4, approx="linear")) -0.23949089
>>> print("%.8f" % fce.at(213.4, approx="spline")) -0.24056615
>>> print("%.8f" % numpy.cos(2.0*numpy.pi*213.4/300.0)) -0.24056687
Once the splines are initialized, they become default >>> print(“%.8f” % fce.at(213.4)) -0.24056615
-
change_axis
(axis)[source]¶ Replaces the axis object with a compatible one, zero pads or trims the values
Examples
>>> time = TimeAxis(0.0, 1000, 1.0) >>> vals = numpy.cos(2.0*numpy.pi*time.data/500.0) >>> fce = DFunction(time, vals) >>> print("%.4f" % fce.at(914.0)) 0.4707
>>> time1 = TimeAxis(0.0, 1000, 1.0) >>> fce.change_axis(time1) >>> fce.axis == time1 True
>>> time2 = TimeAxis(0.0, 900, 1.0) >>> fce.change_axis(time2) >>> print("%.4f" % fce.at(914.0)) Traceback (most recent call last): ... Exception: Value out of bounds
>>> print("%.4f" % fce.at(814.0)) -0.6937
Zero-padding
>>> time3 = TimeAxis(0.0, 1000, 1.0) >>> fce.change_axis(time3) >>> print("%.4f" % fce.at(814.0)) -0.6937
>>> print("%.4f" % fce.at(914.0)) 0.0000
>>> time4 = TimeAxis(0.0, 100, 10.0) >>> fce.change_axis(time4) Traceback (most recent call last): ... Exception: Incompatible axis
-
fit_exponential
(guess=None)[source]¶ Exponential fit of the function
Examples
>>> t = TimeAxis(0.0, 100, 1.0) >>> f = DFunction(t, 2.3*numpy.exp(-(t.data)/(10.0))+0.32) >>> popt = f.fit_exponential() >>> print(popt) [ 2.3 0.1 0.32]
-
fit_gaussian
(N=1, guess=None, Nsvf=251)[source]¶ Performs a Gaussian fit of the spectrum based on an initial guess
Parameters: Nsvf (int) – Length of the Savitzky-Golay filter window (odd integer) Examples
>>> t = TimeAxis(0.0, 100, 1.0) >>> f = DFunction(t, 2.3*numpy.exp(-(4.0*numpy.log(2.0))*((t.data-30.0)**2)/(10.0**2))+0.32) >>> popt = f.fit_gaussian(guess=[1.0, 33.0, 5.0, 0.5]) >>> print(popt) [ 2.3 30. 10. 0.32]
-
get_Fourier_transform
(window=None)[source]¶ Returns Fourier transform of the DFunction
>>> t = TimeAxis(0.0, 200, 1.0)
The default type of TimeAxis is “upper-half”
>>> print(t.atype) upper-half
We create a function with this TimeAxis
>>> f = DFunction(t, numpy.exp(((-t.data-50.0)**2)/(30.0**2))) >>> F = f.get_Fourier_transform()
When TimeAxis is the “upper-half” it is assumed that only half of the function is specified. The “lower-half” corresponds to a complex conjugated function, and FT is real.
>>> rmax = numpy.max(numpy.abs(numpy.real(F.data))) >>> imax = numpy.max(numpy.abs(numpy.imag(F.data))) >>> imax/rmax < 1.0e-15 True
>>>
The same with “complete” gives a complex result
>>> t = TimeAxis(0.0, 200, 1.0, atype="complete") >>> f = DFunction(t, numpy.exp((-(t.data-50.0)**2)/(30.0**2))) >>> F = f.get_Fourier_transform()
>>> rmax = numpy.max(numpy.abs(numpy.real(F.data))) >>> imax = numpy.max(numpy.abs(numpy.imag(F.data))) >>> imax/rmax < 1.0e-15 False
>>> f.axis.atype="lower-half" >>> F = f.get_Fourier_transform() Traceback (most recent call last): ... Exception: Unknown time axis type
-
get_inverse_Fourier_transform
()[source]¶ Returns inverse Fourier transform of the DFunction
>>> import quantarhei as qr
>>> t = TimeAxis(-100.0, 200, 1.0) >>> f = DFunction(t, numpy.exp(-(t.data**2)/(30.0**2))) >>> F = f.get_Fourier_transform()
>>> fn = F.get_inverse_Fourier_transform() >>> numpy.testing.assert_allclose(numpy.real(fn.data[100]), f.data[100])
>>> dw = qr.convert(5.0,"1/cm","int") >>> w = FrequencyAxis(0.0, 100, dw) #t.get_FrequencyAxis() >>> delt = qr.convert(30.0,"1/cm","int") >>> F = DFunction(w, numpy.exp((w.data**2)/(delt**2))) >>> f = F.get_inverse_Fourier_transform() >>> isinstance(f.axis, TimeAxis) True
-
plot
(fig=None, title=None, title_font=None, axis=None, vmax=None, vmin=None, xlabel=None, ylabel=None, label_font=None, text=None, text_font=None, label=None, text_loc=[0.05, 0.9], fontsize='20', real_only=True, show=False, color=None)[source]¶ Plotting of the DFunction’s data against the ValueAxis.
Parameters: - title (str) – Title of the plot
- title_font (str) – Name of the title font