簡體   English   中英

用 hist function 計算直方圖的 MATLAB 算法是什么?

[英]What is MATLAB's algorithm to calculate histogram with hist function?

我正在將一些舊的 MATLAB 代碼翻譯成 C++。我注意到,我的自定義 function 計算直方圖應該等同於 MATLAB [counts,centers]= hist(___)給出不同的結果。 我在我的實現中找不到錯誤,所以我使用 MATLAB Coder 從 MATLAB 代碼生成 C++ function 並將其與我的 C++ 代碼進行比較。 這是一個簡單的 MATLAB function 我用來生成 C++ 的代碼:

function [counts, centers] = my_hist(values, bins)
    [counts, centers] = hist(values, bins);
    disp(centers);
    disp(counts);
end

以及調用它的腳本,因此 MATLAB 可以定義輸入:

values = rand(1,1000);
bins = linspace(0.05, 0.95, 10);

[counts, centers] = my_hist(values, bins);

基於以上,Coder生成function:

//
// File: my_hist.cpp
//
// MATLAB Coder version            : 5.3
// C/C++ source code generated on  : 17-Nov-2022 15:46:17
//

// Include Files
#include "my_hist.h"
#include "rt_nonfinite.h"
#include <algorithm>
#include <cmath>
#include <cstring>
#include <math.h>

// Function Definitions
//
// MY_HIST Summary of this function goes here
//    Detailed explanation goes here
//
// Arguments    : const double values[1000]
//                const double bins[10]
//                double counts[10]
//                double centers[10]
// Return Type  : void
//
void my_hist(const double values[1000], const double bins[10],
             double counts[10], double centers[10])
{
  double edges[11];
  double nn[11];
  double absx;
  int k;
  int low_i;
  std::copy(&bins[0], &bins[10], &centers[0]);
  for (k = 0; k < 9; k++) {
    absx = bins[k];
    edges[k + 1] = absx + (bins[k + 1] - absx) / 2.0;
  }
  edges[0] = rtMinusInf;
  edges[10] = rtInf;
  for (k = 0; k < 9; k++) {
    double absx_tmp;
    absx_tmp = edges[k + 1];
    absx = std::abs(absx_tmp);
    if ((!std::isinf(absx)) && (!std::isnan(absx))) {
      if (absx <= 2.2250738585072014E-308) {
        absx = 4.94065645841247E-324;
      } else {
        frexp(absx, &low_i);
        absx = std::ldexp(1.0, low_i - 53);
      }
    } else {
      absx = rtNaN;
    }
    edges[k + 1] = absx_tmp + absx;
  }
  std::memset(&nn[0], 0, 11U * sizeof(double));
  low_i = 1;
  int exitg1;
  do {
    exitg1 = 0;
    if (low_i + 1 < 12) {
      if (!(edges[low_i] >= edges[low_i - 1])) {
        for (low_i = 0; low_i < 11; low_i++) {
          nn[low_i] = rtNaN;
        }
        exitg1 = 1;
      } else {
        low_i++;
      }
    } else {
      for (k = 0; k < 1000; k++) {
        low_i = 0;
        absx = values[k];
        if (!std::isnan(absx)) {
          if ((absx >= edges[0]) && (absx < edges[10])) {
            int high_i;
            int low_ip1;
            low_i = 1;
            low_ip1 = 2;
            high_i = 11;
            while (high_i > low_ip1) {
              int mid_i;
              mid_i = (low_i + high_i) >> 1;
              if (values[k] >= edges[mid_i - 1]) {
                low_i = mid_i;
                low_ip1 = mid_i + 1;
              } else {
                high_i = mid_i;
              }
            }
          }
          if (values[k] == edges[10]) {
            low_i = 11;
          }
        }
        if (low_i > 0) {
          nn[low_i - 1]++;
        }
      }
      exitg1 = 1;
    }
  } while (exitg1 == 0);
  std::copy(&nn[0], &nn[10], &counts[0]);
  counts[9] += nn[10];
}

//
// File trailer for my_hist.cpp
//
// [EOF]
//

我不明白這段代碼中發生了什么以及為什么這樣做:

  for (k = 0; k < 9; k++) {
    double absx_tmp;
    absx_tmp = edges[k + 1];
    absx = std::abs(absx_tmp);
    if ((!std::isinf(absx)) && (!std::isnan(absx))) {
      if (absx <= 2.2250738585072014E-308) {
        absx = 4.94065645841247E-324;
      } else {
        frexp(absx, &low_i);
        absx = std::ldexp(1.0, low_i - 53);
      }
    } else {
      absx = rtNaN;
    }
    edges[k + 1] = absx_tmp + absx;
  }

function 移動垃圾箱的邊緣,但是如何以及為什么? 我將不勝感激幫助和解釋!

那段代碼將eps添加到除第一個和最后一個之外的每個 bin 邊緣。

很難知道hist為什么這樣做,他們一定是在解決他們發現的一些邊緣情況(可能與浮點舍入錯誤有關),並認為這是最好或最簡單的解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM