CTR-Pia  5.4.3
Game Communication Engine
 全て クラス ネームスペース 関数 変数 型定義 列挙型 列挙型の値 ページ
common_LatestMedian.h
1 /*--------------------------------------------------------------------------------*
2  Copyright (C)Nintendo All rights reserved.
3 
4  These coded instructions, statements, and computer programs contain proprietary
5  information of Nintendo and/or its licensed developers and are protected by
6  national and international copyright laws. They may not be disclosed to third
7  parties or copied or duplicated in any form, in whole or in part, without the
8  prior written consent of Nintendo.
9 
10  The content herein is highly confidential and should be handled accordingly.
11  *--------------------------------------------------------------------------------*/
12 
13 
14 #pragma once
15 
16 #include <nn/pia/common/common_Definitions.h>
17 
18 #include <nn/pia/common/common_FixedRingBuffer.h>
19 
20 #include <algorithm>
21 
22 
23 namespace nn
24 {
25 namespace pia
26 {
27 namespace common
28 {
29 
30 
31 /*!
32  @cond PRIVATE
33  @brief 最新 N 個の値から、メジアン(中央値)を求めるためのクラスです。
34 
35  */
36 template <typename T, int N>
37 class LatestMedian : public common::RootObject
38 {
39 public:
40  /*!
41  @brief デフォルトコンストラクタです。
42  */
43  LatestMedian(void)
44  {
45  Clear();
46  }
47 
48 
49  /*!
50  @brief デストラクタです。
51  */
52  ~LatestMedian(void)
53  {
54  }
55 
56 
57  /*!
58  @brief 要素をクリアします。コンストラクタ実行直後の状態に戻ります。
59  */
60  void Clear(void)
61  {
62  m_Values.Clear();
63  }
64 
65 
66  /*!
67  @brief 最新の値を追加します。保持できる値は N 個のみなので、最も旧い値は捨てられます。
68  */
69  void Add(T value)
70  {
71  m_Values.PushBackForce(value);
72  }
73 
74 
75  /*!
76  @brief メジアンを取得します。内部でソート処理などを実行しているので、頻繁に呼び出すのは推奨しません。
77  要素が空の時に呼び出された場合は、 0 を返します。
78  */
79  T GetMedian(void) const
80  {
81  return GetMedian(N);
82  }
83 
84 
85  /*!
86  @brief 直近の n 個の値を対象にしたメジアンを取得します。
87  直近の値の個数が n 未満の場合は、それらの値から
88  メジアンを算出します。
89  内部でソート処理などを実行しているので、頻繁に呼び出すのは推奨しません。
90  要素が空の時に呼び出された場合は、 0 を返します。
91  */
92  T GetMedian(uint32_t n) const
93  {
94  PIA_ASSERT(n <= N);
95 
96  // 要素数のチェック。
97  uint32_t sz = m_Values.GetSize();
98  PIA_ASSERT(sz <= N);
99  if (sz == 0)
100  {
101  return 0; // 要素が空のときは、 0 を返すと約束。
102  }
103 
104  // 直近の値の個数が n 未満の場合は、それらの値からメジアンを算出します。
105  uint32_t num = (sz < n) ? sz : n; // num は今回使用するサンプリング値の個数。
106 
107  // 配列を別に用意し、ソートする。
108  // 直近の値 num 個が欲しいので、配列の後ろから値を読み出していく。
109  T buf[N];
110  for (uint32_t i = 0; i < num; ++i)
111  {
112  uint32_t idx = sz - 1 - i; // sz - 1は配列最後の添え字
113  buf[i] = m_Values[idx];
114  }
115  std::sort(buf, buf + num);
116 
117  // 中央値の添え字を取得。要素数の偶数/奇数により、メジアンの算出方法は変わる。
118  int midIdx = num / 2;
119  if (num % 2 == 0)
120  {
121  return static_cast<T>(buf[midIdx - 1] + buf[midIdx]) / static_cast<T>(2);
122  }
123  else
124  {
125  return buf[midIdx];
126  }
127  }
128 
129 
130  /*!
131  @brief 要素が空であるかどうかを判定します。
132  */
133  bool IsEmpty(void) const
134  {
135  return m_Values.IsEmpty();
136  }
137 
138 
139  /*!
140  @brief 要素が満杯であるかどうかを判定します。
141  */
142  bool IsFull(void) const
143  {
144  return m_Values.IsFull();
145  }
146 
147 
148  /*!
149  @brief 要素数を返します。
150  */
151  int32_t GetSize(void) const
152  {
153  int32_t ret = static_cast<int32_t>(m_Values.GetSize());
154  PIA_ASSERT(ret >= 0);
155  return ret;
156  }
157 
158 
159  /*!
160  @brief デバッグに有用な情報をプリントします。
161 
162  @param[in] flag トレースフラグの論理和。詳細は@ref TraceFlag 型を参照してください。
163  */
164  void Trace(uint64_t flag) const
165  {
166  (void)flag; // not implemented...
167  }
168 
169 
170 private:
171  FixedRingBuffer<T, N> m_Values;
172 };
173 //! @endcond
174 }
175 }
176 } // end of namespace nn::pia::common