mdarray 0.5.4-java → 0.5.5-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.
@@ -34,21 +34,40 @@
34
34
  # WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
35
35
  ##########################################################################################
36
36
 
37
+
37
38
  ##########################################################################################
38
- # Copyright © 2013 Rodrigo Botafogo. All Rights Reserved. Permission to use, copy, modify,
39
- # and distribute this software and its documentation, without fee and without a signed
40
- # licensing agreement, is hereby granted, provided that the above copyright notice, this
41
- # paragraph and the following two paragraphs appear in all copies, modifications, and
42
- # distributions.
43
- #
44
- # IN NO EVENT SHALL RODRIGO BOTAFOGO BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
45
- # INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF
46
- # THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RODRIGO BOTAFOGO HAS BEEN ADVISED OF THE
47
- # POSSIBILITY OF SUCH DAMAGE.
48
- #
49
- # RODRIGO BOTAFOGO SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
50
- # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
51
- # SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
52
- # RODRIGO BOTAFOGO HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
53
- # OR MODIFICATIONS.
39
+ This version of MDArray is licensed under the BSD 2-clause license.
40
+
41
+ * http://sciruby.com
42
+ * http://github.com/sciruby/sciruby/wiki/License
43
+
44
+ You *must* read the Contributor Agreement before contributing code to the SciRuby Project.
45
+ This is available online:
46
+
47
+ * http://github.com/sciruby/sciruby/wiki/Contributor-Agreement
48
+
49
+ -----
50
+
51
+ Copyright (c) 2010 - 2013, Rodrigo Botafogo and Ruby Science Foundation
52
+ All rights reserved.
53
+
54
+ Redistribution and use in source and binary forms, with or without modification, are permitted
55
+ provided that the following conditions are met:
56
+
57
+ * Redistributions of source code must retain the above copyright notice, this list of conditions
58
+ and the following disclaimer.
59
+
60
+ * Redistributions in binary form must reproduce the above copyright notice, this list of
61
+ conditions and the following disclaimer in the documentation and/or other materials provided
62
+ with the distribution.
63
+
64
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
65
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
66
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
67
+ THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
68
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
69
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
70
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
71
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
72
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54
73
  ##########################################################################################
data/README.md CHANGED
@@ -1,48 +1,124 @@
1
1
  Announcement
2
2
  ============
3
3
 
4
- MDArray version 0.5.4 has Just been released. MDArray is a multi dimensional array implemented
5
- for JRuby inspired by NumPy (www.numpy.org) and Masahiro Tanaka´s Narray (narray.rubyforge.org).
4
+ MDArray version 0.5.5 has Just been released. MDArray is a multi dimensional array implemented
5
+ for JRuby inspired by NumPy (www.numpy.org) and Masahiro Tanaka´s Narray (narray.rubyforge.org).
6
6
  MDArray stands on the shoulders of Java-NetCDF and Parallel Colt. At this point MDArray has
7
- libraries for mathematical, trigonometric and descriptive statistics methods.
7
+ libraries for linear algebra, mathematical, trigonometric and descriptive statistics methods.
8
8
 
9
9
  NetCDF-Java Library is a Java interface to NetCDF files, as well as to many other types of
