<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def corr_dim(data, emb_dim, rvals=None, dist=rowwise_euclidean, fit="RANSAC", debug_plot=False, debug_data=False, plot_file=None):
 """ Calculates the correlation dimension with the Grassberger-Procaccia algorithm Explanation of correlation dimension: The correlation dimension is a characteristic measure that can be used to describe the geometry of chaotic attractors. It is defined using the correlation sum C(r) which is the fraction of pairs of points X_i in the phase space whose distance is smaller than r. If the relation between C(r) and r can be described by the power law C(r) ~ r^D then D is called the correlation dimension of the system. In a d-dimensional system, the maximum value for D is d. This value is obtained for systems that expand uniformly in each dimension with time. The lowest possible value is 0 for a system with constant C(r) (i.e. a system that visits just one point in the phase space). Generally if D is lower than d and the system has an attractor, this attractor is called "strange" and D is a measure of this "strangeness". Explanation of the algorithm: The Grassberger-Procaccia algorithm calculates C(r) for a range of different r and then fits a straight line into the plot of log(C(r)) versus log(r). This version of the algorithm is created for one-dimensional (scalar) time series. Therefore, before calculating C(r), a delay embedding of the time series is performed to yield emb_dim dimensional vectors value for emb_dim allows to reconstruct higher dimensional dynamics and avoids "systematic errors due to corrections to scaling". References: .. [cd_1] P. Grassberger and I. Procaccia, “Characterization of strange attractors,” Physical review letters, vol. 50, no. 5, p. 346, 1983. .. [cd_2] P. Grassberger and I. Procaccia, “Measuring the strangeness of strange attractors,” Physica D: Nonlinear Phenomena, vol. 9, no. 1, pp. 189–208, 1983. .. [cd_3] P. Grassberger, “Grassberger-Procaccia algorithm,” Scholarpedia, vol. 2, no. 5, p. 3043. urL: http://www.scholarpedia.org/article/Grassberger-Procaccia_algorithm Reference Code: .. [cd_a] "corrDim" function in R package "fractal", url: https://cran.r-project.org/web/packages/fractal/fractal.pdf .. [cd_b] Peng Yuehua, "Correlation dimension", url: http://de.mathworks.com/matlabcentral/fileexchange/24089-correlation-dimension Args: data (array-like of float):
 time series of data points emb_dim (int):
 embedding dimension Kwargs: rvals (iterable of float):
 list of values for to use for r (default: logarithmic_r(0.1 * std, 0.5 * std, 1.03)) dist (function (2d-array, 1d-array) -> 1d-array):
 row-wise difference function fit (str):
 the fitting method to use for the line fit, either 'poly' for normal least squares polynomial fitting or 'RANSAC' for RANSAC-fitting which is more robust to outliers debug_plot (boolean):
 if True, a simple plot of the final line-fitting step will be shown debug_data (boolean):
 if True, debugging data will be returned alongside the result plot_file (str):
 if debug_plot is True and plot_file is not None, the plot will be saved under the given file name instead of directly showing it through ``plt.show()`` Returns: float: correlation dimension as slope of the line fitted to log(r) vs log(C(r)) (1d-vector, 1d-vector, list):
 only present if debug_data is True: debug data of the form ``(rvals, csums, poly)`` where ``rvals`` are the values used for log(r), ``csums`` are the corresponding log(C(r)) and ``poly`` are the line coefficients (``[slope, intercept]``) """

  data = np.asarray(data)

  # TODO what are good values for r?
  # TODO do this for multiple values of emb_dim?
  if rvals is None:
    sd = np.std(data)
    rvals = logarithmic_r(0.1 * sd, 0.5 * sd, 1.03)
  n = len(data)
  orbit = delay_embedding(data, emb_dim, lag=1)
  dists = np.array([dist(orbit, orbit[i]) for i in range(len(orbit))])
  csums = []
  for r in rvals:
    s = 1.0 / (n * (n - 1)) * np.sum(dists < r)
    csums.append(s)
  csums = np.array(csums)
  # filter zeros from csums
  nonzero = np.where(csums != 0)
  rvals = np.array(rvals)[nonzero]
  csums = csums[nonzero]
  if len(csums) == 0:
    # all sums are zero => we cannot fit a line
    poly = [np.nan, np.nan]
  else:
    poly = poly_fit(np.log(rvals), np.log(csums), 1)
  if debug_plot:
    plot_reg(np.log(rvals), np.log(csums), poly, "log(r)", "log(C(r))",
             fname=plot_file)
  if debug_data:
    return (poly[0], (np.log(rvals), np.log(csums), poly))
  else:
    return poly[0]