docstr: forward.
  FIXME:
  - Some times it will be a slightly different from the result from `pandas.corr()`
  - It may be caused by the precision problem of model;
  
  :param pred:
  :param y:
  :param idx: Assume the level of the idx is (date, inst), and it is sorted
docstr_tok: ["forward",".","FIXME",":","-","Some","times","it","will","be","a","slightly","different","from","the","result","from","`","pandas.corr","(",")","`","-","It","may","be","caused","by","the","precision","problem","of","model",";",":","param","pred",":",":","param","y",":",":","param","idx",":","Assume","the","level","of","the","idx","is","(","date",",","inst",")",",","and","it","is","sorted"]
code: def forward(self, pred, y, idx, skip_size=50):
      """forward.
      FIXME:
      - Some times it will be a slightly different from the result from `pandas.corr()`
      - It may be caused by the precision problem of model;
  
      :param pred:
      :param y:
      :param idx: Assume the level of the idx is (date, inst), and it is sorted
      """
      prev = None
      diff_point = []
      for i, (date, inst) in enumerate(idx):
          if date != prev:
              diff_point.append(i)
          prev = date
      diff_point.append(None)
      # The lengths of diff_point will be one more larger then diff_point
  
      ic_all = 0.0
      skip_n = 0
      for start_i, end_i in zip(diff_point, diff_point[1:]):
          pred_focus = pred[start_i:end_i]  # TODO: just for fake
          if pred_focus.shape[0] < skip_size:
              # skip some days which have very small amount of stock.
              skip_n += 1
              continue
          y_focus = y[start_i:end_i]
          if pred_focus.std() < EPS or y_focus.std() < EPS:
              # These cases often happend at the end of test data.
              # Usually caused by fillna(0.)
              skip_n += 1
              continue
  
          ic_day = torch.dot(
              (pred_focus - pred_focus.mean())
              / np.sqrt(pred_focus.shape[0])
              / pred_focus.std(),
              (y_focus - y_focus.mean())
              / np.sqrt(y_focus.shape[0])
              / y_focus.std(),
          )
          ic_all += ic_day
      if len(diff_point) - 1 - skip_n <= 0:
          raise ValueError("No enough data for calculating IC")
      if skip_n > 0:
          get_module_logger("ICLoss").info(
              f"{skip_n} days are skipped due to zero std or small scale of valid samples."
          )
      ic_mean = ic_all / (len(diff_point) - 1 - skip_n)
      return -ic_mean
  
file_path: qlib/qlib/contrib/meta/data_selection/utils.py
imports: import numpy
  import torch
  from torch import nn
  from qlib.constant import EPS
  from qlib.log import get_module_logger
label_desc: Use image node_id 1 for calling the ICLoss obj's underlying member method code with example usage: obj.forward(pred, y, idx, skip_size) and returns: unknown