123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342 |
- """
- Functions which are common and require SciPy Base and Level 1 SciPy
- (special, linalg)
- """
- from scipy._lib.deprecation import _deprecated
- from scipy._lib._finite_differences import _central_diff_weights, _derivative
- from numpy import array, frombuffer, load
- __all__ = ['central_diff_weights', 'derivative', 'ascent', 'face',
- 'electrocardiogram']
- @_deprecated(msg="scipy.misc.central_diff_weights is deprecated in "
- "SciPy v1.10.0; and will be completely removed in "
- "SciPy v1.12.0. You may consider using "
- "findiff: https://github.com/maroba/findiff or "
- "numdifftools: https://github.com/pbrod/numdifftools")
- def central_diff_weights(Np, ndiv=1):
- """
- Return weights for an Np-point central derivative.
- Assumes equally-spaced function points.
- If weights are in the vector w, then
- derivative is w[0] * f(x-ho*dx) + ... + w[-1] * f(x+h0*dx)
- .. deprecated:: 1.10.0
- `central_diff_weights` has been deprecated from
- `scipy.misc.central_diff_weights` in SciPy 1.10.0 and
- it will be completely removed in SciPy 1.12.0.
- You may consider using
- findiff: https://github.com/maroba/findiff or
- numdifftools: https://github.com/pbrod/numdifftools
- Parameters
- ----------
- Np : int
- Number of points for the central derivative.
- ndiv : int, optional
- Number of divisions. Default is 1.
- Returns
- -------
- w : ndarray
- Weights for an Np-point central derivative. Its size is `Np`.
- Notes
- -----
- Can be inaccurate for a large number of points.
- Examples
- --------
- We can calculate a derivative value of a function.
- >>> from scipy.misc import central_diff_weights
- >>> def f(x):
- ... return 2 * x**2 + 3
- >>> x = 3.0 # derivative point
- >>> h = 0.1 # differential step
- >>> Np = 3 # point number for central derivative
- >>> weights = central_diff_weights(Np) # weights for first derivative
- >>> vals = [f(x + (i - Np/2) * h) for i in range(Np)]
- >>> sum(w * v for (w, v) in zip(weights, vals))/h
- 11.79999999999998
- This value is close to the analytical solution:
- f'(x) = 4x, so f'(3) = 12
- References
- ----------
- .. [1] https://en.wikipedia.org/wiki/Finite_difference
- """
- return _central_diff_weights(Np, ndiv)
- @_deprecated(msg="scipy.misc.derivative is deprecated in "
- "SciPy v1.10.0; and will be completely removed in "
- "SciPy v1.12.0. You may consider using "
- "findiff: https://github.com/maroba/findiff or "
- "numdifftools: https://github.com/pbrod/numdifftools")
- def derivative(func, x0, dx=1.0, n=1, args=(), order=3):
- """
- Find the nth derivative of a function at a point.
- Given a function, use a central difference formula with spacing `dx` to
- compute the nth derivative at `x0`.
- .. deprecated:: 1.10.0
- `derivative` has been deprecated from `scipy.misc.derivative`
- in SciPy 1.10.0 and it will be completely removed in SciPy 1.12.0.
- You may consider using
- findiff: https://github.com/maroba/findiff or
- numdifftools: https://github.com/pbrod/numdifftools
- Parameters
- ----------
- func : function
- Input function.
- x0 : float
- The point at which the nth derivative is found.
- dx : float, optional
- Spacing.
- n : int, optional
- Order of the derivative. Default is 1.
- args : tuple, optional
- Arguments
- order : int, optional
- Number of points to use, must be odd.
- Notes
- -----
- Decreasing the step size too small can result in round-off error.
- Examples
- --------
- >>> from scipy.misc import derivative
- >>> def f(x):
- ... return x**3 + x**2
- >>> derivative(f, 1.0, dx=1e-6)
- 4.9999999999217337
- """
- return _derivative(func, x0, dx, n, args, order)
- @_deprecated(msg="scipy.misc.ascent has been deprecated in SciPy v1.10.0;"
- " and will be completely removed in SciPy v1.12.0. "
- "Dataset methods have moved into the scipy.datasets "
- "module. Use scipy.datasets.ascent instead.")
- def ascent():
- """
- Get an 8-bit grayscale bit-depth, 512 x 512 derived image for easy use in demos
- The image is derived from accent-to-the-top.jpg at
- http://www.public-domain-image.com/people-public-domain-images-pictures/
- .. deprecated:: 1.10.0
- `ascent` has been deprecated from `scipy.misc.ascent`
- in SciPy 1.10.0 and it will be completely removed in SciPy 1.12.0.
- Dataset methods have moved into the `scipy.datasets` module.
- Use `scipy.datasets.ascent` instead.
- Parameters
- ----------
- None
- Returns
- -------
- ascent : ndarray
- convenient image to use for testing and demonstration
- Examples
- --------
- >>> import scipy.misc
- >>> ascent = scipy.misc.ascent()
- >>> ascent.shape
- (512, 512)
- >>> ascent.max()
- 255
- >>> import matplotlib.pyplot as plt
- >>> plt.gray()
- >>> plt.imshow(ascent)
- >>> plt.show()
- """
- import pickle
- import os
- fname = os.path.join(os.path.dirname(__file__),'ascent.dat')
- with open(fname, 'rb') as f:
- ascent = array(pickle.load(f))
- return ascent
- @_deprecated(msg="scipy.misc.face has been deprecated in SciPy v1.10.0; "
- "and will be completely removed in SciPy v1.12.0. "
- "Dataset methods have moved into the scipy.datasets "
- "module. Use scipy.datasets.face instead.")
- def face(gray=False):
- """
- Get a 1024 x 768, color image of a raccoon face.
- raccoon-procyon-lotor.jpg at http://www.public-domain-image.com
- .. deprecated:: 1.10.0
- `face` has been deprecated from `scipy.misc.face`
- in SciPy 1.10.0 and it will be completely removed in SciPy 1.12.0.
- Dataset methods have moved into the `scipy.datasets` module.
- Use `scipy.datasets.face` instead.
- Parameters
- ----------
- gray : bool, optional
- If True return 8-bit grey-scale image, otherwise return a color image
- Returns
- -------
- face : ndarray
- image of a racoon face
- Examples
- --------
- >>> import scipy.misc
- >>> face = scipy.misc.face()
- >>> face.shape
- (768, 1024, 3)
- >>> face.max()
- 255
- >>> face.dtype
- dtype('uint8')
- >>> import matplotlib.pyplot as plt
- >>> plt.gray()
- >>> plt.imshow(face)
- >>> plt.show()
- """
- import bz2
- import os
- with open(os.path.join(os.path.dirname(__file__), 'face.dat'), 'rb') as f:
- rawdata = f.read()
- data = bz2.decompress(rawdata)
- face = frombuffer(data, dtype='uint8')
- face.shape = (768, 1024, 3)
- if gray is True:
- face = (0.21 * face[:,:,0] + 0.71 * face[:,:,1] + 0.07 * face[:,:,2]).astype('uint8')
- return face
- @_deprecated(msg="scipy.misc.electrocardiogram has been "
- "deprecated in SciPy v1.10.0; and will "
- "be completely removed in SciPy v1.12.0. "
- "Dataset methods have moved into the scipy.datasets "
- "module. Use scipy.datasets.electrocardiogram instead.")
- def electrocardiogram():
- """
- Load an electrocardiogram as an example for a 1-D signal.
- The returned signal is a 5 minute long electrocardiogram (ECG), a medical
- recording of the heart's electrical activity, sampled at 360 Hz.
- .. deprecated:: 1.10.0
- `electrocardiogram` has been deprecated from
- `scipy.misc.electrocardiogram` in SciPy 1.10.0 and it will be
- completely removed in SciPy 1.12.0.
- Dataset methods have moved into the `scipy.datasets` module.
- Use `scipy.datasets.electrocardiogram` instead.
- Returns
- -------
- ecg : ndarray
- The electrocardiogram in millivolt (mV) sampled at 360 Hz.
- Notes
- -----
- The provided signal is an excerpt (19:35 to 24:35) from the `record 208`_
- (lead MLII) provided by the MIT-BIH Arrhythmia Database [1]_ on
- PhysioNet [2]_. The excerpt includes noise induced artifacts, typical
- heartbeats as well as pathological changes.
- .. _record 208: https://physionet.org/physiobank/database/html/mitdbdir/records.htm#208
- .. versionadded:: 1.1.0
- References
- ----------
- .. [1] Moody GB, Mark RG. The impact of the MIT-BIH Arrhythmia Database.
- IEEE Eng in Med and Biol 20(3):45-50 (May-June 2001).
- (PMID: 11446209); :doi:`10.13026/C2F305`
- .. [2] Goldberger AL, Amaral LAN, Glass L, Hausdorff JM, Ivanov PCh,
- Mark RG, Mietus JE, Moody GB, Peng C-K, Stanley HE. PhysioBank,
- PhysioToolkit, and PhysioNet: Components of a New Research Resource
- for Complex Physiologic Signals. Circulation 101(23):e215-e220;
- :doi:`10.1161/01.CIR.101.23.e215`
- Examples
- --------
- >>> from scipy.misc import electrocardiogram
- >>> ecg = electrocardiogram()
- >>> ecg
- array([-0.245, -0.215, -0.185, ..., -0.405, -0.395, -0.385])
- >>> ecg.shape, ecg.mean(), ecg.std()
- ((108000,), -0.16510875, 0.5992473991177294)
- As stated the signal features several areas with a different morphology.
- E.g., the first few seconds show the electrical activity of a heart in
- normal sinus rhythm as seen below.
- >>> import numpy as np
- >>> import matplotlib.pyplot as plt
- >>> fs = 360
- >>> time = np.arange(ecg.size) / fs
- >>> plt.plot(time, ecg)
- >>> plt.xlabel("time in s")
- >>> plt.ylabel("ECG in mV")
- >>> plt.xlim(9, 10.2)
- >>> plt.ylim(-1, 1.5)
- >>> plt.show()
- After second 16, however, the first premature ventricular contractions, also
- called extrasystoles, appear. These have a different morphology compared to
- typical heartbeats. The difference can easily be observed in the following
- plot.
- >>> plt.plot(time, ecg)
- >>> plt.xlabel("time in s")
- >>> plt.ylabel("ECG in mV")
- >>> plt.xlim(46.5, 50)
- >>> plt.ylim(-2, 1.5)
- >>> plt.show()
- At several points large artifacts disturb the recording, e.g.:
- >>> plt.plot(time, ecg)
- >>> plt.xlabel("time in s")
- >>> plt.ylabel("ECG in mV")
- >>> plt.xlim(207, 215)
- >>> plt.ylim(-2, 3.5)
- >>> plt.show()
- Finally, examining the power spectrum reveals that most of the biosignal is
- made up of lower frequencies. At 60 Hz the noise induced by the mains
- electricity can be clearly observed.
- >>> from scipy.signal import welch
- >>> f, Pxx = welch(ecg, fs=fs, nperseg=2048, scaling="spectrum")
- >>> plt.semilogy(f, Pxx)
- >>> plt.xlabel("Frequency in Hz")
- >>> plt.ylabel("Power spectrum of the ECG in mV**2")
- >>> plt.xlim(f[[0, -1]])
- >>> plt.show()
- """
- import os
- file_path = os.path.join(os.path.dirname(__file__), "ecg.dat")
- with load(file_path) as file:
- ecg = file["ecg"].astype(int) # np.uint16 -> int
- # Convert raw output of ADC to mV: (ecg - adc_zero) / adc_gain
- ecg = (ecg - 1024) / 200.0
- return ecg
|