gsl_wavelet__bspline.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592
  1. /* wavelet/bspline.c
  2. *
  3. * Copyright (C) 2004 Ivo Alxneit
  4. *
  5. * This program 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 3 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * This program 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. See the GNU
  13. * General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. */
  19. /* Coefficients are from A. Cohen, I. Daubechies, and J.-C. Feauveau;
  20. * "Biorthogonal Bases of Compactly Supported Wavelets", Communications
  21. * on Pure and Applied Mathematics, 45 (1992) 485--560 (table 6.1).
  22. *
  23. * Note the following errors in table 1:
  24. *
  25. * N = 2, N~ = 4, m0~
  26. * the second term in z^-1 (45/64 z^-1) should be left out.
  27. *
  28. * N = 3, N~ = 7, m0~
  29. * the term 336z^-3 should read 363z^-3.
  30. */
  31. #include "gsl__config.h"
  32. #include "gsl_errno.h"
  33. #include "gsl_math.h"
  34. #include "gsl_wavelet.h"
  35. static const double h1_103[6] = { -0.0883883476483184405501055452631,
  36. 0.0883883476483184405501055452631,
  37. M_SQRT1_2,
  38. M_SQRT1_2,
  39. 0.0883883476483184405501055452631,
  40. -0.0883883476483184405501055452631
  41. };
  42. static const double g2_103[6] = { -0.0883883476483184405501055452631,
  43. -0.0883883476483184405501055452631,
  44. M_SQRT1_2,
  45. -(M_SQRT1_2),
  46. 0.0883883476483184405501055452631,
  47. 0.0883883476483184405501055452631
  48. };
  49. static const double h1_105[10] = { 0.0165728151840597076031447897368,
  50. -0.0165728151840597076031447897368,
  51. -0.1215339780164378557563951247368,
  52. 0.1215339780164378557563951247368,
  53. M_SQRT1_2,
  54. M_SQRT1_2,
  55. 0.1215339780164378557563951247368,
  56. -0.1215339780164378557563951247368,
  57. -0.0165728151840597076031447897368,
  58. 0.0165728151840597076031447897368
  59. };
  60. static const double g2_105[10] = { 0.0165728151840597076031447897368,
  61. 0.0165728151840597076031447897368,
  62. -0.1215339780164378557563951247368,
  63. -0.1215339780164378557563951247368,
  64. M_SQRT1_2,
  65. -(M_SQRT1_2),
  66. 0.1215339780164378557563951247368,
  67. 0.1215339780164378557563951247368,
  68. -0.0165728151840597076031447897368,
  69. -0.0165728151840597076031447897368
  70. };
  71. static const double g1_1[10] = { 0.0, 0.0, 0.0, 0.0,
  72. M_SQRT1_2,
  73. -(M_SQRT1_2),
  74. 0.0, 0.0, 0.0, 0.0
  75. };
  76. static const double h2_1[10] = { 0.0, 0.0, 0.0, 0.0,
  77. M_SQRT1_2,
  78. M_SQRT1_2,
  79. 0.0, 0.0, 0.0, 0.0
  80. };
  81. static const double h1_202[6] = { -0.1767766952966368811002110905262,
  82. 0.3535533905932737622004221810524,
  83. 1.0606601717798212866012665431573,
  84. 0.3535533905932737622004221810524,
  85. -0.1767766952966368811002110905262,
  86. 0.0
  87. };
  88. static const double g2_202[6] = { 0.0,
  89. -0.1767766952966368811002110905262,
  90. -0.3535533905932737622004221810524,
  91. 1.0606601717798212866012665431573,
  92. -0.3535533905932737622004221810524,
  93. -0.1767766952966368811002110905262
  94. };
  95. static const double h1_204[10] = { 0.0331456303681194152062895794737,
  96. -0.0662912607362388304125791589473,
  97. -0.1767766952966368811002110905262,
  98. 0.4198446513295125926130013399998,
  99. 0.9943689110435824561886873842099,
  100. 0.4198446513295125926130013399998,
  101. -0.1767766952966368811002110905262,
  102. -0.0662912607362388304125791589473,
  103. 0.0331456303681194152062895794737,
  104. 0.0
  105. };
  106. static const double g2_204[10] = { 0.0,
  107. 0.0331456303681194152062895794737,
  108. 0.0662912607362388304125791589473,
  109. -0.1767766952966368811002110905262,
  110. -0.4198446513295125926130013399998,
  111. 0.9943689110435824561886873842099,
  112. -0.4198446513295125926130013399998,
  113. -0.1767766952966368811002110905262,
  114. 0.0662912607362388304125791589473,
  115. 0.0331456303681194152062895794737
  116. };
  117. static const double h1_206[14] = { -0.0069053396600248781679769957237,
  118. 0.0138106793200497563359539914474,
  119. 0.0469563096881691715422435709210,
  120. -0.1077232986963880994204411332894,
  121. -0.1698713556366120029322340948025,
  122. 0.4474660099696121052849093228945,
  123. 0.9667475524034829435167794013152,
  124. 0.4474660099696121052849093228945,
  125. -0.1698713556366120029322340948025,
  126. -0.1077232986963880994204411332894,
  127. 0.0469563096881691715422435709210,
  128. 0.0138106793200497563359539914474,
  129. -0.0069053396600248781679769957237,
  130. 0.0
  131. };
  132. static const double g2_206[14] = { 0.0,
  133. -0.0069053396600248781679769957237,
  134. -0.0138106793200497563359539914474,
  135. 0.0469563096881691715422435709210,
  136. 0.1077232986963880994204411332894,
  137. -0.1698713556366120029322340948025,
  138. -0.4474660099696121052849093228945,
  139. 0.9667475524034829435167794013152,
  140. -0.4474660099696121052849093228945,
  141. -0.1698713556366120029322340948025,
  142. 0.1077232986963880994204411332894,
  143. 0.0469563096881691715422435709210,
  144. -0.0138106793200497563359539914474,
  145. -0.0069053396600248781679769957237,
  146. };
  147. static const double h1_208[18] = { 0.0015105430506304420992449678146,
  148. -0.0030210861012608841984899356291,
  149. -0.0129475118625466465649568669819,
  150. 0.0289161098263541773284036695929,
  151. 0.0529984818906909399392234421792,
  152. -0.1349130736077360572068505539514,
  153. -0.1638291834340902345352542235443,
  154. 0.4625714404759165262773590010400,
  155. 0.9516421218971785225243297231697,
  156. 0.4625714404759165262773590010400,
  157. -0.1638291834340902345352542235443,
  158. -0.1349130736077360572068505539514,
  159. 0.0529984818906909399392234421792,
  160. 0.0289161098263541773284036695929,
  161. -0.0129475118625466465649568669819,
  162. -0.0030210861012608841984899356291,
  163. 0.0015105430506304420992449678146,
  164. 0.0
  165. };
  166. static const double g2_208[18] = { 0.0,
  167. 0.0015105430506304420992449678146,
  168. 0.0030210861012608841984899356291,
  169. -0.0129475118625466465649568669819,
  170. -0.0289161098263541773284036695929,
  171. 0.0529984818906909399392234421792,
  172. 0.1349130736077360572068505539514,
  173. -0.1638291834340902345352542235443,
  174. -0.4625714404759165262773590010400,
  175. 0.9516421218971785225243297231697,
  176. -0.4625714404759165262773590010400,
  177. -0.1638291834340902345352542235443,
  178. 0.1349130736077360572068505539514,
  179. 0.0529984818906909399392234421792,
  180. -0.0289161098263541773284036695929,
  181. -0.0129475118625466465649568669819,
  182. 0.0030210861012608841984899356291,
  183. 0.0015105430506304420992449678146,
  184. };
  185. static const double h2_2[18] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
  186. 0.3535533905932737622004221810524,
  187. 0.7071067811865475244008443621048,
  188. 0.3535533905932737622004221810524,
  189. 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
  190. };
  191. static const double g1_2[18] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
  192. -0.3535533905932737622004221810524,
  193. 0.7071067811865475244008443621048,
  194. -0.3535533905932737622004221810524,
  195. 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
  196. };
  197. static const double h1_301[4] = { -0.3535533905932737622004221810524,
  198. 1.0606601717798212866012665431573,
  199. 1.0606601717798212866012665431573,
  200. -0.3535533905932737622004221810524
  201. };
  202. static const double g2_301[4] = { 0.3535533905932737622004221810524,
  203. 1.0606601717798212866012665431573,
  204. -1.0606601717798212866012665431573,
  205. -0.3535533905932737622004221810524
  206. };
  207. static const double h1_303[8] = { 0.0662912607362388304125791589473,
  208. -0.1988737822087164912377374768420,
  209. -0.1546796083845572709626847042104,
  210. 0.9943689110435824561886873842099,
  211. 0.9943689110435824561886873842099,
  212. -0.1546796083845572709626847042104,
  213. -0.1988737822087164912377374768420,
  214. 0.0662912607362388304125791589473
  215. };
  216. static const double g2_303[8] = { -0.0662912607362388304125791589473,
  217. -0.1988737822087164912377374768420,
  218. 0.1546796083845572709626847042104,
  219. 0.9943689110435824561886873842099,
  220. -0.9943689110435824561886873842099,
  221. -0.1546796083845572709626847042104,
  222. 0.1988737822087164912377374768420,
  223. 0.0662912607362388304125791589473
  224. };
  225. static const double h1_305[12] = { -0.0138106793200497563359539914474,
  226. 0.0414320379601492690078619743421,
  227. 0.0524805814161890740766251675000,
  228. -0.2679271788089652729175074340788,
  229. -0.0718155324642587329469607555263,
  230. 0.9667475524034829435167794013152,
  231. 0.9667475524034829435167794013152,
  232. -0.0718155324642587329469607555263,
  233. -0.2679271788089652729175074340788,
  234. 0.0524805814161890740766251675000,
  235. 0.0414320379601492690078619743421,
  236. -0.0138106793200497563359539914474
  237. };
  238. static const double g2_305[12] = { 0.0138106793200497563359539914474,
  239. 0.0414320379601492690078619743421,
  240. -0.0524805814161890740766251675000,
  241. -0.2679271788089652729175074340788,
  242. 0.0718155324642587329469607555263,
  243. 0.9667475524034829435167794013152,
  244. -0.9667475524034829435167794013152,
  245. -0.0718155324642587329469607555263,
  246. 0.2679271788089652729175074340788,
  247. 0.0524805814161890740766251675000,
  248. -0.0414320379601492690078619743421,
  249. -0.0138106793200497563359539914474
  250. };
  251. static const double h1_307[16] = { 0.0030210861012608841984899356291,
  252. -0.0090632583037826525954698068873,
  253. -0.0168317654213106405344439270765,
  254. 0.0746639850740189951912512662623,
  255. 0.0313329787073628846871956180962,
  256. -0.3011591259228349991008967259990,
  257. -0.0264992409453454699696117210896,
  258. 0.9516421218971785225243297231697,
  259. 0.9516421218971785225243297231697,
  260. -0.0264992409453454699696117210896,
  261. -0.3011591259228349991008967259990,
  262. 0.0313329787073628846871956180962,
  263. 0.0746639850740189951912512662623,
  264. -0.0168317654213106405344439270765,
  265. -0.0090632583037826525954698068873,
  266. 0.0030210861012608841984899356291
  267. };
  268. static const double g2_307[16] = { -0.0030210861012608841984899356291,
  269. -0.0090632583037826525954698068873,
  270. 0.0168317654213106405344439270765,
  271. 0.0746639850740189951912512662623,
  272. -0.0313329787073628846871956180962,
  273. -0.3011591259228349991008967259990,
  274. 0.0264992409453454699696117210896,
  275. 0.9516421218971785225243297231697,
  276. -0.9516421218971785225243297231697,
  277. -0.0264992409453454699696117210896,
  278. 0.3011591259228349991008967259990,
  279. 0.0313329787073628846871956180962,
  280. -0.0746639850740189951912512662623,
  281. -0.0168317654213106405344439270765,
  282. 0.0090632583037826525954698068873,
  283. 0.0030210861012608841984899356291
  284. };
  285. static const double h1_309[20] = { -0.0006797443727836989446602355165,
  286. 0.0020392331183510968339807065496,
  287. 0.0050603192196119810324706421788,
  288. -0.0206189126411055346546938106687,
  289. -0.0141127879301758447558029850103,
  290. 0.0991347824942321571990197448581,
  291. 0.0123001362694193142367090236328,
  292. -0.3201919683607785695513833204624,
  293. 0.0020500227115698857061181706055,
  294. 0.9421257006782067372990864259380,
  295. 0.9421257006782067372990864259380,
  296. 0.0020500227115698857061181706055,
  297. -0.3201919683607785695513833204624,
  298. 0.0123001362694193142367090236328,
  299. 0.0991347824942321571990197448581,
  300. -0.0141127879301758447558029850103,
  301. -0.0206189126411055346546938106687,
  302. 0.0050603192196119810324706421788,
  303. 0.0020392331183510968339807065496,
  304. -0.0006797443727836989446602355165
  305. };
  306. static const double g2_309[20] = { 0.0006797443727836989446602355165,
  307. 0.0020392331183510968339807065496,
  308. -0.0050603192196119810324706421788,
  309. -0.0206189126411055346546938106687,
  310. 0.0141127879301758447558029850103,
  311. 0.0991347824942321571990197448581,
  312. -0.0123001362694193142367090236328,
  313. -0.3201919683607785695513833204624,
  314. -0.0020500227115698857061181706055,
  315. 0.9421257006782067372990864259380,
  316. -0.9421257006782067372990864259380,
  317. 0.0020500227115698857061181706055,
  318. 0.3201919683607785695513833204624,
  319. 0.0123001362694193142367090236328,
  320. -0.0991347824942321571990197448581,
  321. -0.0141127879301758447558029850103,
  322. 0.0206189126411055346546938106687,
  323. 0.0050603192196119810324706421788,
  324. -0.0020392331183510968339807065496,
  325. -0.0006797443727836989446602355165
  326. };
  327. static const double h2_3[20] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
  328. 0.1767766952966368811002110905262,
  329. 0.5303300858899106433006332715786,
  330. 0.5303300858899106433006332715786,
  331. 0.1767766952966368811002110905262,
  332. 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
  333. };
  334. static const double g1_3[20] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
  335. -0.1767766952966368811002110905262,
  336. 0.5303300858899106433006332715786,
  337. -0.5303300858899106433006332715786,
  338. 0.1767766952966368811002110905262,
  339. 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
  340. };
  341. static int
  342. bspline_init (const double **h1, const double **g1,
  343. const double **h2, const double **g2, size_t * nc,
  344. size_t * offset, size_t member)
  345. {
  346. switch (member)
  347. {
  348. case 103:
  349. *nc = 6;
  350. *h1 = h1_103;
  351. *g1 = &g1_1[2];
  352. *h2 = &h2_1[2];
  353. *g2 = g2_103;
  354. break;
  355. case 105:
  356. *nc = 10;
  357. *h1 = h1_105;
  358. *g1 = g1_1;
  359. *h2 = h2_1;
  360. *g2 = g2_105;
  361. break;
  362. case 202:
  363. *nc = 6;
  364. *h1 = h1_202;
  365. *g1 = &g1_2[6];
  366. *h2 = &h2_2[6];
  367. *g2 = g2_202;
  368. break;
  369. case 204:
  370. *nc = 10;
  371. *h1 = h1_204;
  372. *g1 = &g1_2[4];
  373. *h2 = &h2_2[4];
  374. *g2 = g2_204;
  375. break;
  376. case 206:
  377. *nc = 14;
  378. *h1 = h1_206;
  379. *g1 = &g1_2[2];
  380. *h2 = &h2_2[2];
  381. *g2 = g2_206;
  382. break;
  383. case 208:
  384. *nc = 18;
  385. *h1 = h1_208;
  386. *g1 = g1_2;
  387. *h2 = h2_2;
  388. *g2 = g2_208;
  389. break;
  390. case 301:
  391. *nc = 4;
  392. *h1 = h1_301;
  393. *g1 = &g1_3[8];
  394. *h2 = &h2_3[8];
  395. *g2 = g2_301;
  396. break;
  397. case 303:
  398. *nc = 8;
  399. *h1 = h1_303;
  400. *g1 = &g1_3[6];
  401. *h2 = &h2_3[6];
  402. *g2 = g2_303;
  403. break;
  404. case 305:
  405. *nc = 12;
  406. *h1 = h1_305;
  407. *g1 = &g1_3[4];
  408. *h2 = &h2_3[4];
  409. *g2 = g2_305;
  410. break;
  411. case 307:
  412. *nc = 16;
  413. *h1 = h1_307;
  414. *g1 = &g1_3[2];
  415. *h2 = &h2_3[2];
  416. *g2 = g2_307;
  417. break;
  418. case 309:
  419. *nc = 20;
  420. *h1 = h1_309;
  421. *g1 = g1_3;
  422. *h2 = h2_3;
  423. *g2 = g2_309;
  424. break;
  425. default:
  426. return GSL_FAILURE;
  427. }
  428. *offset = 0;
  429. return GSL_SUCCESS;
  430. }
  431. static int
  432. bspline_centered_init (const double **h1, const double **g1,
  433. const double **h2, const double **g2, size_t * nc,
  434. size_t * offset, size_t member)
  435. {
  436. switch (member)
  437. {
  438. case 103:
  439. *nc = 6;
  440. *h1 = h1_103;
  441. *g1 = &g1_1[2];
  442. *h2 = &h2_1[2];
  443. *g2 = g2_103;
  444. break;
  445. case 105:
  446. *nc = 10;
  447. *h1 = h1_105;
  448. *g1 = g1_1;
  449. *h2 = h2_1;
  450. *g2 = g2_105;
  451. break;
  452. case 202:
  453. *nc = 6;
  454. *h1 = h1_202;
  455. *g1 = &g1_2[6];
  456. *h2 = &h2_2[6];
  457. *g2 = g2_202;
  458. break;
  459. case 204:
  460. *nc = 10;
  461. *h1 = h1_204;
  462. *g1 = &g1_2[4];
  463. *h2 = &h2_2[4];
  464. *g2 = g2_204;
  465. break;
  466. case 206:
  467. *nc = 14;
  468. *h1 = h1_206;
  469. *g1 = &g1_2[2];
  470. *h2 = &h2_2[2];
  471. *g2 = g2_206;
  472. break;
  473. case 208:
  474. *nc = 18;
  475. *h1 = h1_208;
  476. *g1 = g1_2;
  477. *h2 = h2_2;
  478. *g2 = g2_208;
  479. break;
  480. case 301:
  481. *nc = 4;
  482. *h1 = h1_301;
  483. *g1 = &g1_3[8];
  484. *h2 = &h2_3[8];
  485. *g2 = g2_301;
  486. break;
  487. case 303:
  488. *nc = 8;
  489. *h1 = h1_303;
  490. *g1 = &g1_3[6];
  491. *h2 = &h2_3[6];
  492. *g2 = g2_303;
  493. break;
  494. case 305:
  495. *nc = 12;
  496. *h1 = h1_305;
  497. *g1 = &g1_3[4];
  498. *h2 = &h2_3[4];
  499. *g2 = g2_305;
  500. break;
  501. case 307:
  502. *nc = 16;
  503. *h1 = h1_307;
  504. *g1 = &g1_3[2];
  505. *h2 = &h2_3[2];
  506. *g2 = g2_307;
  507. break;
  508. case 309:
  509. *nc = 20;
  510. *h1 = h1_309;
  511. *g1 = g1_3;
  512. *h2 = h2_3;
  513. *g2 = g2_309;
  514. break;
  515. default:
  516. return GSL_FAILURE;
  517. }
  518. *offset = ((*nc) >> 1);
  519. return GSL_SUCCESS;
  520. }
  521. static const gsl_wavelet_type bspline_type = {
  522. "bspline",
  523. &bspline_init
  524. };
  525. static const gsl_wavelet_type bspline_centered_type = {
  526. "bspline-centered",
  527. &bspline_centered_init
  528. };
  529. const gsl_wavelet_type *gsl_wavelet_bspline = &bspline_type;
  530. const gsl_wavelet_type *gsl_wavelet_bspline_centered = &bspline_centered_type;