n_gradient.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114
  1. /*****************************************************************************
  2. *
  3. * MODULE: Grass PDE Numerical Library
  4. * AUTHOR(S): Soeren Gebbert, Berlin (GER) Dec 2006
  5. * soerengebbert <at> gmx <dot> de
  6. *
  7. * PURPOSE: gradient management functions
  8. * part of the gpde library
  9. *
  10. * COPYRIGHT: (C) 2000 by the GRASS Development Team
  11. *
  12. * This program is free software under the GNU General Public
  13. * License (>=v2). Read the file COPYING that comes with GRASS
  14. * for details.
  15. *
  16. *****************************************************************************/
  17. #include <grass/N_pde.h>
  18. /*!
  19. * \brief Allocate a N_gradient_2d structure
  20. *
  21. * \return N_gradient_2d *
  22. *
  23. * */
  24. N_gradient_2d *N_alloc_gradient_2d(void)
  25. {
  26. N_gradient_2d *grad;
  27. grad = (N_gradient_2d *) G_calloc(1, sizeof(N_gradient_2d));
  28. return grad;
  29. }
  30. /*!
  31. * \brief Free's a N_gradient_2d structure
  32. *
  33. * \return void
  34. *
  35. * */
  36. void N_free_gradient_2d(N_gradient_2d * grad)
  37. {
  38. G_free(grad);
  39. grad = NULL;
  40. return;
  41. }
  42. /*!
  43. * \brief allocate and initialize a N_gradient_2d structure
  44. *
  45. * \param NC double - the gradient between northern and center cell
  46. * \param SC double - the gradient between southern and center cell
  47. * \param WC double - the gradient between western and center cell
  48. * \param EC double - the gradient between eastern and center cell
  49. * \return N_gradient_2d *
  50. *
  51. * */
  52. N_gradient_2d *N_create_gradient_2d(double NC, double SC, double WC,
  53. double EC)
  54. {
  55. N_gradient_2d *grad;
  56. G_debug(5, "N_create_gradient_2d: create N_gradient_2d");
  57. grad = N_alloc_gradient_2d();
  58. grad->NC = NC;
  59. grad->SC = SC;
  60. grad->WC = WC;
  61. grad->EC = EC;
  62. return grad;
  63. }
  64. /*!
  65. * \brief copy a N_gradient_2d structure
  66. *
  67. * \param source - the source N_gradient_2d struct
  68. * \param target - the target N_gradient_2d struct
  69. * \return int - 1 success, 0 failure while copying
  70. *
  71. * */
  72. int N_copy_gradient_2d(N_gradient_2d * source, N_gradient_2d * target)
  73. {
  74. G_debug(5, "N_copy_gradient_2d: copy N_gradient_2d");
  75. if (!source || !target)
  76. return 0;
  77. target->NC = source->NC;
  78. target->SC = source->SC;
  79. target->WC = source->WC;
  80. target->EC = source->EC;
  81. return 1;
  82. }
  83. /*!
  84. * \brief Return a N_gradient_2d structure calculated from the input gradient field
  85. * at position [row][col]
  86. *
  87. * This function returns the gradient of a cell at position [row][col] from the input gradient field.
  88. * Returend is a new structure of type N_gradient_2d.
  89. *
  90. * \param field N_gradient_field_2d * - A two dimensional gradient field
  91. * \param gradient N_gradient_2d * - the gradient structure which should be filled with data, if a NULL pointer is given, a new structure will be created
  92. * \param col int
  93. * \param row int
  94. * \return N_gradient_2d * - the new or filled gradient structure
  95. *
  96. *
  97. * */
  98. N_gradient_2d *N_get_gradient_2d(N_gradient_field_2d * field,
  99. N_gradient_2d * gradient, int col, int row)
  100. {
  101. double NC = 0, SC = 0, WC = 0, EC = 0;
  102. N_gradient_2d *grad = gradient;
  103. NC = N_get_array_2d_d_value(field->y_array, col, row);
  104. SC = N_get_array_2d_d_value(field->y_array, col, row + 1);
  105. WC = N_get_array_2d_d_value(field->x_array, col, row);
  106. EC = N_get_array_2d_d_value(field->x_array, col + 1, row);
  107. G_debug(5,
  108. "N_get_gradient_2d: calculate N_gradient_2d NC %g SC %g WC %g EC %g",
  109. NC, SC, WC, EC);
  110. /*if gradient is a NULL pointer, create a new one */
  111. if (!grad) {
  112. grad = N_create_gradient_2d(NC, SC, WC, EC);
  113. }
  114. else {
  115. grad->NC = NC;
  116. grad->SC = SC;
  117. grad->WC = WC;
  118. grad->EC = EC;
  119. }
  120. return grad;
  121. }
  122. /*!
  123. * \brief Allocate a N_gradient_3d structure
  124. *
  125. * \return N_gradient_3d *
  126. *
  127. * */
  128. N_gradient_3d *N_alloc_gradient_3d(void)
  129. {
  130. N_gradient_3d *grad;
  131. grad = (N_gradient_3d *) G_calloc(1, sizeof(N_gradient_3d));
  132. return grad;
  133. }
  134. /*!
  135. * \brief Free's a N_gradient_3d structure
  136. *
  137. * \return void
  138. *
  139. * */
  140. void N_free_gradient_3d(N_gradient_3d * grad)
  141. {
  142. G_free(grad);
  143. grad = NULL;
  144. return;
  145. }
  146. /*!
  147. * \brief allocate and initialize a N_gradient_3d structure
  148. *
  149. * \param NC double - the gradient between northern and center cell
  150. * \param SC double - the gradient between southern and center cell
  151. * \param WC double - the gradient between western and center cell
  152. * \param EC double - the gradient between eastern and center cell
  153. * \param TC double - the gradient between top and center cell
  154. * \param BC double - the gradient between bottom and center cell
  155. * \return N_gradient_3d *
  156. *
  157. * */
  158. N_gradient_3d *N_create_gradient_3d(double NC, double SC, double WC,
  159. double EC, double TC, double BC)
  160. {
  161. N_gradient_3d *grad;
  162. G_debug(5, "N_create_gradient_3d: create N_gradient_3d");
  163. grad = N_alloc_gradient_3d();
  164. grad->NC = NC;
  165. grad->SC = SC;
  166. grad->WC = WC;
  167. grad->EC = EC;
  168. grad->TC = TC;
  169. grad->BC = BC;
  170. return grad;
  171. }
  172. /*!
  173. * \brief copy a N_gradient_3d structure
  174. *
  175. * \param source - the source N_gradient_3d struct
  176. * \param target - the target N_gradient_3d struct
  177. * \return int - 1 success, 0 failure while copying
  178. *
  179. * */
  180. int N_copy_gradient_3d(N_gradient_3d * source, N_gradient_3d * target)
  181. {
  182. G_debug(5, "N_copy_gradient_3d: copy N_gradient_3d");
  183. if (!source || !target)
  184. return 0;
  185. target->NC = source->NC;
  186. target->SC = source->SC;
  187. target->WC = source->WC;
  188. target->EC = source->EC;
  189. target->TC = source->TC;
  190. target->BC = source->BC;
  191. return 1;
  192. }
  193. /*!
  194. * \brief Return a N_gradient_3d structure calculated from the input gradient field
  195. * at position [depth][row][col]
  196. *
  197. * This function returns the gradient of a 3d cell at position [depth][row][col] from the input gradient field.
  198. * Returned is a new structure of type N_gradient_3d.
  199. *
  200. * \param field N_gradient_field_3d * - A three dimensional gradient field
  201. * \param gradient N_gradient_3d * - an existing gradient structure or a NULL pointer, if a NULL pointer is providet a new structure will be returned
  202. * \param col int
  203. * \param row int
  204. * \param depth int
  205. * \return N_gradient_3d *
  206. *
  207. *
  208. * */
  209. N_gradient_3d *N_get_gradient_3d(N_gradient_field_3d * field,
  210. N_gradient_3d * gradient, int col, int row,
  211. int depth)
  212. {
  213. double NC, SC, WC, EC, TC, BC;
  214. N_gradient_3d *grad = gradient;
  215. NC = N_get_array_3d_d_value(field->y_array, col, row, depth);
  216. SC = N_get_array_3d_d_value(field->y_array, col, row + 1, depth);
  217. WC = N_get_array_3d_d_value(field->x_array, col, row, depth);
  218. EC = N_get_array_3d_d_value(field->x_array, col + 1, row, depth);
  219. BC = N_get_array_3d_d_value(field->z_array, col, row, depth);
  220. TC = N_get_array_3d_d_value(field->z_array, col, row, depth + 1);
  221. G_debug(6,
  222. "N_get_gradient_3d: calculate N_gradient_3d NC %g SC %g WC %g EC %g TC %g BC %g",
  223. NC, SC, WC, EC, TC, BC);
  224. /*if gradient is a NULL pointer, create a new one */
  225. if (!grad) {
  226. grad = N_create_gradient_3d(NC, SC, WC, EC, TC, BC);
  227. }
  228. else {
  229. grad->NC = NC;
  230. grad->SC = SC;
  231. grad->WC = WC;
  232. grad->EC = EC;
  233. grad->BC = BC;
  234. grad->TC = TC;
  235. }
  236. return grad;
  237. }
  238. /*!
  239. * \brief Allocate a N_gradient_neighbours_x structure
  240. *
  241. * This structure contains all neighbour gradients in x direction of one cell
  242. *
  243. * \return N_gradient_neighbours_x *
  244. *
  245. * */
  246. N_gradient_neighbours_x *N_alloc_gradient_neighbours_x(void)
  247. {
  248. N_gradient_neighbours_x *grad;
  249. grad =
  250. (N_gradient_neighbours_x *) G_calloc(1,
  251. sizeof(N_gradient_neighbours_x));
  252. return grad;
  253. }
  254. /*!
  255. * \brief Free's a N_gradient_neighbours_x structure
  256. *
  257. * \return void
  258. *
  259. * */
  260. void N_free_gradient_neighbours_x(N_gradient_neighbours_x * grad)
  261. {
  262. G_free(grad);
  263. grad = NULL;
  264. return;
  265. }
  266. /*!
  267. * \brief Allocate and initialize a N_gradient_neighbours_x structure
  268. *
  269. * \param NWN double - the gradient between north-west and northern cell
  270. * \param NEN double - the gradient between north-east and northern cell
  271. * \param WC double - the gradient between western and center cell
  272. * \param EC double - the gradient between eastern and center cell
  273. * \param SWS double - the gradient between south-west and southern cell
  274. * \param SES double - the gradient between south-east and southern cell
  275. * \return N_gradient_neighbours_x *
  276. *
  277. * */
  278. N_gradient_neighbours_x *N_create_gradient_neighbours_x(double NWN,
  279. double NEN, double WC,
  280. double EC, double SWS,
  281. double SES)
  282. {
  283. N_gradient_neighbours_x *grad;
  284. G_debug(6,
  285. "N_create_gradient_neighbours_x: create N_gradient_neighbours_x");
  286. grad = N_alloc_gradient_neighbours_x();
  287. grad->NWN = NWN;
  288. grad->NEN = NEN;
  289. grad->WC = WC;
  290. grad->EC = EC;
  291. grad->SWS = SWS;
  292. grad->SES = SES;
  293. return grad;
  294. }
  295. /*!
  296. * \brief copy a N_gradient_neighbours_x structure
  297. *
  298. * \param source - the source N_gradient_neighbours_x struct
  299. * \param target - the target N_gradient_neighbours_x struct
  300. * \return int - 1 success, 0 failure while copying
  301. *
  302. * */
  303. int
  304. N_copy_gradient_neighbours_x(N_gradient_neighbours_x * source,
  305. N_gradient_neighbours_x * target)
  306. {
  307. G_debug(6, "N_copy_gradient_neighbours_x: copy N_gradient_neighbours_x");
  308. if (!source || !target)
  309. return 0;
  310. target->NWN = source->NWN;
  311. target->NEN = source->NEN;
  312. target->WC = source->WC;
  313. target->EC = source->EC;
  314. target->SWS = source->SWS;
  315. target->SES = source->SES;
  316. return 1;
  317. }
  318. /*!
  319. * \brief Allocate a N_gradient_neighbours_y structure
  320. *
  321. * This structure contains all neighbour gradients in y direction of one cell
  322. *
  323. * \return N_gradient_neighbours_y *
  324. *
  325. * */
  326. N_gradient_neighbours_y *N_alloc_gradient_neighbours_y(void)
  327. {
  328. N_gradient_neighbours_y *grad;
  329. grad =
  330. (N_gradient_neighbours_y *) G_calloc(1,
  331. sizeof(N_gradient_neighbours_y));
  332. return grad;
  333. }
  334. /*!
  335. * \brief Free's a N_gradient_neighbours_y structure
  336. *
  337. * \return void
  338. *
  339. * */
  340. void N_free_gradient_neighbours_y(N_gradient_neighbours_y * grad)
  341. {
  342. G_free(grad);
  343. grad = NULL;
  344. return;
  345. }
  346. /*!
  347. * \brief Allocate and initialize a N_gradient_neighbours_y structure
  348. *
  349. * \param NWW double - the gradient between north-west and western cell
  350. * \param NEE double - the gradient between north-east and eastern cell
  351. * \param NC double - the gradient between northern and center cell
  352. * \param SC double - the gradient between southern and center cell
  353. * \param SWW double - the gradient between south-west and western cell
  354. * \param SEE double - the gradient between south-east and eastern cell
  355. * \return N_gradient_neighbours_y *
  356. *
  357. * */
  358. N_gradient_neighbours_y *N_create_gradient_neighbours_y(double NWW,
  359. double NEE, double NC,
  360. double SC, double SWW,
  361. double SEE)
  362. {
  363. N_gradient_neighbours_y *grad;
  364. G_debug(6,
  365. "N_create_gradient_neighbours_y: create N_gradient_neighbours_y");
  366. grad = N_alloc_gradient_neighbours_y();
  367. grad->NWW = NWW;
  368. grad->NEE = NEE;
  369. grad->NC = NC;
  370. grad->SC = SC;
  371. grad->SWW = SWW;
  372. grad->SEE = SEE;
  373. return grad;
  374. }
  375. /*!
  376. * \brief copy a N_gradient_neighbours_y structure
  377. *
  378. * \param source - the source N_gradient_neighbours_y struct
  379. * \param target - the target N_gradient_neighbours_y struct
  380. * \return int - 1 success, 0 failure while copying
  381. *
  382. * */
  383. int
  384. N_copy_gradient_neighbours_y(N_gradient_neighbours_y * source,
  385. N_gradient_neighbours_y * target)
  386. {
  387. G_debug(6, "N_copy_gradient_neighbours_y: copy N_gradient_neighbours_y");
  388. if (!source || !target)
  389. return 0;
  390. target->NWW = source->NWW;
  391. target->NEE = source->NEE;
  392. target->NC = source->NC;
  393. target->SC = source->SC;
  394. target->SWW = source->SWW;
  395. target->SEE = source->SEE;
  396. return 1;
  397. }
  398. /*!
  399. * \brief Allocate a N_gradient_neighbours_z structure
  400. *
  401. * This structure contains all neighbour gradients in z direction of one cell
  402. *
  403. * \return N_gradient_neighbours_z *
  404. *
  405. * */
  406. N_gradient_neighbours_z *N_alloc_gradient_neighbours_z(void)
  407. {
  408. N_gradient_neighbours_z *grad;
  409. grad =
  410. (N_gradient_neighbours_z *) G_calloc(1,
  411. sizeof(N_gradient_neighbours_z));
  412. return grad;
  413. }
  414. /*!
  415. * \brief Free's a N_gradient_neighbours_z structure
  416. *
  417. * \return void
  418. *
  419. * */
  420. void N_free_gradient_neighbours_z(N_gradient_neighbours_z * grad)
  421. {
  422. G_free(grad);
  423. grad = NULL;
  424. return;
  425. }
  426. /*!
  427. * \brief Allocate and initialize a N_gradient_neighbours_z structure
  428. *
  429. * \param NWZ double - the gradient between upper and lower north-western cells
  430. * \param NZ double - the gradient between upper and lower northern cells
  431. * \param NEZ double - the gradient between upper and lower north-eastern cells
  432. * \param WZ double - the gradient between upper and lower western cells
  433. * \param CZ double - the gradient between upper and lower center cells
  434. * \param EZ double - the gradient between upper and lower eastern cells
  435. * \param SWZ double - the gradient between upper and lower south-western cells
  436. * \param SZ double - the gradient between upper and lower southern cells
  437. * \param SEZ double - the gradient between upper and lower south-eastern cells
  438. * \return N_gradient_neighbours_z *
  439. *
  440. * */
  441. N_gradient_neighbours_z *N_create_gradient_neighbours_z(double NWZ, double NZ,
  442. double NEZ, double WZ,
  443. double CZ, double EZ,
  444. double SWZ, double SZ,
  445. double SEZ)
  446. {
  447. N_gradient_neighbours_z *grad;
  448. G_debug(6,
  449. "N_create_gradient_neighbours_z: create N_gradient_neighbours_z");
  450. grad = N_alloc_gradient_neighbours_z();
  451. grad->NWZ = NWZ;
  452. grad->NZ = NZ;
  453. grad->NEZ = NEZ;
  454. grad->WZ = WZ;
  455. grad->CZ = CZ;
  456. grad->EZ = EZ;
  457. grad->SWZ = SWZ;
  458. grad->SZ = SZ;
  459. grad->SEZ = SEZ;
  460. return grad;
  461. }
  462. /*!
  463. * \brief copy a N_gradient_neighbours_z structure
  464. *
  465. * \param source - the source N_gradient_neighbours_z struct
  466. * \param target - the target N_gradient_neighbours_z struct
  467. * \return int - 1 success, 0 failure while copying
  468. *
  469. * */
  470. int
  471. N_copy_gradient_neighbours_z(N_gradient_neighbours_z * source,
  472. N_gradient_neighbours_z * target)
  473. {
  474. G_debug(6, "N_copy_gradient_neighbours_z: copy N_gradient_neighbours_z");
  475. if (!source || !target)
  476. return 0;
  477. target->NWZ = source->NWZ;
  478. target->NZ = source->NZ;
  479. target->NEZ = source->NEZ;
  480. target->WZ = source->WZ;
  481. target->CZ = source->CZ;
  482. target->EZ = source->EZ;
  483. target->SWZ = source->SWZ;
  484. target->SZ = source->SZ;
  485. target->SEZ = source->SEZ;
  486. return 1;
  487. }
  488. /*!
  489. * \brief Allocate a N_gradient_neighbours_2d structure
  490. *
  491. * This structure contains all neighbour gradients in all directions of one cell
  492. * in a 2d raster layer
  493. *
  494. * \return N_gradient_neighbours_2d *
  495. *
  496. * */
  497. N_gradient_neighbours_2d *N_alloc_gradient_neighbours_2d(void)
  498. {
  499. N_gradient_neighbours_2d *grad;
  500. grad =
  501. (N_gradient_neighbours_2d *) G_calloc(1,
  502. sizeof
  503. (N_gradient_neighbours_2d));
  504. grad->x = N_alloc_gradient_neighbours_x();
  505. grad->y = N_alloc_gradient_neighbours_y();
  506. return grad;
  507. }
  508. /*!
  509. * \brief Free's a N_gradient_neighbours_2d structure
  510. *
  511. * \return void
  512. *
  513. * */
  514. void N_free_gradient_neighbours_2d(N_gradient_neighbours_2d * grad)
  515. {
  516. N_free_gradient_neighbours_x(grad->x);
  517. N_free_gradient_neighbours_y(grad->y);
  518. G_free(grad);
  519. grad = NULL;
  520. return;
  521. }
  522. /*!
  523. * \brief Allocate and initialize a N_gradient_neighbours_2d structure
  524. *
  525. * The parameter N_gradient_neighbours x and y are copied into the new allocated structure
  526. * and can be deleted after the initializing
  527. *
  528. * \return N_gradient_neighbours_2d * -- if failure NULL is returned
  529. *
  530. * */
  531. N_gradient_neighbours_2d
  532. * N_create_gradient_neighbours_2d(N_gradient_neighbours_x * x,
  533. N_gradient_neighbours_y * y)
  534. {
  535. N_gradient_neighbours_2d *grad;
  536. int fail = 0;
  537. G_debug(5,
  538. "N_create_gradient_neighbours_2d: create N_gradient_neighbours_2d");
  539. grad = N_alloc_gradient_neighbours_2d();
  540. if (!N_copy_gradient_neighbours_x(x, grad->x))
  541. fail++;
  542. if (!N_copy_gradient_neighbours_y(y, grad->y))
  543. fail++;
  544. if (fail > 0) {
  545. N_free_gradient_neighbours_2d(grad);
  546. grad = NULL;
  547. }
  548. return grad;
  549. }
  550. /*!
  551. * \brief copy a N_gradient_neighbours_2d structure
  552. *
  553. * \param source - the source N_gradient_neighbours_2d struct
  554. * \param target - the target N_gradient_neighbours_2d struct
  555. * \return int - 1 success, 0 failure while copying
  556. *
  557. * */
  558. int
  559. N_copy_gradient_neighbours_2d(N_gradient_neighbours_2d * source,
  560. N_gradient_neighbours_2d * target)
  561. {
  562. int fail = 0;
  563. G_debug(5,
  564. "N_copy_gradient_neighbours_2d: copy N_gradient_neighbours_2d");
  565. if (!source || !target)
  566. return 0;
  567. if (!(N_copy_gradient_neighbours_x(source->x, target->x)))
  568. fail++;
  569. if (!(N_copy_gradient_neighbours_y(source->y, target->y)))
  570. fail++;
  571. if (fail > 0) {
  572. return 0;
  573. }
  574. return 1;
  575. }
  576. /*!
  577. * \brief Return a N_gradient_neighbours_2d structure calculated from the input gradient field
  578. * at position [row][col]
  579. *
  580. * This function returns the gradient neighbours in x and y dierection
  581. * of a cell at position [row][col] from the input gradient field.
  582. * Returend is a pointer to a structure of type N_gradient_neighbours_2d.
  583. *
  584. * \param field N_gradient_field_2d * - A two dimensional gradient field
  585. * \param gradient N_gradient_neighbours_2d * - the gradient structure which should be filled with data, if a NULL pointer is given, a new structure will be created
  586. * \param col int
  587. * \param row int
  588. * \return N_gradient_neighbours_2d * - the new or filled gradient structure
  589. *
  590. *
  591. * */
  592. N_gradient_neighbours_2d *N_get_gradient_neighbours_2d(N_gradient_field_2d *
  593. field,
  594. N_gradient_neighbours_2d
  595. * gradient, int col,
  596. int row)
  597. {
  598. double NWN, NEN, WC, EC, SWS, SES;
  599. double NWW, NEE, NC, SC, SWW, SEE;
  600. N_gradient_neighbours_2d *grad = NULL;
  601. N_gradient_neighbours_x *grad_x = NULL;
  602. N_gradient_neighbours_y *grad_y = NULL;
  603. NWN = N_get_array_2d_d_value(field->x_array, col, row - 1);
  604. NEN = N_get_array_2d_d_value(field->x_array, col + 1, row - 1);
  605. WC = N_get_array_2d_d_value(field->x_array, col, row);
  606. EC = N_get_array_2d_d_value(field->x_array, col + 1, row);
  607. SWS = N_get_array_2d_d_value(field->x_array, col, row + 1);
  608. SES = N_get_array_2d_d_value(field->x_array, col + 1, row + 1);
  609. NWW = N_get_array_2d_d_value(field->y_array, col - 1, row);
  610. NEE = N_get_array_2d_d_value(field->y_array, col + 1, row);
  611. NC = N_get_array_2d_d_value(field->y_array, col, row);
  612. SC = N_get_array_2d_d_value(field->y_array, col, row + 1);
  613. SWW = N_get_array_2d_d_value(field->y_array, col - 1, row + 1);
  614. SEE = N_get_array_2d_d_value(field->y_array, col + 1, row + 1);
  615. grad_x = N_create_gradient_neighbours_x(NWN, NEN, WC, EC, SWS, SES);
  616. grad_y = N_create_gradient_neighbours_y(NWW, NEE, NC, SC, SWW, SEE);
  617. G_debug(5,
  618. "N_get_gradient_neighbours_2d: calculate N_gradient_neighbours_x NWN %g NEN %g WC %g EC %g SWS %g SES %g",
  619. NWN, NEN, WC, EC, SWS, SES);
  620. G_debug(5,
  621. "N_get_gradient_neighbours_2d: calculate N_gradient_neighbours_y NWW %g NEE %g NC %g SC %g SWW %g SEE %g",
  622. NWW, NEE, NC, SC, SWW, SEE);
  623. /*if gradient is a NULL pointer, create a new one */
  624. if (!gradient) {
  625. grad = N_create_gradient_neighbours_2d(grad_x, grad_y);
  626. gradient = grad;
  627. }
  628. else {
  629. grad = N_create_gradient_neighbours_2d(grad_x, grad_y);
  630. N_copy_gradient_neighbours_2d(grad, gradient);
  631. N_free_gradient_neighbours_2d(grad);
  632. }
  633. N_free_gradient_neighbours_x(grad_x);
  634. N_free_gradient_neighbours_y(grad_y);
  635. return gradient;
  636. }
  637. /*!
  638. * \brief Allocate a N_gradient_neighbours_3d structure
  639. *
  640. * This structure contains all neighbour gradients in all directions of one cell
  641. * in a 3d raster layer
  642. *
  643. * \return N_gradient_neighbours_3d *
  644. *
  645. * */
  646. N_gradient_neighbours_3d *N_alloc_gradient_neighbours_3d(void)
  647. {
  648. N_gradient_neighbours_3d *grad;
  649. grad =
  650. (N_gradient_neighbours_3d *) G_calloc(1,
  651. sizeof
  652. (N_gradient_neighbours_3d));
  653. grad->xt = N_alloc_gradient_neighbours_x();
  654. grad->xc = N_alloc_gradient_neighbours_x();
  655. grad->xb = N_alloc_gradient_neighbours_x();
  656. grad->yt = N_alloc_gradient_neighbours_y();
  657. grad->yc = N_alloc_gradient_neighbours_y();
  658. grad->yb = N_alloc_gradient_neighbours_y();
  659. grad->zt = N_alloc_gradient_neighbours_z();
  660. grad->zb = N_alloc_gradient_neighbours_z();
  661. return grad;
  662. }
  663. /*!
  664. * \brief Free's a N_gradient_neighbours_3d structure
  665. *
  666. * \return void
  667. *
  668. * */
  669. void N_free_gradient_neighbours_3d(N_gradient_neighbours_3d * grad)
  670. {
  671. N_free_gradient_neighbours_x(grad->xt);
  672. N_free_gradient_neighbours_x(grad->xc);
  673. N_free_gradient_neighbours_x(grad->xb);
  674. N_free_gradient_neighbours_y(grad->yt);
  675. N_free_gradient_neighbours_y(grad->yc);
  676. N_free_gradient_neighbours_y(grad->yb);
  677. N_free_gradient_neighbours_z(grad->zt);
  678. N_free_gradient_neighbours_z(grad->zb);
  679. G_free(grad);
  680. grad = NULL;
  681. return;
  682. }
  683. /*!
  684. * \brief Allocate and initialize a N_gradient_neighbours_3d structure
  685. *
  686. * The parameter N_gradient_neighbours x(tcb) and y(tcb) and z(tb) are copied into the new allocated structure
  687. * and can be deleted after the initializing
  688. *
  689. * \return N_gradient_neighbours_3d * -- if failure NULL is returned
  690. *
  691. * */
  692. N_gradient_neighbours_3d
  693. * N_create_gradient_neighbours_3d(N_gradient_neighbours_x * xt,
  694. N_gradient_neighbours_x * xc,
  695. N_gradient_neighbours_x * xb,
  696. N_gradient_neighbours_y * yt,
  697. N_gradient_neighbours_y * yc,
  698. N_gradient_neighbours_y * yb,
  699. N_gradient_neighbours_z * zt,
  700. N_gradient_neighbours_z * zb)
  701. {
  702. N_gradient_neighbours_3d *grad;
  703. int fail = 0;
  704. G_debug(5,
  705. "N_create_gradient_neighbours_3d: create N_gradient_neighbours_3d");
  706. grad = N_alloc_gradient_neighbours_3d();
  707. if (!(N_copy_gradient_neighbours_x(xt, grad->xt)))
  708. fail++;
  709. if (!(N_copy_gradient_neighbours_x(xc, grad->xc)))
  710. fail++;
  711. if (!(N_copy_gradient_neighbours_x(xb, grad->xb)))
  712. fail++;
  713. if (!(N_copy_gradient_neighbours_y(yt, grad->yt)))
  714. fail++;
  715. if (!(N_copy_gradient_neighbours_y(yc, grad->yc)))
  716. fail++;
  717. if (!(N_copy_gradient_neighbours_y(yb, grad->yb)))
  718. fail++;
  719. if (!(N_copy_gradient_neighbours_z(zt, grad->zt)))
  720. fail++;
  721. if (!(N_copy_gradient_neighbours_z(zb, grad->zb)))
  722. fail++;
  723. if (fail > 0) {
  724. return NULL;
  725. }
  726. return grad;
  727. }
  728. /*!
  729. * \brief copy a N_gradient_neighbours_3d structure
  730. *
  731. * \param source - the source N_gradient_neighbours_3d struct
  732. * \param target - the target N_gradient_neighbours_3d struct
  733. * \return int - 1 success, 0 failure while copying
  734. *
  735. * */
  736. int
  737. N_copy_gradient_neighbours_3d(N_gradient_neighbours_3d * source,
  738. N_gradient_neighbours_3d * target)
  739. {
  740. int fail = 0;
  741. G_debug(5,
  742. "N_copy_gradient_neighbours_3d: copy N_gradient_neighbours_3d");
  743. if (!source || !target)
  744. return 0;
  745. if (!(N_copy_gradient_neighbours_x(source->xt, target->xt)))
  746. fail++;
  747. if (!(N_copy_gradient_neighbours_x(source->xc, target->xc)))
  748. fail++;
  749. if (!(N_copy_gradient_neighbours_x(source->xb, target->xb)))
  750. fail++;
  751. if (!(N_copy_gradient_neighbours_y(source->yt, target->yt)))
  752. fail++;
  753. if (!(N_copy_gradient_neighbours_y(source->yc, target->yc)))
  754. fail++;
  755. if (!(N_copy_gradient_neighbours_y(source->yb, target->yb)))
  756. fail++;
  757. if (!(N_copy_gradient_neighbours_z(source->zt, target->zt)))
  758. fail++;
  759. if (!(N_copy_gradient_neighbours_z(source->zb, target->zb)))
  760. fail++;
  761. if (fail > 0) {
  762. return 0;
  763. }
  764. return 1;
  765. }
  766. /*!
  767. * \brief Allocate a N_gradient_field_2d
  768. *
  769. * The field arrays are of type DCELL.
  770. *
  771. * \param rows - number of rows of the 2d array from which the gradient should be calculated
  772. * \param cols - number of cols of the 2d array from which the gradient should be calculated
  773. * \return N_gradient_field_2d *
  774. *
  775. * */
  776. N_gradient_field_2d *N_alloc_gradient_field_2d(int cols, int rows)
  777. {
  778. N_gradient_field_2d *field;
  779. G_debug(5,
  780. "N_alloc_gradient_field_2d: allocate a N_gradient_field_2d struct");
  781. field = (N_gradient_field_2d *) G_calloc(1, sizeof(N_gradient_field_2d));
  782. field->x_array = N_alloc_array_2d(cols, rows, 1, DCELL_TYPE);
  783. field->y_array = N_alloc_array_2d(cols, rows, 1, DCELL_TYPE);
  784. field->cols = cols;
  785. field->rows = rows;
  786. return field;
  787. }
  788. /*!
  789. * \brief Free's a N_gradient_neighbours_2d structure
  790. *
  791. * \return void
  792. *
  793. * */
  794. void N_free_gradient_field_2d(N_gradient_field_2d * field)
  795. {
  796. N_free_array_2d(field->x_array);
  797. N_free_array_2d(field->y_array);
  798. G_free(field);
  799. field = NULL;
  800. return;
  801. }
  802. /*!
  803. * \brief Copy N_gradient_field_2d structure from source to target
  804. *
  805. * \param source - the source N_gradient_field_2d struct
  806. * \param target - the target N_gradient_field_2d struct
  807. * \return int - 1 success, 0 failure while copying
  808. *
  809. * */
  810. int
  811. N_copy_gradient_field_2d(N_gradient_field_2d * source,
  812. N_gradient_field_2d * target)
  813. {
  814. G_debug(3, "N_copy_gradient_field_2d: copy N_gradient_field_2d");
  815. if (!source || !target)
  816. return 0;
  817. N_copy_array_2d(source->x_array, target->x_array);
  818. N_copy_array_2d(source->y_array, target->y_array);
  819. return 1;
  820. }
  821. /*! \brief Print gradient field information to stdout
  822. *
  823. * \param field N_gradient_2d_field *
  824. * \return void
  825. *
  826. * */
  827. void N_print_gradient_field_2d_info(N_gradient_field_2d * field)
  828. {
  829. fprintf(stdout, "N_gradient_field_2d \n");
  830. fprintf(stdout, "Cols %i\n", field->cols);
  831. fprintf(stdout, "Rows: %i\n", field->rows);
  832. fprintf(stdout, "X array pointer: %p\n", field->x_array);
  833. fprintf(stdout, "Y array pointer: %p\n", field->y_array);
  834. fprintf(stdout, "Min %g\n", field->min);
  835. fprintf(stdout, "Max %g\n", field->max);
  836. fprintf(stdout, "Sum %g\n", field->sum);
  837. fprintf(stdout, "Mean %g\n", field->mean);
  838. fprintf(stdout, "Nonull %i\n", field->nonull);
  839. fprintf(stdout, "X array info \n");
  840. N_print_array_2d_info(field->x_array);
  841. fprintf(stdout, "Y array info \n");
  842. N_print_array_2d_info(field->y_array);
  843. return;
  844. }
  845. /*!
  846. * \brief Allocate a N_gradient_field_3d
  847. *
  848. * The field arrays are always of type DCELL_TYPE.
  849. *
  850. * \param cols - number of cols of the 3d array from which the gradient should be calculated
  851. * \param rows - number of rows of the 3d array from which the gradient should be calculated
  852. * \param depths - number of depths of the 3d array from which the gradient should be calculated
  853. * \return N_gradient_field_3d *
  854. *
  855. * */
  856. N_gradient_field_3d *N_alloc_gradient_field_3d(int cols, int rows, int depths)
  857. {
  858. N_gradient_field_3d *field;
  859. G_debug(5,
  860. "N_alloc_gradient_field_3d: allocate a N_gradient_field_3d struct");
  861. field = (N_gradient_field_3d *) G_calloc(1, sizeof(N_gradient_field_3d));
  862. field->x_array = N_alloc_array_3d(cols, rows, depths, 1, DCELL_TYPE);
  863. field->y_array = N_alloc_array_3d(cols, rows, depths, 1, DCELL_TYPE);
  864. field->z_array = N_alloc_array_3d(cols, rows, depths, 1, DCELL_TYPE);
  865. field->cols = cols;
  866. field->rows = rows;
  867. field->depths = depths;
  868. return field;
  869. }
  870. /*!
  871. * \brief Free's a N_gradient_neighbours_3d structure
  872. *
  873. * \return void
  874. *
  875. * */
  876. void N_free_gradient_field_3d(N_gradient_field_3d * field)
  877. {
  878. N_free_array_3d(field->x_array);
  879. N_free_array_3d(field->y_array);
  880. N_free_array_3d(field->z_array);
  881. G_free(field);
  882. field = NULL;
  883. return;
  884. }
  885. /*!
  886. * \brief Copy N_gradient_field_3d structure from source to target
  887. *
  888. * \param source - the source N_gradient_field_3d struct
  889. * \param target - the target N_gradient_field_3d struct
  890. * \return int - 1 success, 0 failure while copying
  891. *
  892. * */
  893. int
  894. N_copy_gradient_field_3d(N_gradient_field_3d * source,
  895. N_gradient_field_3d * target)
  896. {
  897. G_debug(3, "N_copy_gradient_field_3d: copy N_gradient_field_3d");
  898. if (!source || !target)
  899. return 0;
  900. N_copy_array_3d(source->x_array, target->x_array);
  901. N_copy_array_3d(source->y_array, target->y_array);
  902. N_copy_array_3d(source->z_array, target->z_array);
  903. return 1;
  904. }
  905. /*! \brief Print gradient field information to stdout
  906. *
  907. * \param field N_gradient_3d_field *
  908. * \return void
  909. *
  910. * */
  911. void N_print_gradient_field_3d_info(N_gradient_field_3d * field)
  912. {
  913. fprintf(stdout, "N_gradient_field_3d \n");
  914. fprintf(stdout, "Cols %i\n", field->cols);
  915. fprintf(stdout, "Rows: %i\n", field->rows);
  916. fprintf(stdout, "Depths %i\n", field->depths);
  917. fprintf(stdout, "X array pointer: %p\n", field->x_array);
  918. fprintf(stdout, "Y array pointer: %p\n", field->y_array);
  919. fprintf(stdout, "Z array pointer: %p\n", field->z_array);
  920. fprintf(stdout, "Min %g\n", field->min);
  921. fprintf(stdout, "Max %g\n", field->max);
  922. fprintf(stdout, "Sum %g\n", field->sum);
  923. fprintf(stdout, "Mean %g\n", field->mean);
  924. fprintf(stdout, "Nonull %i\n", field->nonull);
  925. fprintf(stdout, "X array info \n");
  926. N_print_array_3d_info(field->x_array);
  927. fprintf(stdout, "Y array info \n");
  928. N_print_array_3d_info(field->y_array);
  929. fprintf(stdout, "Z array info \n");
  930. N_print_array_3d_info(field->z_array);
  931. return;
  932. }