mdarray 0.5.3-java → 0.5.4-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. data/README.md +325 -70
  2. data/doc/20130625 MDArray Internals.docx +0 -0
  3. data/lib/colt/colt.rb +2 -0
  4. data/lib/colt/matrix/colt_matrix.rb +365 -0
  5. data/lib/colt/matrix/matrix2D_floating_algebra.rb +325 -0
  6. data/lib/colt/matrix/matrix_hierarchy.rb +258 -0
  7. data/lib/mdarray.rb +54 -3
  8. data/lib/mdarray/access.rb +16 -0
  9. data/lib/mdarray/counter.rb +16 -0
  10. data/lib/mdarray/creation.rb +13 -1
  11. data/lib/mdarray/lazy_mdarray.rb +6 -2
  12. data/lib/mdarray/lazy_operators.rb +8 -0
  13. data/lib/mdarray/printing.rb +18 -3
  14. data/lib/mdarray/section.rb +101 -0
  15. data/lib/netcdf/attribute.rb +154 -0
  16. data/lib/netcdf/cdm_node.rb +71 -0
  17. data/lib/netcdf/dimension.rb +146 -0
  18. data/lib/netcdf/file.rb +253 -0
  19. data/lib/netcdf/file_writer.rb +474 -0
  20. data/lib/netcdf/group.rb +205 -0
  21. data/lib/netcdf/netcdf.rb +151 -0
  22. data/lib/netcdf/variable.rb +520 -0
  23. data/test/colt/test_complete.rb +1 -2
  24. data/test/colt/test_double_matrix2d.rb +186 -0
  25. data/test/colt/test_float_matrix2d.rb +171 -0
  26. data/test/colt/test_math.rb +21 -0
  27. data/test/colt/test_matrix.rb +172 -0
  28. data/test/complete.rb +9 -1
  29. data/test/env.rb +11 -1
  30. data/test/mdarray/test_complete.rb +2 -0
  31. data/test/mdarray/test_creation.rb +19 -28
  32. data/test/mdarray/test_non_numeric.rb +97 -0
  33. data/test/mdarray/test_sections.rb +94 -0
  34. data/test/mdarray/test_views.rb +23 -1
  35. data/test/netcdf/netcdfwriter.rb +197 -0
  36. data/test/netcdf/test_complete.rb +27 -0
  37. data/test/netcdf/test_netcdf.rb +331 -0
  38. data/test/netcdf/test_redefine.rb +120 -0
  39. data/vendor/incanter.jar +0 -0
  40. data/vendor/{netcdfAll-4.3.16.jar → netcdfAll-4.3.18.jar} +0 -0
  41. data/version.rb +1 -1
  42. metadata +44 -26
  43. data/vendor/parallelcolt-0.10.0.jar +0 -0
@@ -23,4 +23,12 @@ require 'env.rb'
23
23
 
24
24
  require 'mdarray/test_complete'
25
25
  require 'colt/test_complete'
26
- # require 'mdarray/test_lazy'
26
+ require 'netcdf/test_complete'
27
+
28
+
29
+ # Temporary tests. Remove before shipping!
30
+
31
+ # require 'colt/test_matrix'
32
+ # require 'netcdf/test_netcdf'
33
+ # require 'mdarray/test_sections'
34
+ # require 'netcdf/netcdfwriter'
@@ -19,6 +19,9 @@ $MDARRAY_TEST_DIR = "./mdarray"
19
19
  # Colt Test directory
20
20
  $COLT_TEST_DIR = "./colt"
21
21
 
22
+ # Tmp directory
23
+ $TMP_TEST_DIR = "./tmp"
24
+
22
25
  # Need to change this variable before publication
23
26
  # $MDARRAY_ENV = 'cygwin'
24
27
 
@@ -34,6 +37,7 @@ if $COVERAGE == 'true'
34
37
  @filters = []
35
38
  add_group "MDArray", "lib/mdarray"
36
39
  add_group "Colt", "lib/colt"
40
+ add_group "NetCDF", "lib/netcdf"
37
41
  end
38
42
 
39
43
  end