10
- scientific data formats. It is developed and distributed by Unidata
11
- (http://www.unidata.ucar.edu).
10
+ scientific data formats. It is developed and distributed by Unidata (http://www.unidata.ucar.edu).
11
+
12
+ Parallel Colt (https://sites.google.com/site/piotrwendykier/software/parallelcolt is a
13
+ multithreaded version of Colt (http://acs.lbl.gov/software/colt/). Colt provides a set of
14
+ Open Source Libraries for High Performance Scientific and Technical Computing in Java.
15
+ Scientific and technical computing is characterized by demanding problem sizes and a need for
16
+ high performance at reasonably small memory footprint.
12
17
 
13
- Parallel Colt (http://grepcode.com/snapshot/repo1.maven.org/maven2/net.sourceforge.parallelcolt/
14
- parallelcolt/0.10.0/) is a multithreaded version of Colt (http://acs.lbl.gov/software/colt/).
15
- Colt provides a set of Open Source Libraries for High Performance Scientific and Technical
16
- Computing in Java. Scientific and technical computing is characterized by demanding problem
17
- sizes and a need for high performance at reasonably small memory footprint.
18
-
19
- For more information and (some) documentation please go to: https://github.com/rbotafogo/mdarray/wiki
20
18
 
21
19
  What´s new:
22
20
  ===========
23
21
 
24
- NetCDF-3 File Support
25
- ---------------------
26
-
27
- From Wikipedia, the free encyclopedia:
28
-
29
- "NetCDF (Network Common Data Form) is a set of software libraries and self-describing,
30
- machine-independent data formats that support the creation, access, and sharing of array-oriented
31
- scientific data. The project homepage is hosted by the Unidata program at the University
32
- Corporation for Atmospheric Research (UCAR). They are also the chief source of netCDF software,
33
- standards development, updates, etc. The format is an open standard. NetCDF Classic and 64-bit
34
- Offset Format are an international standard of the Open Geospatial Consortium.
35
-
36
- The project is actively supported by UCAR. Version 4.0 (released in 2008) allows the use of the
37
- HDF5 data file format. Version 4.1 (2010) adds support for C and Fortran client access to
38
- specified subsets of remote data via OPeNDAP.
39
-
40
- The format was originally based on the conceptual model of the Common Data Format developed by
41
- NASA, but has since diverged and is not compatible with it."
42
-
43
- This version of MDArray implements NetCDF-3 file support only. NetCDF-4 is not yet supported. At
44
- the end of this announcement we show the MDArray implementation of the NetCDF-3 writing from the
45
- tutorial at: http://www.unidata.ucar.edu/software/netcdf-java/tutorial/NetcdfWriting.html
22
+ Class MDMatrix and Linear Algebra Methods
23
+ -----------------------------------------
24
+
25
+ This version of MDArray introduces class MDMatrix. MDMatrix is a matrix class wrapping many
26
+ linear algebra methods from Parallel Colt (see below). MDMatrix support only the following
27
+ types: i) int; ii) long; iii) float and iv) double.
28
+
29
+ Differently from other libraries, in which matrix is a subclass of array, MDMatrix is a
30
+ twin class of MDArray. MDMatrix is a twin class of MDArray as every time an MDMatrix is
31
+ instantiated, an MDArray class is also instantiated. In reality, there is only one backing
32
+ store that can be viewed by either MDMatrix or MDArray.
33
+
34
+ Creation of MDMatrix follows the same API as MDArray API. For instance, creating a double
35
+ square matrix of size 5 x 5 can be done by:
36
+
37
+ matrix = MDMatrix.double([5, 5], [2.0, 0.0, 8.0, 6.0, 0.0,\
38
+ 1.0, 6.0, 0.0, 1.0, 7.0,\
39
+ 5.0, 0.0, 7.0, 4.0, 0.0,\
40
+ 7.0, 0.0, 8.0, 5.0, 0.0,\
41
+ 0.0, 10.0, 0.0, 0.0, 7.0])
42
+
43
+ Creating an int matrix filled with zero can be done by:
44
+
45
+ matrix = MDMatrix.int([4, 3])
46
+
47
+ MDMatrix also supports creation based on methods such as fromfunction, linspace, init_with,
48
+ arange, typed_arange and ones:
49
+
50
+
51
+ array = MDArray.typed_arange("double", 0, 15)
52
+ array = MDMatrix.fromfunction("double", [4, 4]) { |x, y| x + y }
53
+
54
+ An MDMatrix can also be created from an MDArray as follows:
55
+
56
+ d2 = MDArray.typed_arange("double", 0, 15)
57
+ double_matrix = MDMatrix.from_mdarray(d2)
58
+
59
+ An MDMatrix can only be created from MDArrays of one, two or three dimensions. However,
60
+ one can take a view from an MDArray to create an MDMatrix, as long as the view is at most
61
+ three dimensional:
62
+
63
+ # Instantiate an MDArray and shape it with 4 dimensions
64
+ > d1 = MDArray.typed_arange("double", 0, 420)
65
+ > d1.reshape!([5, 4, 3, 7])
66
+ # slice the array, getting a three dimensional array and from that, make a matrix
67
+ > matrix = MDMatrix.from_mdarray(d1.slice(0, 0))
68
+ # get a region from the array, with the first two dimensions of size 0, reduce it to a
69
+ # size two array and then build a two dimensional matrix
70
+ > matrix = MDMatrix.from_mdarray(d1.region(:spec => "0:0, 0:0, 0:2, 0:6").reduce)
71
+
72
+ printing the above two dimensional matrix gives us:
73
+
74
+ > matrix.print
75
+ 3 x 7 matrix
76
+ 0,00000 1,00000 2,00000 3,00000 4,00000 5,00000 6,00000
77
+ 7,00000 8,00000 9,00000 10,0000 11,0000 12,0000 13,0000
78
+ 14,0000 15,0000 16,0000 17,0000 18,0000 19,0000 20,0000
79
+
80
+ Every MDMatrix instance has a twin MDArray instance that uses the same backing store. This
81
+ allows the user to treat the data as either a matrix or an array and use methods either from
82
+ matrix or array. The above matrix can be printed as an array:
83
+
84
+
85
+ > matrix.mdarray.print
86
+ [[0.00 1.00 2.00 3.00 4.00 5.00 6.00]
87
+ [7.00 8.00 9.00 10.00 11.00 12.00 13.00]
88
+ [14.00 15.00 16.00 17.00 18.00 19.00 20.00]]
89
+
90
+ With an MDMatrix, many linear algebra methods can be easily calculated:
91
+
92
+ # basic operations on matrix can be done, such as, ‘+’, ‘-‘, ´*’, ‘/’
93
+ # make a 4 x 4 matrix and fill it with ´double´ 2.5
94
+ > a = MDMatrix.double([4, 4])
95
+ > a.fill(2.5)
96
+ > make a 4 x 4 matrix ´b´ from a given function (block)
97
+ > b = MDMatrix.fromfunction("double", [4, 4]) { |x, y| x + y }
98
+ # add both matrices
99
+ > c = a + b
100
+ # multiply by scalar
101
+ > c = a * 2
102
+ # divide two matrices. Matrix ´b´ has to be non-singular, otherwise an exception is
103
+ # raised.
104
+ # generate a non-singular matrix from a given matrix
105
+ > b.generate_non_singular!
106
+ > c = a / b
107
+
108
+ Linear algebra methods:
109
+
110
+ # create a matrix with the given data
111
+ > pos = MDArray.double([3, 3], [4, 12, -16, 12, 37, -43, -16, -43, 98])
112
+ > matrix = MDMatrix.from_mdarray(pos)
113
+ # Cholesky decomposition from wikipedia example
114
+ > chol = matrix.chol
115
+ > assert_equal(2, chol[0, 0])
116
+ > assert_equal(6, chol[1, 0])
117
+ > assert_equal(-8, chol[2, 0])
118
+ > assert_equal(5, chol[2, 1])
119
+ > assert_equal(3, chol[2, 2])
120
+
121
+ All other linear algebra methods are called the same way.
46
122
 
47
123
 
48
124
  MDArray and SciRuby:
@@ -63,6 +139,7 @@ MDArray main properties are:
63
139
 
64
140
  + Homogeneous multidimensional array, a table of elements (usually numbers), all of the
65
141
  same type, indexed by a tuple of positive integers;
142
+ + Support for many linear algebra methods (see bellow);
66
143
  + Easy calculation for large numerical multi dimensional arrays;
67
144
  + Basic types are: boolean, byte, short, int, long, float, double, string, structure;
68
145
  + Based on JRuby, which allows importing Java libraries;
@@ -81,6 +158,74 @@ MDArray main properties are:
81
158
  statistics;
82
159
  + Experimental lazy evaluation (still slower than eager evaluation).
83
160
 
161
+ Supported linear algebra methods:
162
+ =================================
163
+
164
+ + backwardSolve: Solves the upper triangular system U*x=b;
165
+ + chol: Constructs and returns the cholesky-decomposition of the given matrix.
166
+ + cond: Returns the condition of matrix A, which is the ratio of largest to smallest singular value.
167
+ + det: Returns the determinant of matrix A.
168
+ + eig: Constructs and returns the Eigenvalue-decomposition of the given matrix.
169
+ + forwardSolve: Solves the lower triangular system L*x=b;
170
+ + inverse: Returns the inverse or pseudo-inverse of matrix A.
171
+ + kron: Computes the Kronecker product of two real matrices.
172
+ + lu: Constructs and returns the LU-decomposition of the given matrix.
173
+ + mult: Inner product of two vectors; Sum(x[i] * y[i]).
174
+ + mult: Linear algebraic matrix-vector multiplication; z = A * y.
175
+ + mult: Linear algebraic matrix-matrix multiplication; C = A x B.
176
+ + multOuter: Outer product of two vectors; Sets A[i,j] = x[i] * y[j].
177
+ + norm1: Returns the one-norm of vector x, which is Sum(abs(x[i])).
178
+ + norm1: Returns the one-norm of matrix A, which is the maximum absolute column sum.
179
+ + norm2: Returns the two-norm (aka euclidean norm) of vector x; equivalent to Sqrt(mult(x,x)).
180
+ + norm2: Returns the two-norm of matrix A, which is the maximum singular value; obtained from SVD.
181
+ + normF: Returns the Frobenius norm of matrix A, which is Sqrt(Sum(A[i]2)).
182
+ + normF: Returns the Frobenius norm of matrix A, which is Sqrt(Sum(A[i,j]2)).
183
+ + normInfinity: Returns the infinity norm of vector x, which is Max(abs(x[i])).
184
+ + normInfinity: Returns the infinity norm of matrix A, which is the maximum absolute row sum.
185
+ + pow: Linear algebraic matrix power; B = Ak <==> B = A*A*...*A.
186
+ + qr: Constructs and returns the QR-decomposition of the given matrix.
187
+ + rank: Returns the effective numerical rank of matrix A, obtained from Singular Value Decomposition.
188
+ + solve: Solves A*x = b.
189
+ + solve: Solves A*X = B.
190
+ + solveTranspose: Solves X*A = B, which is also A'*X' = B'.
191
+ + svd: Constructs and returns the SingularValue-decomposition of the given matrix.
192
+ + trace: Returns the sum of the diagonal elements of matrix A; Sum(A[i,i]).
193
+ + trapezoidalLower: Modifies the matrix to be a lower trapezoidal matrix.
194
+ + vectorNorm2: Returns the two-norm (aka euclidean norm) of vector X.vectorize();
195
+ + xmultOuter: Outer product of two vectors; Returns a matrix with A[i,j] = x[i] * y[j].
196
+ + xpowSlow: Linear algebraic matrix power; B = Ak <==> B = A*A*...*A.
197
+
198
+ Properties´ methods tested on matrices:
199
+ =======================================
200
+
201
+ + density: Returns the matrix's fraction of non-zero cells; A.cardinality() / A.size().
202
+ + generate_non_singular!: Modifies the given square matrix A such that it is diagonally dominant by row and column, hence non-singular, hence invertible.
203
+ + diagonal?: A matrix A is diagonal if A[i,j] == 0 whenever i != j.
204
+ + diagonally_dominant_by_column?: A matrix A is diagonally dominant by column if the absolute value of each diagonal element is larger than the sum of the absolute values of the off-diagonal elements in the corresponding column.
205
+ + diagonally_dominant_by_row?: A matrix A is diagonally dominant by row if the absolute value of each diagonal element is larger than the sum of the absolute values of the off-diagonal elements in the corresponding row.
206
+ + identity?: A matrix A is an identity matrix if A[i,i] == 1 and all other cells are zero.
207
+ + lower_bidiagonal?: A matrix A is lower bidiagonal if A[i,j]==0 unless i==j || i==j+1.
208
+ + lower_triangular?: A matrix A is lower triangular if A[i,j]==0 whenever i < j.
209
+ + nonnegative?: A matrix A is non-negative if A[i,j] >= 0 holds for all cells.
210
+ + orthogonal?: A square matrix A is orthogonal if A*transpose(A) = I.
211
+ + positive?: A matrix A is positive if A[i,j] > 0 holds for all cells.
212
+ + singular?: A matrix A is singular if it has no inverse, that is, iff det(A)==0.
213
+ + skew_symmetric?: A square matrix A is skew-symmetric if A = -transpose(A), that is A[i,j] == -A[j,i].
214
+ + square?: A matrix A is square if it has the same number of rows and columns.
215
+ + strictly_lower_triangular?: A matrix A is strictly lower triangular if A[i,j]==0 whenever i <= j.
216
+ + strictly_triangular?: A matrix A is strictly triangular if it is triangular and its diagonal elements all equal 0.
217
+ + strictly_upper_triangular?: A matrix A is strictly upper triangular if A[i,j]==0 whenever i >= j.
218
+ + symmetric?: A matrix A is symmetric if A = tranpose(A), that is A[i,j] == A[j,i].
219
+ + triangular?: A matrix A is triangular iff it is either upper or lower triangular.
220
+ + tridiagonal?: A matrix A is tridiagonal if A[i,j]==0 whenever Math.abs(i-j) > 1.
221
+ + unit_triangular?: A matrix A is unit triangular if it is triangular and its diagonal elements all equal 1.
222
+ + upper_bidiagonal?: A matrix A is upper bidiagonal if A[i,j]==0 unless i==j || i==j-1.
223
+ + upper_triangular?: A matrix A is upper triangular if A[i,j]==0 whenever i > j.
224
+ + zero?: A matrix A is zero if all its cells are zero.
225
+ + lower_bandwidth: The lower bandwidth of a square matrix A is the maximum i-j for which A[i,j] is nonzero and i > j.
226
+ + semi_bandwidth: Returns the semi-bandwidth of the given square matrix A.
227
+ + upper_bandwidth: The upper bandwidth of a square matrix A is the maximum j-i for which A[i,j] is nonzero and j > i.
228
+
84
229
  Descriptive statistics methods imported from Parallel Colt:
85
230
  ===========================================================
86
231
 
@@ -132,6 +277,7 @@ Contributors are welcome.
132
277
  MDArray History:
133
278
  ================
134
279
 
280
+ + 14/11/2013: Version 0.5.5 - Support for linear algebra methods
135
281
  + 07/08/2013: Version 0.5.4 - Support for reading and writing NetCDF-3 files
136
282
  + 24/06/2013: Version 0.5.3 – Over 90% Performance improvements for methods imported
137
283
  from Parallel Colt and over 40% performance improvements for all other methods
@@ -142,203 +288,3 @@ MDArray History:
142
288
  + 17/04/2013: Version 0.4.2 - Adds simple statistics and boolean operators;
143
289
  + 05/04/2013: Version 0.4.0 – Initial release.
144
290
 
145
- NetCDF-3 Writing with MDArray API
146
- =================================
147
-
148
- require 'mdarray'
149
-
150
- class NetCDF
151
-
152
- attr_reader :dir, :filename, :max_strlen
153
-
154
- #---------------------------------------------------------------------------------------
155
- #
156
- #---------------------------------------------------------------------------------------
157
-
158
- def initialize
159
- @dir = "~/tmp"
160
- @filename1 = "testWriter"
161
- @filename2 = "testWriteRecord2"
162
- @max_strlen = 80
163
- end
164
-
165
- #---------------------------------------------------------------------------------------
166
- # Define the NetCDF-3 file
167
- #---------------------------------------------------------------------------------------
168
-
169
- def define_file
170
-
171
- # We pass the directory, filename, filetype and optionaly the outside_scope.
172
- #
173
- # I'm implementing in cygwin, so the need for method cygpath that converts the
174
- # directory name to a Windows name. In another environment, just pass the directory
175
- # name.
176
- #
177
- # Inside a block we have another scope, so the block cannot access any variables, etc.
178
- # from the ouside scope. If we pass the outside scope, in this case we are passing self,
179
- # we can access variables in the outside scope by using @outside_scope.<variable>.
180
- NetCDF.define(cygpath(@dir), @filename1, "netcdf3", self) do
181
-
182
- # add dimensions
183
- dimension "lat", 64
184
- dimension "lon", 128
185
-
186
- # add variables and attributes
187
- # add Variable double temperature(lat, lon)
188
- variable "temperature", "double", [@dim_lat, @dim_lon]
189
- variable_att @var_temperature, "units", "K"
190
- variable_att @var_temperature, "scale", [1, 2, 3]
191
-
192
- # add a string-value variable: char svar(80)
193
- # note that this is created as a scalar variable although in NetCDF-3 there is no
194
- # string type and the string has to be represented as a char type.
195
- variable "svar", "string", [], {:max_strlen => @outside_scope.max_strlen}
196
-
197
- # add a 2D string-valued variable: char names(names, 80)
198
- dimension "names", 3
199
- variable "names", "string", [@dim_names], {:max_strlen => @outside_scope.max_strlen}
200
-
201
- # add a scalar variable
202
- variable "scalar", "double", []
203
-
204
- # add global attributes
205
- global_att "yo", "face"
206
- global_att "versionD", 1.2, "double"
207
- global_att "versionF", 1.2, "float"
208
- global_att "versionI", 1, "int"
209
- global_att "versionS", 2, "short"
210
- global_att "versionB", 3, "byte"
211
-
212
- end
213
-
214
- end
215
-
216
- #---------------------------------------------------------------------------------------
217
- # write data on the above define file
218
- #---------------------------------------------------------------------------------------
219
-
220
- def write_file
221
-
222
- NetCDF.write(cygpath(@dir), @filename1, self) do
223
-
224
- temperature = find_variable("temperature")
225
- shape = temperature.shape
226
- data = MDArray.fromfunction("double", shape) do |i, j|
227
- i * 1_000_000 + j * 1_000
228
- end
229
- write(temperature, data)
230
-
231
- svar = find_variable("svar")
232
- write_string(svar, "Two pairs of ladies stockings!")
233
-
234
- names = find_variable("names")
235
- # careful here with the shape of a string variable. A string variable has one
236
- # more dimension than it should as there is no string type in NetCDF-3. As such,
237
- # if we look as names' shape it has 2 dimensions, be we need to create a one
238
- # dimension string array.
239
- data = MDArray.string([3], ["No pairs of ladies stockings!",
240
- "One pair of ladies stockings!",
241
- "Two pairs of ladies stockings!"])
242
- write_string(names, data)
243
-
244
- # write scalar data
245
- scalar = find_variable("scalar")
246
- write(scalar, 222.333 )
247
-
248
- end
249
-
250
- end
251
-
252
- #---------------------------------------------------------------------------------------
253
- # Define a file for writing one record at a time
254
- #---------------------------------------------------------------------------------------
255
-
256
- def define_one_at_time
257
-
258
- NetCDF.define(cygpath(@dir), @filename2, "netcdf3", self) do
259
-
260
- dimension "lat", 3
261
- dimension "lon", 4
262
- # zero sized dimension is an unlimited dimension
263
- dimension "time", 0
264
-
265
- variable "lat", "float", [@dim_lat]
266
- variable_att @var_lat, "units", "degree_north"
267
-
268
- variable "lon", "float", [@dim_lon]
269
- variable_att @var_lon, "units", "degree_east"
270
-
271
- variable "rh", "int", [@dim_time, @dim_lat, @dim_lon]
272
- variable_att @var_rh, "long_name", "relative humidity"
273
- variable_att @var_rh, "units", "percent"
274
-
275
- variable "T", "double", [@dim_time, @dim_lat, @dim_lon]
276
- variable_att @var_t, "long_name", "surface temperature"
277
- variable_att @var_t, "units", "degC"
278
-
279
- variable "time", "int", [@dim_time]
280
- variable_att @var_time, "units", "hours since 1990-01-01"
281
-
282
- end
283
-
284
- end
285
-
286
- #---------------------------------------------------------------------------------------
287
- # Define a file for writing one record at a time
288
- #---------------------------------------------------------------------------------------
289
-
290
- def write_one_at_time
291
-
292
- NetCDF.write(cygpath(@dir), @filename2, self) do
293
-
294
- lat = find_variable("lat")
295
- lon = find_variable("lon")
296
- write(lat, MDArray.float([3], [41, 40, 39]))
297
- write(lon, MDArray.float([4], [-109, -107, -105, -103]))
298
-
299
- # get variables from file
300
- rh = find_variable("rh")
301
- time = find_variable("time")
302
- t = find_variable("T")
303
-
304
- # there is no method find_dimension for NetcdfFileWriter, so we need to get the
305
- # dimension from a variable.
306
- rh_shape = rh.shape
307
- dim_lat = rh_shape[1]
308
- dim_lon = rh_shape[2]
309
-
310
- (0...10).each do |time_idx|
311
-
312
- # fill rh_data array
313
- rh_data = MDArray.fromfunction("int", [dim_lat, dim_lon]) do |lat, lon|
314
- time_idx * lat * lon
315
- end
316
- # reshape rh_data so that it has the same shape as rh variable
317
- # Method reshape! reshapes the array in-place without data copying.
318
- rh_data.reshape!([1, dim_lat, dim_lon])
319
-
320
- # fill temp_data array
321
- temp_data = MDArray.fromfunction("double", [dim_lat, dim_lon]) do |lat, lon|
322
- time_idx * lat * lon / 3.14159
323
- end
324
- # reshape temp_data array so that it has the same shape as temp variable.
325
- temp_data.reshape!([1, dim_lat, dim_lon])
326
-
327
- # write the variables
328
- write(time, MDArray.int([1], [time_idx * 12]), [time_idx])
329
- write(rh, rh_data, [time_idx, 0, 0])
330
- write(t, temp_data, [time_idx, 0, 0])
331
-
332
- end # End time_idx loop
333
-
334
- end
335
-
336
- end
337
-
338
- end
339
-
340
- netcdf = NetCDF.new
341
- netcdf.define_file
342
- netcdf.write_file
343
- netcdf.define_one_at_time
344
- netcdf.write_one_at_time