dapodom.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. /*********************************************************************
  2. * Copyright 1993, UCAR/Unidata
  3. * See netcdf/COPYRIGHT file for copying and redistribution conditions.
  4. * $Header: /upc/share/CVS/netcdf-3/libncdap3/dapodom.c,v 1.12 2010/05/27 21:34:08 dmh Exp $
  5. *********************************************************************/
  6. #include "ncdap3.h"
  7. #include "dapodom.h"
  8. /**********************************************/
  9. /* Define methods for a dimension dapodometer*/
  10. Dapodometer*
  11. newdapodometer(DCEslice* slices, unsigned int first, unsigned int rank)
  12. {
  13. int i;
  14. Dapodometer* odom = (Dapodometer*)calloc(1,sizeof(Dapodometer));
  15. MEMCHECK(odom,NULL);
  16. if(rank == 0) {
  17. return newdapodometer1(1);
  18. }
  19. odom->rank = rank;
  20. ASSERT(odom->rank <= NC_MAX_VAR_DIMS);
  21. for(i=0;i<odom->rank;i++) {
  22. DCEslice* slice = slices+(first+i);
  23. odom->slices[i] = *slice;
  24. odom->index[i] = odom->slices[i].first;
  25. }
  26. return odom;
  27. }
  28. Dapodometer*
  29. newsimpledapodometer(DCEsegment* segment, unsigned int rank)
  30. {
  31. int i;
  32. Dapodometer* odom = (Dapodometer*)calloc(1,sizeof(Dapodometer));
  33. MEMCHECK(odom,NULL);
  34. if(rank == 0) {
  35. return newdapodometer1(1);
  36. }
  37. odom->rank = rank;
  38. assert(odom->rank <= NC_MAX_VAR_DIMS);
  39. assert(segment->slicesdefined && segment->slicesdeclized);
  40. for(i=0;i<odom->rank;i++) {
  41. DCEslice* odslice = &odom->slices[i];
  42. DCEslice* segslice = &segment->slices[i];
  43. odslice->first = 0;
  44. odslice->stride = 1;
  45. odslice->declsize = segslice->count;
  46. odslice->length = odslice->declsize;
  47. odslice->stop = odslice->declsize;
  48. odslice->count = odslice->declsize;
  49. odom->index[i] = 0;
  50. }
  51. return odom;
  52. }
  53. Dapodometer*
  54. newdapodometer1(unsigned int count)
  55. {
  56. Dapodometer* odom = (Dapodometer*)calloc(1,sizeof(Dapodometer));
  57. MEMCHECK(odom,NULL);
  58. odom->rank = 1;
  59. odom->slices[0].first = 0;
  60. odom->slices[0].length = count;
  61. odom->slices[0].stride = 1;
  62. odom->slices[0].stop = count;
  63. odom->slices[0].declsize = count;
  64. odom->slices[0].count = count;
  65. odom->index[0] = 0;
  66. return odom;
  67. }
  68. void
  69. freedapodometer(Dapodometer* odom)
  70. {
  71. if(odom) free(odom);
  72. }
  73. char*
  74. dapodometerprint(Dapodometer* odom)
  75. {
  76. int i;
  77. static char line[1024];
  78. char tmp[64];
  79. line[0] = '\0';
  80. if(odom->rank == 0) {
  81. strcat(line,"[]");
  82. } else for(i=0;i<odom->rank;i++) {
  83. sprintf(tmp,"[%lu/%lu:%lu:%lu]",
  84. (unsigned long)odom->index[i],
  85. (unsigned long)odom->slices[i].first,
  86. (unsigned long)odom->slices[i].stride,
  87. (unsigned long)odom->slices[i].length);
  88. strcat(line,tmp);
  89. }
  90. return line;
  91. }
  92. int
  93. dapodometermore(Dapodometer* odom)
  94. {
  95. return (odom->index[0] < odom->slices[0].stop);
  96. }
  97. void
  98. dapodometerreset(Dapodometer* odom)
  99. {
  100. int rank = odom->rank;
  101. while(rank-- > 0) {odom->index[rank] = odom->slices[rank].first;}
  102. }
  103. /* Convert current dapodometer settings to a single integer count*/
  104. size_t
  105. dapodometercount(Dapodometer* odom)
  106. {
  107. int i;
  108. size_t offset = 0;
  109. for(i=0;i<odom->rank;i++) {
  110. offset *= odom->slices[i].declsize;
  111. offset += odom->index[i];
  112. }
  113. return offset;
  114. }
  115. /*
  116. Given a dapodometer, compute the total
  117. number of elements in its space
  118. as determined by declsize; start at
  119. offset wheel
  120. */
  121. size_t
  122. dapodometerspace(Dapodometer* odom, unsigned int wheel)
  123. {
  124. unsigned int i,rank = odom->rank;
  125. size_t count = 1;
  126. DCEslice* slice;
  127. ASSERT((wheel < rank));
  128. slice = odom->slices+wheel;
  129. for(i=wheel;i<rank;i++,slice++) {
  130. count *= slice->declsize;
  131. }
  132. return count;
  133. }
  134. /*
  135. Compute the number of elements
  136. that will be returned as the odometer
  137. is incremented to its stop point.
  138. */
  139. size_t
  140. dapodometerpoints(Dapodometer* odom)
  141. {
  142. unsigned int i,rank = odom->rank;
  143. size_t count = 1;
  144. DCEslice* slice = odom->slices;
  145. for(i=0;i<rank;i++,slice++) {
  146. size_t slicecount = (slice->length/slice->stride);
  147. count *= slicecount;
  148. }
  149. return count;
  150. }
  151. int
  152. dapodometerincr(Dapodometer* odom)
  153. {
  154. return dapodometerincrith(odom,-1);
  155. }
  156. int
  157. dapodometerincrith(Dapodometer* odom, int wheel)
  158. {
  159. int i; /* do not make unsigned */
  160. DCEslice* slice;
  161. if(odom->rank == 0) return 0;
  162. if(wheel < 0) wheel = (odom->rank - 1);
  163. for(slice=odom->slices+(wheel),i=wheel;i>=0;i--,slice--) {
  164. odom->index[i] += slice->stride;
  165. if(odom->index[i] < slice->stop) break;
  166. if(i == 0) return 0; /* leave the 0th entry if it overflows*/
  167. odom->index[i] = slice->first; /* reset this position*/
  168. }
  169. return 1;
  170. }
  171. /**************************************************/
  172. int
  173. dapodometervarmcount(Dapodometer* odom, const ptrdiff_t* steps, const size_t* declsizes)
  174. {
  175. int i;
  176. size_t offset = 0;
  177. for(i=0;i<odom->rank;i++) {
  178. size_t tmp;
  179. tmp = odom->index[i];
  180. tmp = tmp - odom->slices[i].first;
  181. tmp = tmp / odom->slices[i].stride;
  182. tmp = tmp * steps[i];
  183. offset += tmp;
  184. }
  185. return offset;
  186. }
  187. /* Return the current set of indices */
  188. size_t*
  189. dapodometerindices(Dapodometer* odom)
  190. {
  191. if(odom == NULL) return NULL;
  192. return odom->index;
  193. }
  194. Dapodometer*
  195. newdapodometer2(const size_t* start, const size_t* count, const ptrdiff_t* stride,
  196. unsigned int first, unsigned int rank)
  197. {
  198. int i;
  199. Dapodometer* odom = (Dapodometer*)calloc(1,sizeof(Dapodometer));
  200. MEMCHECK(odom,NULL);
  201. odom->rank = rank;
  202. assert(odom->rank <= NC_MAX_VAR_DIMS);
  203. for(i=0;i<odom->rank;i++) {
  204. odom->slices[i].first = start[first+i];
  205. odom->slices[i].stride = (size_t)stride[first+i];
  206. odom->slices[i].length = count[first+i] * stride[first+i];
  207. odom->slices[i].stop = (odom->slices[i].first+odom->slices[i].length);
  208. odom->slices[i].declsize = odom->slices[i].stop;
  209. odom->slices[i].count = (odom->slices[i].length /odom->slices[i].stride);
  210. odom->index[i] = odom->slices[i].first;
  211. }
  212. return odom;
  213. }
  214. Dapodometer*
  215. newdapodometer3(int rank, size_t* dimsizes)
  216. {
  217. int i;
  218. Dapodometer* odom = (Dapodometer*)calloc(1,sizeof(Dapodometer));
  219. MEMCHECK(odom,NULL);
  220. odom->rank = rank;
  221. for(i=0;i<rank;i++) {
  222. odom->slices[i].first = 0;
  223. odom->slices[i].length = dimsizes[i];
  224. odom->slices[i].stride = 1;
  225. odom->slices[i].stop = dimsizes[i];
  226. odom->slices[i].declsize = dimsizes[i];
  227. odom->slices[i].count = (odom->slices[i].length / odom->slices[i].stride);
  228. odom->index[i] = 0;
  229. }
  230. return odom;
  231. }