@@ -75,7 +79,13 @@ if $MDARRAY_ENV == 'cygwin'
75
79
 
76
80
  $MDARRAY_TEST_DIR = cygpath($MDARRAY_TEST_DIR)
77
81
  $COLT_TEST_DIR = cygpath($COLT_TEST_DIR)
78
-
82
+
83
+ else
84
+
85
+ def cygpath(path)
86
+ path
87
+ end
88
+
79
89
  end
80
90
 
81
91
  =begin
@@ -50,6 +50,7 @@
50
50
 
51
51
  #=begin
52
52
  require_relative 'test_creation'
53
+ require_relative 'test_non_numeric'
53
54
  require_relative 'test_access'
54
55
  require_relative 'test_operator'
55
56
  require_relative 'arithmetic_casting'
@@ -61,5 +62,6 @@ require_relative 'test_trigonometry'
61
62
  require_relative 'test_views'
62
63
  require_relative 'test_printing'
63
64
  require_relative 'test_lazy'
65
+ require_relative 'test_sections'
64
66
  #require_relative 'test_performance'
65
67
  #=end
@@ -316,45 +316,36 @@ class MDArrayTest < Test::Unit::TestCase
316
316
  end
317
317
 
318
318
  #-------------------------------------------------------------------------------------
319
- #
319
+ # Creates a scalar array, i.e, array of size 0. In general this is not necessary and
320
+ # should not be used as one can operate with scalars directly. This is however needed
321
+ # for writing scalar values on NetCDF-3 files.
320
322
  #-------------------------------------------------------------------------------------
321
323
 
322
- should "create boolean arrays" do
323
-
324
- bool = MDArray.boolean([2, 2])
325
- bool[0, 0] = true
326
- assert_raise ( RuntimeError ) { bool[0, 1] = 10.0 }
327
- assert_equal(bool[0, 0], true)
328
- bool[0, 1] = false
329
- assert_equal(bool[0, 1], false)
324
+ should "create scalar arrays" do
330
325
 
331
- end
326
+ scalar = MDArray.double([])
327
+ scalar.set_scalar(2.55)
328
+ assert_equal(2.55, scalar.get_scalar)
332
329
 
333
- #-------------------------------------------------------------------------------------
334
- #
335
- #-------------------------------------------------------------------------------------
336
-
337
- should "create string arrays" do
338
-
339
- sarray = MDArray.string([2, 3], ["hello", "this", "is", "a", "string", "array"])
340
- assert_equal(6, sarray.size)
341
- assert_equal("hello", sarray.get([0, 0]))
342
- assert_equal("hello this is a string array ", sarray.to_string)
330
+ scalar2 = MDArray.double([])
331
+ scalar2.set_scalar(5.55)
332
+
333
+ scalar3 = scalar + scalar2
343
334
 
344
335
  end
345
336
 
346
337
  #-------------------------------------------------------------------------------------
347
- # A struct array is an array of pointers to structures
338
+ # Creates a MDArray from a java array. Needed for some internal methods. Not to be
339
+ # used in general
348
340
  #-------------------------------------------------------------------------------------
349
341
 
350
- should "create struct arrays" do
342
+ should "creade arrays from java arrays" do
351
343
 
352
- m = Hash.new
353
- m[:hello] = "world"
354
- m[:test] = 1.23
355
-
356
- struct = MDArray.structure([10])
357
- struct[0] = m
344
+ value = Array.new
345
+ (0...5).each do |val|
346
+ value << val.to_java(:float)
347
+ end
348
+ MDArray.from_jstorage("float", [1], value.to_java(:float))
358
349
 
359
350
  end
360
351
 
