Interpolate.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /*
  2. * Licensed Materials - Property of HCL
  3. *
  4. * IBM Informix DataBlade Module
  5. * (C) Copyright International Business Machines Corporation 2002.
  6. * (c) Copyright HCL Technologies Ltd. 2017. All Rights Reserved.
  7. *
  8. * COPYRIGHT LICENSE:
  9. * This information contains sample application programs in source language,
  10. * which illustrate programming techniques on various operating platforms.
  11. * You may copy, modify, and distribute these sample programs in any form
  12. * without payment to IBM, for the purposes of developing, using, marketing
  13. * or distributing application programs conforming to the application
  14. * programming interface for the operating platform for which the sample
  15. * programs are written. These examples have not been thoroughly tested under
  16. * all conditions. IBM, therefore, cannot guarantee or imply reliability,
  17. * serviceability, or function of these programs. You may copy, modify, and
  18. * distribute these sample programs in any form without payment to IBM for
  19. * the purposes of developing, using, marketing, or distributing application
  20. * programs conforming to IBM's application programming interfaces.
  21. * Each copy or any portion of these sample programs or any derivative work,
  22. * must include a copyright notice as follows:
  23. * © (your company name) (year). Portions of this code are derived from
  24. * IBM Corp. Sample Programs. © Copyright IBM Corp. (enter the year or
  25. * years). All rights reserved.
  26. *
  27. */
  28. /*
  29. * SETUP:
  30. * create function Interp(TimeSeries) returns TimeSeries
  31. * external name 'Interpolate.so(ts_interp)'
  32. * language c not variant;
  33. *
  34. *
  35. * USAGE:
  36. * select Interp(stock_data) from daily_stocks where stock_id = 901;
  37. */
  38. #include <stdio.h>
  39. #include <mi.h>
  40. #include <tseries.h>
  41. # define TS_MAX_COLS 100
  42. # define DATATYPE "smallfloat"
  43. /*
  44. * This example interpolates between values to fill in null elements.
  45. * It assumes that all columns are of type smallfloat and that there are
  46. * less than 100 columns in each element.
  47. */
  48. #ifdef NT
  49. __declspec(dllexport)
  50. #endif
  51. ts_timeseries *
  52. ts_interp(tsPtr, fParamPtr)
  53. ts_timeseries *tsPtr;
  54. MI_FPARAM *fParamPtr;
  55. {
  56. ts_tsdesc *descPtr;
  57. ts_tselem tselem;
  58. ts_tscan *scan;
  59. MI_CONNECTION *conn;
  60. ts_typeinfo *typeinfo;
  61. int scancode;
  62. mi_real *values[TS_MAX_COLS];
  63. mi_real lastValues[TS_MAX_COLS], newValues[TS_MAX_COLS];
  64. mi_boolean nulls[TS_MAX_COLS];
  65. mi_integer minElem, curElem, elem;
  66. mi_integer i;
  67. mi_boolean noneYet;
  68. mi_integer ncols;
  69. char strbuf[100];
  70. /* get a connection for libmi */
  71. conn = mi_open(NULL,NULL,NULL);
  72. /* open a descriptor for the timeseries */
  73. descPtr = ts_open(conn, tsPtr, mi_fp_rettype(fParamPtr, 0), 0);
  74. if ((ncols = (mi_integer) mi_fp_funcstate(fParamPtr)) == 0) {
  75. ncols = ts_col_cnt(descPtr);
  76. if (ncols > TS_MAX_COLS) {
  77. sprintf(strbuf, "Timeseries elements have too many columns, 100 is the max, got %d instead.", ncols);
  78. mi_db_error_raise(NULL, MI_FATAL, strbuf, 0);
  79. }
  80. for (i = 1; i < ncols; i++) {
  81. typeinfo = ts_colinfo_number(descPtr, i);
  82. if (strlen(typeinfo->ti_typename) != strlen(DATATYPE) ||
  83. memcmp(typeinfo->ti_typename, DATATYPE, strlen(DATATYPE)) != 0){
  84. sprintf(strbuf, "column was not a %s, got %s instead.", DATATYPE, typeinfo->ti_typename);
  85. mi_db_error_raise(NULL, MI_FATAL, strbuf, 0);
  86. }
  87. }
  88. mi_fp_setfuncstate(fParamPtr, (void *) ncols);
  89. }
  90. noneYet = MI_TRUE;
  91. minElem = -1;
  92. curElem = 0;
  93. /* begin a scan of the whole timeseries */
  94. scan = ts_begin_scan(descPtr, 0, NULL, NULL);
  95. while ((scancode = ts_next(scan, &tselem)) != TS_SCAN_EOS) {
  96. switch(scancode) {
  97. case TS_SCAN_ELEM:
  98. /* if this element is not null expand its values */
  99. noneYet = MI_FALSE;
  100. ts_get_all_cols(descPtr, tselem, (void **) values, nulls, curElem);
  101. if (minElem == -1) {
  102. /* save each element */
  103. for (i = 1; i < ncols; i++)
  104. lastValues[i] = *values[i];
  105. }
  106. else {
  107. /* calculate the average */
  108. for (i = 1; i < ncols; i++) {
  109. newValues[i] = (*values[i] + lastValues[i])/2.0;
  110. lastValues[i] = *values[i];
  111. values[i] = &newValues[i];
  112. }
  113. /* update the missing elements */
  114. tselem = ts_make_elem(descPtr, (void **) values, nulls, &elem);
  115. for (elem = minElem; elem < curElem; elem++)
  116. ts_put_nth_elem(descPtr, tselem, elem);
  117. minElem = -1;
  118. }
  119. break;
  120. case TS_SCAN_NULL:
  121. if (noneYet)
  122. break;
  123. /* remember the first null element */
  124. if (minElem == -1)
  125. minElem = curElem;
  126. break;
  127. }
  128. curElem++;
  129. }
  130. ts_end_scan(scan);
  131. ts_close(descPtr);
  132. return(tsPtr);
  133. }