如何计算不同大小的数组在PhP中的协方差?

时间:2019-01-10 03:40:24

标签: php statistics covariance quantitative-finance

此函数计算相同大小的两个数组的协方差(例如$countA=$countB=20)。

如何将其扩展为不同大小的数组? (例如,要基于较小数组的大小进行计算,如果$countA=10$countB=12?较小的数组可能有多低,仍然具有统计意义?)

感谢一百万!

M

function getCovariance($valuesA, $valuesB){
  $countA=count($valuesA);
  $countB=count($valuesB);
  if($countA != $countB){
    trigger_error('Arrays with different sizes: countA='. $countA .', countB='. $countB, E_USER_WARNING);
    return false;
  }

  if($countA < 0){
    trigger_error('Empty arrays', E_USER_WARNING);
    return false;
  }

  // Use library function if available
  if(function_exists('stats_covariance')){
    return stats_covariance($valuesA, $valuesB);
  }

  $meanA=array_sum($valuesA) / floatval($countA);
  $meanB=array_sum($valuesB) / floatval($countB);
  $add=0.0;

  for ($pos=0; $pos < $countA; $pos++){
    $valueA=$valuesA[ $pos ];
    if(!is_numeric($valueA)){
      trigger_error('Not numerical value in array A at position '. $pos .', value='. $valueA, E_USER_WARNING);
      return false;
    }

    $valueB=$valuesB[ $pos ];
    if(!is_numeric($valueB)){
      trigger_error('Not numerical value in array B at position '. $pos .', value='. $valueB, E_USER_WARNING);
      return false;
    }

    $difA=$valueA - $meanA;
    $difB=$valueB - $meanB;
    $add += ($difA * $difB);
  }

  return $add / floatval($countA);
}

1 个答案:

答案 0 :(得分:1)

使用min()查找哪个数组中的项目最少,并以该数量的切片将它们切片。

function getCovariance($valuesA, $valuesB){
  // sizing both arrays the same, if different sizes, @Andreas @stackoverflow
  $no_keys = min(count($valuesA), count($valuesB));
  $valuesA = array_slice($valuesA, 0, $no_keys);
  $valuesB = array_slice($valuesB, 0, $no_keys);

  // if size of arrays is too small
  if($no_keys<2){return 0.0000000000001;}

  // Use library function if available
  if(function_exists('stats_covariance')){return stats_covariance($valuesA, $valuesB);}

  $meanA=array_sum($valuesA)/$no_keys;
  $meanB=array_sum($valuesB)/$no_keys;
  $add=0.0;

  for ($pos=0; $pos < $no_keys; $pos++){
    $valueA=$valuesA[ $pos ];
    if(!is_numeric($valueA)){
      trigger_error('Not numerical value in array A at position '. $pos .', value='. $valueA, E_USER_WARNING);
      return false;
    }

    $valueB=$valuesB[ $pos ];
    if(!is_numeric($valueB)){
      trigger_error('Not numerical value in array B at position '. $pos .', value='. $valueB, E_USER_WARNING);
      return false;
    }

    $difA=$valueA - $meanA;
    $difB=$valueB - $meanB;
    $add += ($difA * $difB);
  }

  return $add/$no_keys;
}