@@ -0,0 +1,97 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ ##########################################################################################
4
+ # Copyright © 2013 Rodrigo Botafogo. All Rights Reserved. Permission to use, copy, modify,
5
+ # and distribute this software and its documentation, without fee and without a signed
6
+ # licensing agreement, is hereby granted, provided that the above copyright notice, this
7
+ # paragraph and the following two paragraphs appear in all copies, modifications, and
8
+ # distributions.
9
+ #
10
+ # IN NO EVENT SHALL RODRIGO BOTAFOGO BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
11
+ # INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF
12
+ # THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RODRIGO BOTAFOGO HAS BEEN ADVISED OF THE
13
+ # POSSIBILITY OF SUCH DAMAGE.
14
+ #
15
+ # RODRIGO BOTAFOGO SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
17
+ # SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
18
+ # RODRIGO BOTAFOGO HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
19
+ # OR MODIFICATIONS.
20
+ ##########################################################################################
21
+
22
+ require 'rubygems'
23
+ require "test/unit"
24
+ require 'shoulda'
25
+
26
+ require 'mdarray'
27
+
28
+ class MDArrayTest < Test::Unit::TestCase
29
+
30
+ context "Non-numeric Array Creation" do
31
+
32
+ #-------------------------------------------------------------------------------------
33
+ # array creation always requires the type and shape, differently from NumPy
34
+ # narray in which the type and shape can be inferred from the initialization
35
+ # data. MDArray can be numerical and non-numerical. Numerical MDArrays can be of
36
+ # type: byte, short, int, long, double. Non-numerical MDArrays can be of type
37
+ # boolean, char, string.
38
+ #-------------------------------------------------------------------------------------
39
+
40
+ #-------------------------------------------------------------------------------------
41
+ #
42
+ #-------------------------------------------------------------------------------------
43
+
44
+ should "create boolean arrays" do
45
+
46
+ bool = MDArray.boolean([2, 2])
47
+ bool[0, 0] = true
48
+ assert_raise ( RuntimeError ) { bool[0, 1] = 10.0 }
49
+ assert_equal(bool[0, 0], true)
50
+ bool[0, 1] = false
51
+ assert_equal(bool[0, 1], false)
52
+
53
+ end
54
+
55
+ #-------------------------------------------------------------------------------------
56
+ #
57
+ #-------------------------------------------------------------------------------------
58
+
59
+ should "create string arrays" do
60
+
61
+ sarray = MDArray.string([2, 3], ["hello", "this", "is", "a", "string", "array"])
62
+ assert_equal(6, sarray.size)
63
+ assert_equal("hello", sarray.get([0, 0]))
64
+ assert_equal("hello this is a string array ", sarray.to_string)
65
+ sarray.print
66
+
67
+ sarray2 = MDArray.string([], ["hello, this is a string array"])
68
+ p sarray2.shape
69
+ sarray2.print
70
+
71
+ sarray3 = MDArray.string([3],
72
+ ["No pairs of ladies stockings!",
73
+ "One pair of ladies stockings!",
74
+ "Two pairs of ladies stockings!"])
75
+ p sarray3.shape
76
+ sarray3.print
77
+
78
+ end
79
+
80
+ #-------------------------------------------------------------------------------------
81
+ # A struct array is an array of pointers to structures
82
+ #-------------------------------------------------------------------------------------
83
+
84
+ should "create struct arrays" do
85
+
86
+ m = Hash.new
87
+ m[:hello] = "world"
88
+ m[:test] = 1.23
89
+
90
+ struct = MDArray.structure([10])
91
+ struct[0] = m
92
+
93
+ end
94
+
95
+ end
96
+
97
+ end
@@ -0,0 +1,94 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ ##########################################################################################
4
+ # Copyright © 2013 Rodrigo Botafogo. All Rights Reserved. Permission to use, copy, modify,
5
+ # and distribute this software and its documentation, without fee and without a signed
6
+ # licensing agreement, is hereby granted, provided that the above copyright notice, this
7
+ # paragraph and the following two paragraphs appear in all copies, modifications, and
8
+ # distributions.
9
+ #
10
+ # IN NO EVENT SHALL RODRIGO BOTAFOGO BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
11
+ # INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF
12
+ # THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RODRIGO BOTAFOGO HAS BEEN ADVISED OF THE
13
+ # POSSIBILITY OF SUCH DAMAGE.
14
+ #
15
+ # RODRIGO BOTAFOGO SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
17
+ # SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
18
+ # RODRIGO BOTAFOGO HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
19
+ # OR MODIFICATIONS.
20
+ ##########################################################################################
21
+
22
+ require 'rubygems'
23
+ require "test/unit"
24
+ require 'shoulda'
25
+
26
+ require 'mdarray'
27
+
28
+ class MDArrayTest < Test::Unit::TestCase
29
+
30
+ context "Section Tests" do
31
+
32
+ setup do
33
+
34
+ end
35
+
36
+ #-------------------------------------------------------------------------------------
37
+ # Create a new Array using same backing store as this Array, by fixing the specified
38
+ # dimension at the specified index value. This reduces rank by 1.
39
+ #-------------------------------------------------------------------------------------
40
+
41
+ should "create sections" do
42
+
43
+ #-----------------------------------------------------------------------------------
44
+ # create a section from a section spec
45
+ # Parse an index section String specification, return equivilent Section. A null
46
+ # Range means "all" (i.e.":") indices in that dimension.
47
+ # The sectionSpec string uses fortran90 array section syntax, namely:
48
+ #
49
+ # sectionSpec := dims
50
+ # dims := dim | dim, dims
51
+ # dim := ':' | slice | start ':' end | start ':' end ':' stride
52
+ # slice := INTEGER
53
+ # start := INTEGER
54
+ # stride := INTEGER
55
+ # end := INTEGER
56
+ #
57
+ # where nonterminals are in lower case, terminals are in upper case, literals are in
58
+ # single quotes.
59
+ #
60
+ # Meaning of index selector :
61
+ # ':' = all
62
+ # slice = hold index to that value
63
+ # start:end = all indices from start to end inclusive
64
+ # start:end:stride = all indices from start to end inclusive with given stride
65
+ #-----------------------------------------------------------------------------------
66
+
67
+ # creates a section from a spec
68
+ section = MDArray::Section.build(:spec => "0:0,0:5:5")
69
+ assert_equal("0:0,0:5:5", section.to_s)
70
+
71
+ section = MDArray::Section.build(:spec => ":,5:10,3:27:3")
72
+ assert_equal(":,5:10,3:27:3", section.to_s)
73
+
74
+ # cannot create a section with only the origin, we also need the size and stride
75
+ assert_raise ( RuntimeError ) { MDArray::Section.build(:origin => [0, 0]) }
76
+
77
+ # create a section with origin, size and stride
78
+ section = MDArray::Section.build(:origin => [0, 0], :size => [5, 10],
79
+ :stride => [2, 3])
80
+ assert_equal("0:4:2,0:9:3", section.to_s)
81
+
82
+ # create a section with origin and shape
83
+ section = MDArray::Section.build(:origin => [5, 1, 2], :shape => [10, 3, 7])
84
+ section.print
85
+
86
+ # create a section from shape only
87
+ section = MDArray::Section.build(:shape => [10, 3, 7])
88
+ assert_equal("0:9,0:2,0:6", section.to_s)
89
+
90
+ end
91
+
92
+ end
93
+
94
+ end
@@ -1,3 +1,24 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ ##########################################################################################
4
+ # Copyright © 2013 Rodrigo Botafogo. All Rights Reserved. Permission to use, copy, modify,
5
+ # and distribute this software and its documentation, without fee and without a signed
6
+ # licensing agreement, is hereby granted, provided that the above copyright notice, this
7
+ # paragraph and the following two paragraphs appear in all copies, modifications, and
8
+ # distributions.
9
+ #
10
+ # IN NO EVENT SHALL RODRIGO BOTAFOGO BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
11
+ # INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF
12
+ # THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RODRIGO BOTAFOGO HAS BEEN ADVISED OF THE
13
+ # POSSIBILITY OF SUCH DAMAGE.
14
+ #
15
+ # RODRIGO BOTAFOGO SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
17
+ # SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
18
+ # RODRIGO BOTAFOGO HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
19
+ # OR MODIFICATIONS.
20
+ ##########################################################################################
21
+
1
22
  require 'rubygems'
