[GRASS-SVN] r60951 - sandbox/annakrat/r3.flow
svn_grass at osgeo.org
svn_grass at osgeo.org
Tue Jun 24 20:49:21 PDT 2014
Author: annakrat
Date: 2014-06-24 20:49:21 -0700 (Tue, 24 Jun 2014)
New Revision: 60951
Added:
sandbox/annakrat/r3.flow/gradient.py
Log:
r3.flow: gradient computation implemented
Added: sandbox/annakrat/r3.flow/gradient.py
===================================================================
--- sandbox/annakrat/r3.flow/gradient.py (rev 0)
+++ sandbox/annakrat/r3.flow/gradient.py 2014-06-25 03:49:21 UTC (rev 60951)
@@ -0,0 +1,80 @@
+# -*- coding: utf-8 -*-
+"""
+ at brief Computing gradient
+
+ at author: Anna Petrasova
+"""
+
+import numpy as np
+import unittest
+
+
+def gradient(array, step):
+ """Computing gradient (second order approximation)
+ using central differencing scheme (plus forward and backward
+ difference of second order approx.)"""
+ size_z, size_y, size_x = array.shape
+
+ gradient_array_x = np.zeros(array.shape)
+ for depth in range(size_z):
+ for row in range(size_y):
+ col_array = array[depth, row, :]
+ gradient_array_x[depth, row, 0] = (-3 * col_array[0] +
+ 4 * col_array[1] -
+ col_array[2]) / (2 * step[0])
+ gradient_array_x[depth, row, size_x - 1] = (col_array[size_x - 3] -
+ 4 * col_array[size_x - 2] +
+ 3 * col_array[size_x - 1]) / (2 * step[0])
+ for col in range(1, size_x - 1):
+ gradient_array_x[depth, row, col] = (col_array[col + 1] -
+ col_array[col - 1]) / (2 * step[0])
+
+ gradient_array_y = np.zeros(array.shape)
+ for depth in range(size_z):
+ for col in range(size_x):
+ row_array = array[depth, :, col]
+ gradient_array_y[depth, 0, col] = (-3 * row_array[0] +
+ 4 * row_array[1] -
+ row_array[2]) / (2 * step[1])
+ gradient_array_y[depth, size_y - 1, col] = (row_array[size_y - 3] -
+ 4 * row_array[size_y - 2] +
+ 3 * row_array[size_y - 1]) / (2 * step[1])
+ for row in range(1, size_y - 1):
+ gradient_array_y[depth, row, col] = (row_array[row + 1] -
+ row_array[row - 1]) / (2 * step[1])
+
+ gradient_array_z = np.zeros(array.shape)
+ for row in range(size_y):
+ for col in range(size_x):
+ depth_array = array[:, row, col]
+ gradient_array_z[0, row, col] = (-3 * depth_array[0] +
+ 4 * depth_array[1] -
+ depth_array[2]) / (2 * step[2])
+ gradient_array_z[size_z - 1, row, col] = (depth_array[size_z - 3] -
+ 4 * depth_array[size_z - 2] +
+ 3 * depth_array[size_z - 1]) / (2 * step[2])
+ for depth in range(1, size_z - 1):
+ gradient_array_z[depth, row, col] = (depth_array[depth + 1] -
+ depth_array[depth - 1]) / (2 * step[2])
+
+ return gradient_array_x, gradient_array_y, gradient_array_z
+
+
+class TestGradient(unittest.TestCase):
+
+ def test_gradient(self):
+ array = np.random.rand(10, 15, 3)
+ step = [2, 0.6, 1]
+ # numpy_gradient is function gradient which must be taken from numpy master branch
+ # https://github.com/numpy/numpy/blob/master/numpy/lib/function_base.py
+ # because 1.8 uses first order approx on edges, not second
+ numpy_gradient_z, numpy_gradient_y, numpy_gradient_x = numpy_gradient(array, step[2], step[1], step[0])
+ gradient_x, gradient_y, gradient_z = gradient(array, step)
+
+ self.assertEqual(True, np.allclose(gradient_z, numpy_gradient_z, atol=1e-8))
+ self.assertEqual(True, np.allclose(gradient_y, numpy_gradient_y, atol=1e-8))
+ self.assertEqual(True, np.allclose(gradient_x, numpy_gradient_x, atol=1e-8))
+
+
+if __name__ == '__main__':
+ unittest.main()
More information about the grass-commit
mailing list