Skip to content

jsh9/fast-konno-ohmachi

Repository files navigation

Fast Konno-Ohmachi

A Python library that performs Konno-Ohmachi spectral smoothing very fast (2x speedup compared to the "vanilla" Konno-Ohmachi smoothing algorithm).

Background

Konno-Ohmachi is a smoothing algorithm proposed by Konno & Ohmachi (1998) [abstract, PDF], which achieves a "uniform-span" smoothing to frequency spectra in the logarithmic scale.

For lower frequencies, the Konno-Ohmachi smoothing window is narrower (i.e., less smoothing), and for higher frequencies, the window is wider (i.e., more smoothing).

This makes the Konno-Ohmachi filter particularly appealing to seismologists, who often try to avoid over-smoothing lower frequencies (< 10 Hz) of seismic wave signals.

The plot below shows the result of Konno-Ohmachi filter versus a regular median value filter. The two filters yield similar results for frequency > 5 Hz, but for lower frequencies, the median filter over-smoothes the original signal, which is undesirable.

(The raw signal used in this example is the Fourier amplitude spectrum of a ground acceleration waveform recorded during the Magnitude-9.0 Tohoku-Oki Earthquake on March 11, 2011.)

Computation speed

Conventionally, Konno-Ohmachi filtering is time-consuming because its smoothing windows are different at each frequency and need to be calculated one by one.

This library achieves a 2x speedup by pre-calculating smoothing windows (i.e., trading memory space for speed).

It can speed up calculation even further by performing parallel computing (the faster_konno_ohmachi() function).

The only minor compromises in order to achieve the 2x speedup are:

  • Only even integer smoothing strengths from 2 to 100 are supported. This is not an issue in reality because people rarely need non-integer smoothing strengths.
  • The smoothing results from fast_konno_ohmachi() and faster_konno_ohmachi() are not entirely identical to the smoothing result from slow_konno_ohmachi() (the "vanilla" algorithm). However, the differences are too minor to have any practical implications.

Installation

pip install fast-konno-ohmachi

Usage

import numpy as np
import fast_konno_ohmachi as fko

freq = np.arange(0, 2, 0.1)  # just an arbitrary example
signal = np.sin(freq)

smoothed = fko.fast_konno_ohmachi(signal, freq, smooth_coeff=40, progress_bar=True)

or (calculate in parallel)

smoothed = fko.faster_konno_ohmachi(signal, freq, smooth_coeff=40, n_cores=4)

or (if you'd like to see how slow the "vanilla" implementation can be)

smoothed = fko.slow_konno_ohmachi(signal, freq, smooth_coeff=40, progress_bar=True)

You can also try to run demo/Demo_konno_ohmachi_smooth.py to smooth a real-world signal. (You'd need scipy and matplotlib to run the demo script.)

Additional notes on parallel computing

  1. When using faster_konno_ohmachi(), the user should to protect the main script with if __name__ == '__main__' (see the demo script). This is mandatory for Windows, and highly recommended for Mac/Linux.
  2. The faster_konno_ohmachi() function uses multiple CPU cores, but it is not necessarily faster than fast_konno_ohmachi(), because the data I/O between the CPU cores takes extra time ("computation overhead"). Below is a benchmarking of the running time for input signals with different length:
Length of signal (x1000) 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31
Time of "fast" (sec) 0.1 0.4 0.9 1.5 2.2 3.3 4.4 5.4 6.8 8.1 9.6 11.2 13.1 14.9 16.7 18.8
Time of "faster" (sec) 2.4 2.4 2.8 3.0 3.3 3.9 4.1 4.6 4.9 5.5 5.8 6.7 7.5 8.2 9.0 9.8

Or as shown in this figure: