mdarray 0.5.4-java → 0.5.5-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -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