2
23
  require "test/unit"
3
24
  require 'shoulda'
@@ -250,6 +271,7 @@ class MDArrayTest < Test::Unit::TestCase
250
271
  end
251
272
 
252
273
  #-------------------------------------------------------------------------------------
274
+ #
253
275
  #-------------------------------------------------------------------------------------
254
276
 
255
277
  should "permute array indices" do
@@ -273,7 +295,7 @@ class MDArrayTest < Test::Unit::TestCase
273
295
  # backing store as the original array.
274
296
  #-------------------------------------------------------------------------------------
275
297
 
276
- should "permute array indices" do
298
+ should "transpose array indices" do
277
299
 
278
300
  # c shape is [2, 3, 4]
279
301
  # b shape is now [3, 2, 4] by transposing the first two dimensions
@@ -0,0 +1,197 @@
1
+ require 'mdarray'
2
+
3
+ class NetCDF
4
+
5
+ attr_reader :dir, :filename, :max_strlen
6
+
7
+ #---------------------------------------------------------------------------------------
8
+ #
9
+ #---------------------------------------------------------------------------------------
10
+
11
+ def initialize
12
+ @dir = $TMP_TEST_DIR
13
+ @filename1 = "testWriter"
14
+ @filename2 = "testWriteRecord2"
15
+ @max_strlen = 80
16
+ end
17
+
18
+ #---------------------------------------------------------------------------------------
19
+ # Define the NetCDF-3 file
20
+ #---------------------------------------------------------------------------------------
21
+
22
+ def define_file
23
+
24
+ # We pass the directory, filename, filetype and optionaly the outside_scope.
25
+ #
26
+ # I'm implementing in cygwin, so the need for method cygpath that converts the
27
+ # directory name to a Windows name. In another environment, just pass the directory
28
+ # name.
29
+ #
30
+ # Inside a block we have another scope, so the block cannot access any variables, etc.
31
+ # from the ouside scope. If we pass the outside scope, in this case we are passing self,
32
+ # we can access variables in the outside scope by using @outside_scope.<variable>.
33
+ NetCDF.define(cygpath(@dir), @filename1, "netcdf3", self) do
34
+
35
+ # add dimensions
36
+ dimension "lat", 64
37
+ dimension "lon", 128
38
+
39
+ # add variables and attributes
40
+ # add Variable double temperature(lat, lon)
41
+ variable "temperature", "double", [@dim_lat, @dim_lon]
42
+ variable_att @var_temperature, "units", "K"
43
+ variable_att @var_temperature, "scale", [1, 2, 3]
44
+
45
+ # add a string-value variable: char svar(80)
46
+ # note that this is created as a scalar variable although in NetCDF-3 there is no
47
+ # string type and the string has to be represented as a char type.
48
+ variable "svar", "string", [], {:max_strlen => @outside_scope.max_strlen}
49
+
50
+ # add a 2D string-valued variable: char names(names, 80)
51
+ dimension "names", 3
52
+ variable "names", "string", [@dim_names], {:max_strlen => @outside_scope.max_strlen}
53
+
54
+ # add a scalar variable
55
+ variable "scalar", "double", []
56
+
57
+ # add global attributes
58
+ global_att "yo", "face"
59
+ global_att "versionD", 1.2, "double"
60
+ global_att "versionF", 1.2, "float"
61
+ global_att "versionI", 1, "int"
62
+ global_att "versionS", 2, "short"
63
+ global_att "versionB", 3, "byte"
64
+
65
+ end
66
+
67
+ end
68
+
69
+ #---------------------------------------------------------------------------------------
70
+ # write data on the above define file
71
+ #---------------------------------------------------------------------------------------
72
+
73
+ def write_file
74
+
75
+ NetCDF.write(cygpath(@dir), @filename1, self) do
76
+
77
+ temperature = find_variable("temperature")
78
+ shape = temperature.shape
79
+ data = MDArray.fromfunction("double", shape) do |i, j|
80
+ i * 1_000_000 + j * 1_000
81
+ end
82
+ write(temperature, data)
83
+
84
+ svar = find_variable("svar")
85
+ write_string(svar, "Two pairs of ladies stockings!")
86
+
87
+ names = find_variable("names")
88
+ # careful here with the shape of a string variable. A string variable has one
89
+ # more dimension than it should as there is no string type in NetCDF-3. As such,
90
+ # if we look as names' shape it has 2 dimensions, be we need to create a one
91
+ # dimension string array.
92
+ data = MDArray.string([3], ["No pairs of ladies stockings!",
93
+ "One pair of ladies stockings!",
94
+ "Two pairs of ladies stockings!"])
95
+ write_string(names, data)
96
+
97
+ # write scalar data
98
+ scalar = find_variable("scalar")
99
+ write(scalar, 222.333 )
100
+
101
+ end
102
+
103
+ end
104
+
105
+ #---------------------------------------------------------------------------------------
106
+ # Define a file for writing one record at a time
107
+ #---------------------------------------------------------------------------------------
108
+
109
+ def define_one_at_time
110
+
111
+ NetCDF.define(cygpath(@dir), @filename2, "netcdf3", self) do
112
+
113
+ dimension "lat", 3
114
+ dimension "lon", 4
115
+ # zero sized dimension is an unlimited dimension
116
+ dimension "time", 0
117
+
118
+ variable "lat", "float", [@dim_lat]
119
+ variable_att @var_lat, "units", "degree_north"
120
+
121
+ variable "lon", "float", [@dim_lon]
122
+ variable_att @var_lon, "units", "degree_east"
123
+
124
+ variable "rh", "int", [@dim_time, @dim_lat, @dim_lon]
125
+ variable_att @var_rh, "long_name", "relative humidity"
126
+ variable_att @var_rh, "units", "percent"
127
+
128
+ variable "T", "double", [@dim_time, @dim_lat, @dim_lon]
129
+ variable_att @var_t, "long_name", "surface temperature"
130
+ variable_att @var_t, "units", "degC"
131
+
132
+ variable "time", "int", [@dim_time]
133
+ variable_att @var_time, "units", "hours since 1990-01-01"
134
+
135
+ end
136
+
137
+ end
138
+
139
+ #---------------------------------------------------------------------------------------
140
+ # Define a file for writing one record at a time
141
+ #---------------------------------------------------------------------------------------
142
+
143
+ def write_one_at_time
144
+
145
+ NetCDF.write(cygpath(@dir), @filename2, self) do
146
+
147
+ lat = find_variable("lat")
148
+ lon = find_variable("lon")
149
+ write(lat, MDArray.float([3], [41, 40, 39]))
150
+ write(lon, MDArray.float([4], [-109, -107, -105, -103]))
151
+
152
+ # get variables from file
153
+ rh = find_variable("rh")
154
+ time = find_variable("time")
155
+ t = find_variable("T")
156
+
157
+ # there is no method find_dimension for NetcdfFileWriter, so we need to get the
158
+ # dimension from a variable.
159
+ rh_shape = rh.shape
160
+ dim_lat = rh_shape[1]
161
+ dim_lon = rh_shape[2]
162
+
163
+ (0...10).each do |time_idx|
164
+
165
+ # fill rh_data array
166
+ rh_data = MDArray.fromfunction("int", [dim_lat, dim_lon]) do |lat, lon|
167
+ time_idx * lat * lon
168
+ end
169
+ # reshape rh_data so that it has the same shape as rh variable
170
+ # Method reshape! reshapes the array in-place without data copying.
171
+ rh_data.reshape!([1, dim_lat, dim_lon])
172
+
173
+ # fill temp_data array
174
+ temp_data = MDArray.fromfunction("double", [dim_lat, dim_lon]) do |lat, lon|
175
+ time_idx * lat * lon / 3.14159
176
+ end
177
+ # reshape temp_data array so that it has the same shape as temp variable.
178
+ temp_data.reshape!([1, dim_lat, dim_lon])
179
+
180
+ # write the variables
181
+ write(time, MDArray.int([1], [time_idx * 12]), [time_idx])
182
+ write(rh, rh_data, [time_idx, 0, 0])
183
+ write(t, temp_data, [time_idx, 0, 0])
184
+
185
+ end # End time_idx loop
186
+
187
+ end
188
+
189
+ end
190
+
191
+ end
192
+
193
+ netcdf = NetCDF.new
194
+ netcdf.define_file
195
+ netcdf.write_file
196
+ netcdf.define_one_at_time
197
+ netcdf.write_one_at_time