Vector.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. /* Vector.cpp
  2. *
  3. * Copyright (C) 1992-2009,2011,2012,2014-2018 Paul Boersma
  4. *
  5. * This code is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * This code is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. * See the GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this work. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "Vector.h"
  19. //
  20. // Vector::getVector () returns a channel or the average of all the channels.
  21. //
  22. double structVector :: v_getVector (integer irow, integer icol) {
  23. if (icol < 1 || icol > nx) return 0.0;
  24. if (ny == 1) return z [1] [icol]; // optimization
  25. if (irow == 0) {
  26. if (ny == 2) return 0.5 * (z [1] [icol] + z [2] [icol]); // optimization
  27. longdouble sum = 0.0;
  28. for (integer channel = 1; channel <= ny; channel ++)
  29. sum += z [channel] [icol];
  30. return double (sum / ny);
  31. }
  32. Melder_assert (irow > 0 && irow <= ny);
  33. return z [irow] [icol];
  34. }
  35. //
  36. // Vector::getFunction1 () returns a channel or the average of all the channels.
  37. //
  38. double structVector :: v_getFunction1 (integer irow, double x) {
  39. double rcol = (x - x1) / dx + 1.0;
  40. integer icol = Melder_ifloor (rcol);
  41. double dcol = rcol - icol;
  42. double z1;
  43. if (icol < 1 || icol > nx) {
  44. z1 = 0.0; // outside the definition region, Formula is expected to return zero
  45. } else if (ny == 1) {
  46. z1 = z [1] [icol]; // optimization
  47. } else if (irow == 0) {
  48. if (ny == 2) {
  49. z1 = 0.5 * (z [1] [icol] + z [2] [icol]); // optimization
  50. } else {
  51. longdouble sum = 0.0;
  52. for (integer channel = 1; channel <= ny; channel ++)
  53. sum += z [channel] [icol];
  54. z1 = double (sum / ny);
  55. }
  56. } else {
  57. Melder_assert (irow > 0 && irow <= ny);
  58. z1 = z [irow] [icol];
  59. }
  60. double z2;
  61. if (icol < 0 || icol >= nx) {
  62. z2 = 0.0; // outside the definition region, Formula is expected to return zero
  63. } else if (ny == 1) {
  64. z2 = z [1] [icol + 1]; // optimization
  65. } else if (irow == 0) {
  66. if (ny == 2) {
  67. z2 = 0.5 * (z [1] [icol + 1] + z [2] [icol + 1]); // optimization
  68. } else {
  69. longdouble sum = 0.0;
  70. for (integer channel = 1; channel <= ny; channel ++)
  71. sum += z [channel] [icol + 1];
  72. z2 = double (sum / ny);
  73. }
  74. } else {
  75. Melder_assert (irow > 0 && irow <= ny);
  76. z2 = z [irow] [icol + 1];
  77. }
  78. return (1.0 - dcol) * z1 + dcol * z2;
  79. }
  80. double structVector :: v_getValueAtSample (integer isamp, integer ilevel, int unit) {
  81. // Preconditions:
  82. // 1 <= isamp <= my nx
  83. // 0 <= ilevel <= my ny
  84. double value;
  85. if (ilevel > Vector_CHANNEL_AVERAGE) {
  86. value = z [ilevel] [isamp];
  87. } else if (ny == 1) {
  88. value = z [1] [isamp]; // optimization
  89. } else if (ny == 2) {
  90. value = 0.5 * (z [1] [isamp] + z [2] [isamp]); // optimization
  91. } else {
  92. longdouble sum = 0.0;
  93. for (integer channel = 1; channel <= ny; channel ++)
  94. sum += z [channel] [isamp];
  95. value = double (sum / ny);
  96. }
  97. return isdefined (value) ? v_convertStandardToSpecialUnit (value, ilevel, unit) : undefined;
  98. }
  99. Thing_implement (Vector, Matrix, 2);
  100. /***** Get content. *****/
  101. //
  102. // Vector_getValueAtX () returns the average of all the interpolated channels.
  103. //
  104. double Vector_getValueAtX (Vector me, double x, integer ilevel, int interpolation) {
  105. double leftEdge = my x1 - 0.5 * my dx, rightEdge = leftEdge + my nx * my dx;
  106. if (x < leftEdge || x > rightEdge) return undefined;
  107. if (ilevel > Vector_CHANNEL_AVERAGE) {
  108. Melder_assert (ilevel <= my ny);
  109. return NUM_interpolate_sinc (my z [ilevel], my nx, Sampled_xToIndex (me, x),
  110. interpolation == Vector_VALUE_INTERPOLATION_SINC70 ? NUM_VALUE_INTERPOLATE_SINC70 :
  111. interpolation == Vector_VALUE_INTERPOLATION_SINC700 ? NUM_VALUE_INTERPOLATE_SINC700 :
  112. interpolation);
  113. }
  114. longdouble sum = 0.0;
  115. for (integer channel = 1; channel <= my ny; channel ++) {
  116. sum += NUM_interpolate_sinc (my z [channel], my nx, Sampled_xToIndex (me, x),
  117. interpolation == Vector_VALUE_INTERPOLATION_SINC70 ? NUM_VALUE_INTERPOLATE_SINC70 :
  118. interpolation == Vector_VALUE_INTERPOLATION_SINC700 ? NUM_VALUE_INTERPOLATE_SINC700 :
  119. interpolation);
  120. }
  121. return double (sum / my ny);
  122. }
  123. /***** Get shape. *****/
  124. void Vector_getMinimumAndX (Vector me, double xmin, double xmax, integer channel, int interpolation,
  125. double *return_minimum, double *return_xOfMinimum)
  126. {
  127. integer imin, imax, n = my nx;
  128. Melder_assert (channel >= 1 && channel <= my ny);
  129. double *y = my z [channel];
  130. double minimum, x;
  131. if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; }
  132. if (! Sampled_getWindowSamples (me, xmin, xmax, & imin, & imax)) {
  133. /*
  134. No samples between xmin and xmax.
  135. Try to return the lesser of the values at these two points.
  136. */
  137. double yleft = Vector_getValueAtX (me, xmin, channel,
  138. interpolation > Vector_VALUE_INTERPOLATION_NEAREST ? Vector_VALUE_INTERPOLATION_LINEAR : Vector_VALUE_INTERPOLATION_NEAREST);
  139. double yright = Vector_getValueAtX (me, xmax, channel,
  140. interpolation > Vector_VALUE_INTERPOLATION_NEAREST ? Vector_VALUE_INTERPOLATION_LINEAR : Vector_VALUE_INTERPOLATION_NEAREST);
  141. minimum = yleft < yright ? yleft : yright;
  142. x = yleft == yright ? (xmin + xmax) / 2 : yleft < yright ? xmin : xmax;
  143. } else {
  144. minimum = y [imin], x = imin;
  145. if (y [imax] < minimum) minimum = y [imax], x = imax;
  146. if (imin == 1) imin ++;
  147. if (imax == my nx) imax --;
  148. for (integer i = imin; i <= imax; i ++) {
  149. if (y [i] < y [i - 1] && y [i] <= y [i + 1]) {
  150. double i_real, localMinimum = NUMimproveMinimum (y, n, i, interpolation, & i_real);
  151. if (localMinimum < minimum) minimum = localMinimum, x = i_real;
  152. }
  153. }
  154. x = my x1 + (x - 1) * my dx; // convert sample to x
  155. if (x < xmin) x = xmin; else if (x > xmax) x = xmax;
  156. }
  157. if (return_minimum) *return_minimum = minimum;
  158. if (return_xOfMinimum) *return_xOfMinimum = x;
  159. }
  160. void Vector_getMinimumAndXAndChannel (Vector me, double xmin, double xmax, int interpolation,
  161. double *return_minimum, double *return_xOfMinimum, integer *return_channelOfMinimum)
  162. {
  163. double minimum, xOfMinimum;
  164. integer channelOfMinimum = 1;
  165. Vector_getMinimumAndX (me, xmin, xmax, 1, interpolation, & minimum, & xOfMinimum);
  166. for (integer channel = 2; channel <= my ny; channel ++) {
  167. double minimumOfChannel, xOfMinimumOfChannel;
  168. Vector_getMinimumAndX (me, xmin, xmax, channel, interpolation, & minimumOfChannel, & xOfMinimumOfChannel);
  169. if (minimumOfChannel < minimum) {
  170. minimum = minimumOfChannel;
  171. xOfMinimum = xOfMinimumOfChannel;
  172. channelOfMinimum = channel;
  173. }
  174. }
  175. if (return_minimum) *return_minimum = minimum;
  176. if (return_xOfMinimum) *return_xOfMinimum = xOfMinimum;
  177. if (return_channelOfMinimum) *return_channelOfMinimum = channelOfMinimum;
  178. }
  179. double Vector_getMinimum (Vector me, double xmin, double xmax, int interpolation) {
  180. double minimum;
  181. Vector_getMinimumAndXAndChannel (me, xmin, xmax, interpolation, & minimum, nullptr, nullptr);
  182. return minimum;
  183. }
  184. double Vector_getXOfMinimum (Vector me, double xmin, double xmax, int interpolation) {
  185. double xOfMinimum;
  186. Vector_getMinimumAndXAndChannel (me, xmin, xmax, interpolation, nullptr, & xOfMinimum, nullptr);
  187. return xOfMinimum;
  188. }
  189. integer Vector_getChannelOfMinimum (Vector me, double xmin, double xmax, int interpolation) {
  190. integer channelOfMinimum;
  191. Vector_getMinimumAndXAndChannel (me, xmin, xmax, interpolation, nullptr, nullptr, & channelOfMinimum);
  192. return channelOfMinimum;
  193. }
  194. void Vector_getMaximumAndX (Vector me, double xmin, double xmax, integer channel, int interpolation,
  195. double *return_maximum, double *return_xOfMaximum)
  196. {
  197. integer imin, imax, i, n = my nx;
  198. Melder_assert (channel >= 1 && channel <= my ny);
  199. double *y = my z [channel];
  200. double maximum, x;
  201. if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; }
  202. if (! Sampled_getWindowSamples (me, xmin, xmax, & imin, & imax)) {
  203. /*
  204. No samples between xmin and xmax.
  205. Try to return the greater of the values at these two points.
  206. */
  207. double yleft = Vector_getValueAtX (me, xmin, channel,
  208. interpolation > Vector_VALUE_INTERPOLATION_NEAREST ? Vector_VALUE_INTERPOLATION_LINEAR : Vector_VALUE_INTERPOLATION_NEAREST);
  209. double yright = Vector_getValueAtX (me, xmax, channel,
  210. interpolation > Vector_VALUE_INTERPOLATION_NEAREST ? Vector_VALUE_INTERPOLATION_LINEAR : Vector_VALUE_INTERPOLATION_NEAREST);
  211. maximum = yleft > yright ? yleft : yright;
  212. x = yleft == yright ? (xmin + xmax) / 2 : yleft > yright ? xmin : xmax;
  213. } else {
  214. maximum = y [imin], x = imin;
  215. if (y [imax] > maximum) maximum = y [imax], x = imax;
  216. if (imin == 1) imin ++;
  217. if (imax == my nx) imax --;
  218. for (i = imin; i <= imax; i ++) {
  219. if (y [i] > y [i - 1] && y [i] >= y [i + 1]) {
  220. double i_real, localMaximum = NUMimproveMaximum (y, n, i, interpolation, & i_real);
  221. if (localMaximum > maximum) maximum = localMaximum, x = i_real;
  222. }
  223. }
  224. x = my x1 + (x - 1) * my dx; // convert sample to x
  225. if (x < xmin) x = xmin; else if (x > xmax) x = xmax;
  226. }
  227. if (return_maximum) *return_maximum = maximum;
  228. if (return_xOfMaximum) *return_xOfMaximum = x;
  229. }
  230. void Vector_getMaximumAndXAndChannel (Vector me, double xmin, double xmax, int interpolation,
  231. double *return_maximum, double *return_xOfMaximum, integer *return_channelOfMaximum)
  232. {
  233. double maximum, xOfMaximum;
  234. integer channelOfMaximum = 1;
  235. Vector_getMaximumAndX (me, xmin, xmax, 1, interpolation, & maximum, & xOfMaximum);
  236. for (integer channel = 2; channel <= my ny; channel ++) {
  237. double maximumOfChannel, xOfMaximumOfChannel;
  238. Vector_getMaximumAndX (me, xmin, xmax, channel, interpolation, & maximumOfChannel, & xOfMaximumOfChannel);
  239. if (maximumOfChannel > maximum) {
  240. maximum = maximumOfChannel;
  241. xOfMaximum = xOfMaximumOfChannel;
  242. channelOfMaximum = channel;
  243. }
  244. }
  245. if (return_maximum) *return_maximum = maximum;
  246. if (return_xOfMaximum) *return_xOfMaximum = xOfMaximum;
  247. if (return_channelOfMaximum) *return_channelOfMaximum = channelOfMaximum;
  248. }
  249. double Vector_getMaximum (Vector me, double xmin, double xmax, int interpolation) {
  250. double maximum;
  251. Vector_getMaximumAndXAndChannel (me, xmin, xmax, interpolation, & maximum, nullptr, nullptr);
  252. return maximum;
  253. }
  254. double Vector_getXOfMaximum (Vector me, double xmin, double xmax, int interpolation) {
  255. double xOfMaximum;
  256. Vector_getMaximumAndXAndChannel (me, xmin, xmax, interpolation, nullptr, & xOfMaximum, nullptr);
  257. return xOfMaximum;
  258. }
  259. integer Vector_getChannelOfMaximum (Vector me, double xmin, double xmax, int interpolation) {
  260. integer channelOfMaximum;
  261. Vector_getMaximumAndXAndChannel (me, xmin, xmax, interpolation, nullptr, nullptr, & channelOfMaximum);
  262. return channelOfMaximum;
  263. }
  264. double Vector_getAbsoluteExtremum (Vector me, double xmin, double xmax, int interpolation) {
  265. double minimum = fabs (Vector_getMinimum (me, xmin, xmax, interpolation));
  266. double maximum = fabs (Vector_getMaximum (me, xmin, xmax, interpolation));
  267. return minimum > maximum ? minimum : maximum;
  268. }
  269. /***** Get statistics. *****/
  270. double Vector_getMean (Vector me, double xmin, double xmax, integer channel) {
  271. return Sampled_getMean (me, xmin, xmax, channel, 0, true);
  272. }
  273. double Vector_getStandardDeviation (Vector me, double xmin, double xmax, integer ilevel) {
  274. if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; }
  275. integer imin, imax, n = Sampled_getWindowSamples (me, xmin, xmax, & imin, & imax);
  276. if (n < 2) return undefined;
  277. if (ilevel == Vector_CHANNEL_AVERAGE) {
  278. longdouble sum2 = 0.0;
  279. for (integer channel = 1; channel <= my ny; channel ++) {
  280. double mean = Vector_getMean (me, xmin, xmax, channel);
  281. for (integer i = imin; i <= imax; i ++) {
  282. double diff = my z [channel] [i] - mean;
  283. sum2 += diff * diff;
  284. }
  285. }
  286. return sqrt (double (sum2 / (n * my ny - my ny))); // The number of constraints equals the number of channels,
  287. // because from every channel its own mean was subtracted.
  288. // Corollary: a two-channel mono sound will have the same stdev as the corresponding one-channel sound.
  289. }
  290. double mean = Vector_getMean (me, xmin, xmax, ilevel);
  291. longdouble sum2 = 0.0;
  292. for (integer i = imin; i <= imax; i ++) {
  293. double diff = my z [ilevel] [i] - mean;
  294. sum2 += diff * diff;
  295. }
  296. return sqrt (double (sum2 / (n - 1)));
  297. }
  298. /***** Modify. *****/
  299. void Vector_addScalar (Vector me, double scalar) {
  300. for (integer ichan = 1; ichan <= my ny; ichan ++)
  301. my channel (ichan) += scalar;
  302. }
  303. void Vector_subtractMean (Vector me) {
  304. for (integer ichan = 1; ichan <= my ny; ichan ++)
  305. VECcentre_inplace (my channel (ichan));
  306. }
  307. void Vector_multiplyByScalar (Vector me, double scalar) {
  308. for (integer ichan = 1; ichan <= my ny; ichan ++)
  309. VECmultiply_inplace (my channel (ichan), scalar);
  310. }
  311. void Vector_scale (Vector me, double scale) {
  312. double extremum = NUMextremum (my z.get());
  313. if (extremum != 0.0)
  314. Vector_multiplyByScalar (me, scale / extremum);
  315. }
  316. /***** Graphics. *****/
  317. void Vector_draw (Vector me, Graphics g, double *pxmin, double *pxmax, double *pymin, double *pymax,
  318. double defaultDy, conststring32 method)
  319. {
  320. bool xreversed = *pxmin > *pxmax, yreversed = *pymin > *pymax;
  321. if (xreversed) { double temp = *pxmin; *pxmin = *pxmax; *pxmax = temp; }
  322. if (yreversed) { double temp = *pymin; *pymin = *pymax; *pymax = temp; }
  323. /*
  324. Automatic domain.
  325. */
  326. if (*pxmin == *pxmax) {
  327. *pxmin = my xmin;
  328. *pxmax = my xmax;
  329. }
  330. /*
  331. Domain expressed in sample numbers.
  332. */
  333. integer ixmin, ixmax;
  334. Matrix_getWindowSamplesX (me, *pxmin, *pxmax, & ixmin, & ixmax);
  335. /*
  336. Automatic vertical range.
  337. */
  338. if (*pymin == *pymax) {
  339. Matrix_getWindowExtrema (me, ixmin, ixmax, 1, 1, pymin, pymax);
  340. if (*pymin == *pymax) {
  341. *pymin -= defaultDy;
  342. *pymax += defaultDy;
  343. }
  344. }
  345. /*
  346. Set coordinates for drawing.
  347. */
  348. Graphics_setInner (g);
  349. Graphics_setWindow (g, xreversed ? *pxmax : *pxmin, xreversed ? *pxmin : *pxmax, yreversed ? *pymax : *pymin, yreversed ? *pymin : *pymax);
  350. if (str32str (method, U"bars") || str32str (method, U"Bars")) {
  351. for (integer ix = ixmin; ix <= ixmax; ix ++) {
  352. double x = Sampled_indexToX (me, ix);
  353. double y = my z [1] [ix];
  354. double left = x - 0.5 * my dx, right = x + 0.5 * my dx;
  355. if (y > *pymax) y = *pymax;
  356. if (left < *pxmin) left = *pxmin;
  357. if (right > *pxmax) right = *pxmax;
  358. if (y > *pymin) {
  359. Graphics_line (g, left, y, right, y);
  360. Graphics_line (g, left, y, left, *pymin);
  361. Graphics_line (g, right, y, right, *pymin);
  362. }
  363. }
  364. } else if (str32str (method, U"poles") || str32str (method, U"Poles")) {
  365. for (integer ix = ixmin; ix <= ixmax; ix ++) {
  366. double x = Sampled_indexToX (me, ix);
  367. Graphics_line (g, x, 0.0, x, my z [1] [ix]);
  368. }
  369. } else if (str32str (method, U"speckles") || str32str (method, U"Speckles")) {
  370. for (integer ix = ixmin; ix <= ixmax; ix ++) {
  371. double x = Sampled_indexToX (me, ix);
  372. Graphics_speckle (g, x, my z [1] [ix]);
  373. }
  374. } else {
  375. /*
  376. * The default: draw as a curve.
  377. */
  378. Graphics_function (g, my z [1], ixmin, ixmax,
  379. Matrix_columnToX (me, ixmin), Matrix_columnToX (me, ixmax));
  380. }
  381. Graphics_unsetInner (g);
  382. }
  383. /* End of file Vector.cpp */