14a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*---------------------------------------------------------------------------*
24a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  specnorm.c  *
34a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
44a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  Copyright 2007, 2008 Nuance Communciations, Inc.                               *
54a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
64a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  Licensed under the Apache License, Version 2.0 (the 'License');          *
74a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  you may not use this file except in compliance with the License.         *
84a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
94a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  You may obtain a copy of the License at                                  *
104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0                           *
114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software      *
134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  distributed under the License is distributed on an 'AS IS' BASIS,        *
144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  See the License for the specific language governing permissions and      *
164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  limitations under the License.                                           *
174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *---------------------------------------------------------------------------*/
194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#ifndef _RTT
224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <stdio.h>
234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <stdlib.h>
254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <math.h>
264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <string.h>
274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <assert.h>
284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "duk_err.h"
304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "specnorm.h"
314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "portable.h"
324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define DEBUG   0
344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic const char specnorm[] = "$Id: specnorm.c,v 1.2.10.7 2007/10/15 18:06:24 dahan Exp $";
364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint copy_distribution_counts(spect_dist_info *spec, spect_dist_info *base);
384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint add_distribution_data(spect_dist_info *spec, int spec_val)
414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /*  Median calculations
434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  */
444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(spec);
454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if USE_MEDIAN
464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (spec_val < spec->low_entry) spec->low_counts += UNIT_SIZE;
474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  else if (spec_val > spec->high_entry) spec->high_counts += UNIT_SIZE;
484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  else spec->hist[spec_val - spec->low_entry] += UNIT_SIZE;
494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /*  Mean calculations
524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  */
534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if 1
544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->running_total += spec_val - spec->mean;
554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->running_total_devn += (spec_val - spec->mean)
564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                              * (spec_val - spec->mean);
574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#else
584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->running_total += spec_val;
594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->running_total_devn += spec_val * spec_val;
604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->count++;
634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (spec->estimate_period > 0 && spec->count >= spec->estimate_period)
644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    evaluate_parameters(spec);
664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    spec->gain_used = False;
674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    spec->count = 0;
684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return (1);
694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return (0);
714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid evaluate_parameters(spect_dist_info *spec)
744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(spec);
764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if USE_MEDIAN
774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  estimate_sv6(spec);
784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->median = estimate_percentile(spec, spec->estimate_percentile);
794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->perc_high = estimate_percentile(spec, 90);  /* check this value */
804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if USE_MEAN
824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  estimate_mean(spec, spec->forget_factor);
834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if USE_MEDIAN
854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  forget_distribution_counts(spec, spec->forget_factor);
864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->count = 0;
884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return;
894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if USE_MEDIAN
924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint estimate_percentile(spect_dist_info *spec, int percentile)
934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int ii, jj, count, cumval;
954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  long    accum = 0;
964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /*  Calculate the median
984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  */
994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(spec);
1004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (spec->count < MIN_COUNT) return(spec->median);
1014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (percentile == 0)
1024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    percentile = spec->estimate_percentile;
1034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  count = spec->low_counts + spec->high_counts;
1044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (ii = 0; ii <= (spec->high_entry - spec->low_entry); ii++)
1054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    count += spec->hist[ii];
1064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  count = (count * percentile) / 100;
1074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  cumval = spec->low_counts;
1094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (ii = 0; ii <= (spec->high_entry - spec->low_entry)
1104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       && cumval < count; ii++)
1114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    cumval += spec->hist[ii];
1124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  count = 0;
1144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (jj = ii; jj <= (spec->high_entry - spec->low_entry); jj++)
1154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
1164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    count += spec->hist[jj];
1174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    accum += spec->hist[jj] * (jj - ii);
1184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG
1204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (count > 0)
1214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    log_report("Median margin %d\n", accum / count);
1224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
1234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return (spec->low_entry + ii);
1244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
1254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid estimate_sv6(spect_dist_info *spec)
1274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
1284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int ii, jj, count, span, totcount;
1294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  long    accum;
1304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /*  Calculate the median
1324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  */
1334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(spec);
1344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (spec->count < MIN_COUNT) return;
1354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  count = spec->high_counts;
1364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  accum = 0;
1374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  span = spec->high_entry - spec->low_entry;
1384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (ii = 0, jj = spec->high_entry - spec->low_entry;
1394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       ii <= span; ii++, jj--)
1404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
1414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    count += spec->hist[jj];
1424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    accum += spec->hist[jj] * ii;
1434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (count > 0 && (ii - accum / count) > spec->sv6_margin)
1444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      break;
1454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  totcount = count;
1484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (; ii <= span; ii++, jj--)
1494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    totcount += spec->hist[jj];
1504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  totcount += spec->high_counts;
1514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG
1534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  log_report("SV6 (%d) Percentage %d, %d, %d\n", spec->sv6_margin,
1544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project             (count * 100) / totcount,
1554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project             totcount, spec->count);
1564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
1574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (count > 0)
1584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    spec->sv6 = spec->high_entry - accum / count;
1594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return;
1604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
1614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
1624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid estimate_mean(spect_dist_info *spec, int forget_factor)
1644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
1654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /*  Calculate the mean and standard deviation
1664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  */
1674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(spec);
1684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (spec->count < MIN_COUNT) return;
1694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG
1704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  log_report("old mean= %d, ", spec->mean);
1714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
1724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->mean_count = (spec->mean_count * (100 - forget_factor)) / 100;
1734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->mean_count += spec->count;
1744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (spec->mean_count > 0)
1754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
1764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    spec->devn = spec->running_total_devn / spec->mean_count
1774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                 - (spec->running_total * spec->running_total)
1784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                 / (spec->mean_count * spec->mean_count);
1794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    spec->devn = (int) sqrt((double)  spec->devn);
1804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (spec->running_total >= 0)
1814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      spec->mean += (spec->running_total + spec->mean_count / 2)
1824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    / spec->mean_count;
1834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else
1844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      spec->mean += (spec->running_total - spec->mean_count / 2)
1854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                    / spec->mean_count;
1864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG
1884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  log_report("accumulates= %d and %d (%d), ", spec->running_total,
1894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project             spec->mean_count, spec->count);
1904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  log_report("new mean= %d\n", spec->mean);
1914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
1924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->running_total = 0;
1934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->running_total_devn = 0;
1944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return;
1964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
1974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if USE_MEDIAN
1994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint median_normalize_data(spect_dist_info *spec, int spec_val)
2004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
2014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return (spec_val - spec->median + spec->offset);
2024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
2034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint sv6_normalize_data(spect_dist_info *spec, int spec_val)
2054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
2064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return (spec_val - spec->sv6 + spec->offset);
2074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
2084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
2094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint mean_normalize_data(spect_dist_info *spec, int spec_val)
2114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
2124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return (spec_val - spec->mean + spec->offset);
2134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
2144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectspect_dist_info *create_spectrum_distribution(int offset, int initial_median,
2164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int low_entry, int high_entry,
2174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int forget_factor, int estimate_period,
2184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int estimate_percentile,
2194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int sv6_margin)
2204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
2214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spect_dist_info *spec;
2224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (high_entry < low_entry) return(NULL);
2244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec = (spect_dist_info *) CALLOC_CLR(1,
2264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project         sizeof(spect_dist_info), "clib.spec");
2274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (estimate_period == 0) /* basically disable 0 as an estimate period */
2284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    spec->estimate_period = 1;
2294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  else
2304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    spec->estimate_period = estimate_period;
2314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->forget_factor = forget_factor;
2324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->offset = offset;
2334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if USE_MEDIAN
2354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->hist = (long *) CALLOC_CLR(high_entry - low_entry + 1,
2364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                         sizeof(int), "clib.spec.hist");
2374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->low_entry = low_entry;
2384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->high_entry = high_entry;
2394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->median = initial_median;
2404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->estimate_percentile = estimate_percentile;
2414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->sv6_margin = sv6_margin;
2424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  clear_distribution_counts(spec);
2434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
2444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if USE_MEAN
2454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->mean = initial_median;
2464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->devn = 0;
2474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  clear_mean_counts(spec);
2484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
2494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->sv6 = initial_median;
2504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return (spec);
2524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
2534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid destroy_spectrum_distribution(spect_dist_info *spec)
2554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
2564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(spec);
2574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if USE_MEDIAN
2584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  FREE((char *)spec->hist);
2594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
2604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  FREE((char *)spec);
2614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return;
2624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
2634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if USE_MEDIAN
2654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid clear_distribution_counts(spect_dist_info *spec)
2664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
2674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int ii;
2684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(spec);
2704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->high_counts = 0;
2714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->low_counts = 0;
2724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->count = 0;
2734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (ii = 0; ii <= (spec->high_entry - spec->low_entry); ii++)
2744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    spec->hist[ii] = 0;
2754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return;
2764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
2774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint copy_distribution_counts(spect_dist_info *spec, spect_dist_info *base)
2794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
2804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int ii;
2814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(spec);
2834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(base);
2844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(spec->hist);
2854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(base->hist);
2864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (base->low_entry != spec->low_entry ||
2874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      base->high_entry != spec->high_entry)
2884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return (False);
2894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->high_counts = base->high_counts;
2904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->low_counts = base->low_counts;
2914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (ii = 0; ii <= (spec->high_entry - spec->low_entry); ii++)
2924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    spec->hist[ii] = base->hist[ii];
2934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return (True);
2944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
2954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid forget_distribution_counts(spect_dist_info *spec, int forget_factor)
2974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
2984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int ii, remember;
2994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(spec);
3014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /*    remember= 100 - (forget_factor * spec->count)/spec->estimate_period; */
3024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  remember = 100 - forget_factor;
3034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->high_counts = (spec->high_counts * remember) / 100;
3044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->low_counts = (spec->low_counts * remember) / 100;
3054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  for (ii = 0; ii <= (spec->high_entry - spec->low_entry); ii++)
3064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    spec->hist[ii] = (spec->hist[ii] * remember) / 100;
3074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return;
3084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
3094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid shift_distribution_counts(spect_dist_info *spec, int shift)
3114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
3124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  int ii;
3134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(spec);
3154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (shift > 0)
3164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
3174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (shift > (spec->high_entry - spec->low_entry))
3184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      SERVICE_ERROR(UNEXPECTED_DATA_ERROR); /* TODO: find a new error code */
3194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (ii = 0; ii < shift; ii++)
3204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      spec->high_counts += spec->hist[spec->high_entry
3214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                      - spec->low_entry - shift + ii];
3224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    MEMMOVE(&spec->hist[shift], spec->hist,
3244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            (spec->high_entry - spec->low_entry - shift + 1),
3254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            sizeof(int));
3264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (ii = 0; ii < shift; ii++)
3274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      spec->hist[ii] = 0;
3284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
3294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  else if (shift < 0)
3304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
3314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (shift < (spec->low_entry - spec->high_entry))
3324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      SERVICE_ERROR(UNEXPECTED_DATA_ERROR); /* TODO: find a new error code */
3334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (ii = 0; ii < -shift; ii++)
3344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      spec->low_counts += spec->hist[ii];
3354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    MEMMOVE(spec->hist, spec->hist - shift,
3374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            (spec->high_entry - spec->low_entry + shift + 1),
3384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            sizeof(int));
3394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (ii = shift; ii < 0; ii++)
3404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      spec->hist[ii + spec->high_entry - spec->low_entry + 1] = 0;
3414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
3424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return;
3434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
3444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
3454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid clear_mean_counts(spect_dist_info *spec)
3474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
3484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(spec);
3494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->mean_count = 0;
3504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->count = 0;
3514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->running_total = 0;
3524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->running_total_devn = 0;
3534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return;
3544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
3554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid shift_parameters(spect_dist_info *spec, int shift)
3574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
3584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ASSERT(spec);
3594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->mean += shift;
3604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if USE_MEDIAN
3614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->median += shift;
3624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  spec->sv6 += shift;
3634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif
3644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return;
3654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
366