carray 1.3.7 → 1.4.0

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 (78) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +0 -7
  3. data/Rakefile +31 -0
  4. data/carray.gemspec +9 -14
  5. data/carray.h +4 -0
  6. data/carray_access.c +50 -8
  7. data/carray_conversion.c +3 -3
  8. data/carray_generate.c +67 -1
  9. data/carray_math.rb +22 -22
  10. data/carray_operator.c +23 -0
  11. data/devel/im2col.rb +17 -0
  12. data/lib/carray.rb +32 -1
  13. data/lib/carray/autoload/autoload_base.rb +0 -4
  14. data/lib/carray/autoload/autoload_gem_cairo.rb +9 -0
  15. data/lib/carray/autoload/autoload_gem_ffi.rb +9 -0
  16. data/lib/carray/autoload/autoload_gem_gnuplot.rb +2 -0
  17. data/lib/carray/autoload/autoload_gem_io_csv.rb +14 -0
  18. data/lib/carray/autoload/autoload_gem_io_pg.rb +6 -0
  19. data/lib/carray/autoload/autoload_gem_io_sqlite3.rb +12 -0
  20. data/lib/carray/autoload/autoload_gem_narray.rb +10 -0
  21. data/lib/carray/autoload/autoload_gem_numo_narray.rb +14 -0
  22. data/lib/carray/autoload/autoload_gem_opencv.rb +16 -0
  23. data/lib/carray/autoload/autoload_gem_rmagick.rb +23 -0
  24. data/lib/carray/autoload/{autoload_graphics_zimg.rb → autoload_gem_zimg.rb} +0 -0
  25. data/lib/carray/base/autoload.rb +47 -5
  26. data/lib/carray/base/basic.rb +58 -2
  27. data/lib/carray/base/math.rb +1 -1
  28. data/lib/carray/base/string.rb +242 -0
  29. data/mkmath.rb +12 -2
  30. data/version.h +5 -5
  31. metadata +29 -109
  32. data/Gemfile +0 -8
  33. data/Gemfile.lock +0 -33
  34. data/ext/calculus/lib/autoload/autoload_math_calculus.rb +0 -2
  35. data/ext/fortio/extconf.rb +0 -3
  36. data/ext/fortio/lib/carray/autoload/autoload_fortran_format.rb +0 -5
  37. data/ext/fortio/lib/carray/io/fortran_format.rb +0 -43
  38. data/ext/fortio/lib/fortio.rb +0 -3
  39. data/ext/fortio/lib/fortio/fortran_format.rb +0 -605
  40. data/ext/fortio/lib/fortio/fortran_format.tab.rb +0 -536
  41. data/ext/fortio/lib/fortio/fortran_format.y +0 -215
  42. data/ext/fortio/lib/fortio/fortran_namelist.rb +0 -151
  43. data/ext/fortio/lib/fortio/fortran_namelist.tab.rb +0 -470
  44. data/ext/fortio/lib/fortio/fortran_namelist.y +0 -213
  45. data/ext/fortio/lib/fortio/fortran_sequential.rb +0 -345
  46. data/ext/fortio/ruby_fortio.c +0 -182
  47. data/ext/fortio/test/test_H.rb +0 -5
  48. data/ext/fortio/test/test_T.rb +0 -7
  49. data/ext/fortio/test/test_fortran_format.rb +0 -86
  50. data/ext/fortio/test/test_namelist.rb +0 -25
  51. data/ext/fortio/test/test_namelist_write.rb +0 -10
  52. data/ext/fortio/test/test_sequential.rb +0 -13
  53. data/ext/fortio/test/test_sequential2.rb +0 -13
  54. data/ext/fortio/work/test.rb +0 -10
  55. data/ext/fortio/work/test_e.rb +0 -19
  56. data/ext/fortio/work/test_ep.rb +0 -10
  57. data/ext/fortio/work/test_parse.rb +0 -12
  58. data/ext/mathfunc/lib/autoload/autoload_math_mathfunc.rb +0 -1
  59. data/ext/mathfunc/lib/math/mathfunc.rb +0 -15
  60. data/ext/narray/README +0 -22
  61. data/ext/narray/ca_wrap_narray.c +0 -500
  62. data/ext/narray/carray_narray.c +0 -21
  63. data/ext/narray/extconf.rb +0 -57
  64. data/ext/narray/lib/autoload/autoload_math_narray.rb +0 -1
  65. data/ext/narray/lib/autoload/autoload_math_narray_miss.rb +0 -11
  66. data/ext/narray/lib/math/narray.rb +0 -17
  67. data/ext/narray/lib/math/narray_miss.rb +0 -45
  68. data/lib/carray/autoload/autoload_graphics_gnuplot.rb +0 -2
  69. data/lib/carray/autoload/autoload_io_csv.rb +0 -14
  70. data/lib/carray/autoload/autoload_io_numo.rb +0 -9
  71. data/lib/carray/autoload/autoload_io_pg.rb +0 -6
  72. data/lib/carray/autoload/autoload_io_sqlite3.rb +0 -12
  73. data/lib/carray/graphics/gnuplot.rb +0 -2141
  74. data/lib/carray/graphics/zimg.rb +0 -296
  75. data/lib/carray/io/csv.rb +0 -572
  76. data/lib/carray/io/numo.rb +0 -52
  77. data/lib/carray/io/pg.rb +0 -101
  78. data/lib/carray/io/sqlite3.rb +0 -215
@@ -1,296 +0,0 @@
1
- # ----------------------------------------------------------------------------
2
- #
3
- # carray/graphics/zimg.rb
4
- #
5
- # This file is part of Ruby/CArray extension library.
6
- # You can redistribute it and/or modify it under the terms of
7
- # the Ruby Licence.
8
- #
9
- # Copyright (C) 2005 Hiroki Motoyoshi
10
- #
11
- # ----------------------------------------------------------------------------
12
-
13
-
14
- =begin
15
-
16
- option
17
-
18
- :debug => (true|false)
19
- :output => filename
20
- :complex => (abs|length|phase|real|imaginary)
21
- :colormap => (red|blue|gray) | "filename" | [r,g,b]
22
- :invert => (true|false)
23
- :crange => [min,max]
24
- :nda_color => color
25
- :scale => [x[,y]]
26
- :align => [h,[,v,bcol]]
27
- :quality => quality
28
- :interlace => (true|false)
29
- :colorbox => (true|false)
30
- :cbox_tics => n
31
- :cbox_label => string
32
- :cbox_format => string
33
- :display => (true|false) | "program"
34
- :legend => string
35
- :label => [[x1,y1,s1], [x2,y2,s2], ...]
36
- :vlabel => [[x1,y1,s1], [x2,y2,s2], ...]
37
- :textfont => n
38
- :textcolor => "xxx"|"xxxxxx"
39
- :smooth => threshold
40
- :contors => [levels,"log",bg,fg] ### Not Implemented
41
-
42
- =end
43
-
44
- class CArray
45
-
46
- @@zimg_count = 0
47
-
48
- def zimg (option={}) # :nodoc:
49
-
50
- tempfile = "%zimg_#{$$}_#{@@zimg_count}.dat"
51
- @@zimg_count += 1
52
-
53
- if self.rank != 2
54
- raise "zimg accept only 2-D data"
55
- end
56
-
57
- option.each do |k, v|
58
- if k.kind_of?(String)
59
- option[k.intern] = v
60
- end
61
- end
62
-
63
- if option[:output]
64
- output = option[:output]
65
- case output
66
- when /.ppm$/
67
- outfmt = "--ppm"
68
- when /.pgm$/
69
- outfmt = "--pgm"
70
- when /.jpg$/i, /.jpeg$/i
71
- if option[:quality]
72
- outfmt = "--jpeg=" + option[:quality].to_s
73
- else
74
- outfmt = "--jpeg"
75
- end
76
- else
77
- outfmt = ""
78
- end
79
- else
80
- output = "-"
81
- outfmt = ""
82
- end
83
-
84
- if option[:interlace]
85
- interlace = "--interlace"
86
- else
87
- interlace = ""
88
- end
89
-
90
- case self.data_type
91
- when CA_UINT8
92
- type_spec = "--unsigned-char"
93
- when CA_INT8, CA_BOOLEAN
94
- type_spec = "--char"
95
- when CA_UINT16
96
- type_spec = "--unsigned-short"
97
- when CA_INT16
98
- type_spec = "--short"
99
- when CA_UINT32
100
- type_spec = "--unsigned-int"
101
- when CA_INT32
102
- type_spec = "--int"
103
- when CA_FLOAT32
104
- type_spec = "--float"
105
- when CA_FLOAT64
106
- type_spec = "--double"
107
- when CA_CMPLX64
108
- type_spec = "--complex-float=" + ( option[:complex] || "abs" )
109
- when CA_CMPLX128
110
- type_spec = "--complex-double=" + ( option[:complex] || "abs" )
111
- else
112
- raise "can't create image for invalid numerical data"
113
- end
114
-
115
- case option[:colormap]
116
- when "red", "blue", "gray"
117
- colormap = "--" + option[:colormap]
118
- when String
119
- if File.exist?(option[:colormap])
120
- colormap = "--colormap=" + option[:colormap]
121
- else
122
- raise "can't find colomap file"
123
- end
124
- when Array
125
- colormap = "--colormap=" + option[:colormap].join(",")
126
- else
127
- colormap = ""
128
- end
129
-
130
- if option[:crange]
131
- crange = "--crange=" + option[:crange].join(',')
132
- else
133
- crange = ''
134
- end
135
-
136
- if option[:nda_color]
137
- if option[:fill_value]
138
- nda = "--nda=" + [option[:fill_value], option[:nda_color]].join(',')
139
- else
140
- nda = "--nda=" + ["Infinity", option[:nda_color]].join(',')
141
- end
142
- else
143
- nda = ""
144
- end
145
-
146
- if option[:scale]
147
- scale = "--scale=" + option[:scale].join(',')
148
- else
149
- scale = ''
150
- end
151
-
152
- if option[:align]
153
- if option[:align].last.kind_of?(String)
154
- align = "--align=" + option[:align][0..-2].join('x')
155
- "," + option[:align].last
156
- else
157
- align = "--align=" + option[:align].join('x')
158
- end
159
- else
160
- align = ''
161
- end
162
-
163
- if option[:colorbox]
164
- if option[:cbox_tics]
165
- colorbox = "--colorbox=" + option[:cbox_tics].to_s
166
- else
167
- colorbox = "--colorbox"
168
- end
169
- else
170
- colorbox = ""
171
- end
172
-
173
- if option[:cbox_format]
174
- cbox_format = option[:cbox_format]
175
- else
176
- cbox_format = ""
177
- end
178
-
179
- if option[:cbox_label]
180
- cbox_label = option[:cbox_label]
181
- else
182
- cbox_label = ""
183
- end
184
-
185
- geom = lambda{|x,y|
186
- [ (x > 0 ? "+" : '') + x.to_s, (y > 0 ? '+' :'') + y.to_s].join
187
- }
188
-
189
- label = ""
190
- if option[:label]
191
- option[:label].each do |x, y, s|
192
- label << "--label=" + [geom[x, y],s].join(',') + " "
193
- end
194
- end
195
-
196
- vlabel = ""
197
- if option[:vlabel]
198
- option[:vlabel].each do |x, y, s|
199
- vlabel << "--vlabel=" + [geom[x, y],s].join(',') + " "
200
- end
201
- end
202
-
203
- if option[:textfont]
204
- textfont = "--font=" + option[:textfont].to_s
205
- else
206
- textfont = ""
207
- end
208
-
209
- if option[:textcolor]
210
- textcolor = "--textcolor=" + option[:textcolor].to_s
211
- else
212
- textcolor = ""
213
- end
214
-
215
- case option[:smooth]
216
- when Numeric
217
- smooth = "--smooth=" + option[:smooth].to_s
218
- else
219
- if option[:smooth]
220
- smooth = "--smooth"
221
- else
222
- smooth = ""
223
- end
224
- end
225
-
226
- command = [
227
- "zimg",
228
- "--output=#{output}",
229
- outfmt,
230
- interlace,
231
- type_spec,
232
- "--size=" + self.dim.reverse.join(","),
233
- scale,
234
- align,
235
- colormap,
236
- option[:invert] ? "--invert" : "",
237
- crange,
238
- nda,
239
- colorbox,
240
- cbox_label,
241
- cbox_format,
242
- label,
243
- vlabel,
244
- textfont,
245
- textcolor,
246
- smooth,
247
- tempfile
248
- ].join(" ")
249
-
250
- if option[:nda_color] and self.has_mask?
251
- if option[:fill_value]
252
- out = self.unmask(option[:fill_value])
253
- else
254
- out = self.unmask(nan)
255
- end
256
- else
257
- out = self
258
- end
259
-
260
- open(tempfile, "w"){ |io|
261
- out.dump_binary(io)
262
- }
263
-
264
- if option[:debug]
265
- puts command
266
- end
267
-
268
- if option[:output]
269
- system(command)
270
- case option[:display]
271
- when String
272
- system([option[:display], output].join(" "))
273
- else
274
- if option[:display]
275
- system(["display", output].join(" "))
276
- end
277
- end
278
- else
279
- case option[:display]
280
- when String
281
- system(command + ["|", option[:display], "-"].join(" "))
282
- else
283
- if option[:display]
284
- system(command + ["|", "display -"].join(" "))
285
- end
286
- end
287
- end
288
-
289
- ensure
290
- if File.exist?(tempfile)
291
- File.unlink(tempfile)
292
- end
293
- end
294
-
295
- end
296
-
@@ -1,572 +0,0 @@
1
- # ----------------------------------------------------------------------------
2
- #
3
- # carray/io/csv.rb
4
- #
5
- # This file is part of Ruby/CArray extension library.
6
- # You can redistribute it and/or modify it under the terms of
7
- # the Ruby Licence.
8
- #
9
- # Copyright (C) 2005 Hiroki Motoyoshi
10
- #
11
- # ----------------------------------------------------------------------------
12
- #
13
- # CSV data reader/writer for CArray (in DSL approach)
14
- #
15
- # For reading (explicit form)
16
- #
17
- # csv = CA::CSVReader.new {
18
- # header # read a line as "names" header
19
- # header :units # read a line as "units" header
20
- # skip 1 # skip a line
21
- # body 10 # read values
22
- # process { |name, column| # post processing
23
- # case name # name : name of columns (string|integer)
24
- # when "Date" # column : column carray
25
- # column.map!{|x| Date.parse(x) }
26
- # else
27
- # column[] = column.double
28
- # end
29
- # }
30
- # }
31
- #
32
- # data1 = csv.read_file(file1)
33
- # data2 = csv.read_file(file2)
34
- # data3 = csv.read_file(file3)
35
- #
36
- # For reading (implicit form)
37
- #
38
- # data = CArray.load_csv(file) { ... definitions ... }
39
- # data = CArray.from_csv(io|string) { ... definitions ... }
40
- #
41
- # For writing (explict form)
42
- #
43
- # csv = CA::CSVWriter.new {
44
- # names ["Date", "a", "b", "c"] # set name of columns
45
- # process { |name, column| # pre processing
46
- # case name # name : name of column
47
- # when "Date" # column : column carray
48
- # column.map!{|x| x.to_s }
49
- # else
50
- # column.map!{|x| "%.2f" % x }
51
- # end
52
- # }
53
- # puts "sample CSV data" # print any string
54
- # header # write names in header
55
- # header ["","mm","cm","m"] # write units in header
56
- # write # write values
57
- # }
58
- #
59
- # data1.write_file(file1)
60
- # data2.write_file(file2)
61
- # data3.write_file(file3)
62
- #
63
- # For writing (implicit form)
64
- #
65
- # data.save_csv(file) { ... definitions ... }
66
- # data.to_csv([io|string]) { ... definitions ... }
67
- #
68
-
69
- require "stringio"
70
- require "strscan"
71
- require "carray/io/table"
72
-
73
- module CA
74
-
75
- class CSVReader # :nodoc:
76
-
77
- def initialize (sep=",", rs=$/, &block)
78
- @block = block
79
- @sep = sep
80
- @rs = rs
81
- end
82
-
83
- def read_io (io)
84
- return Processor.new(io, @sep, @rs, &@block).run
85
- end
86
-
87
- def read_string (string)
88
- return read_io(StringIO.new(string))
89
- end
90
-
91
- def read_file (filename)
92
- open(filename) { |io|
93
- return read_io(io)
94
- }
95
- end
96
-
97
- class Processor # :nodoc:
98
-
99
- def initialize (io, sep, rs=$/, &block)
100
- @io = io
101
- @sep = sep
102
- @rs = rs
103
- @sc = StringScanner.new("")
104
- @block = block || proc { body }
105
- @namelist = nil
106
- @names = nil
107
- @headerlist = []
108
- @header = {}
109
- @note = ""
110
- @table = nil
111
- @regexp_simple1 = /#{@sep}/
112
- @regexp_simple2 = / *#{@sep} */
113
- @regexp_pat1 = /\A([^"#{@sep}][^#{@sep}]*) *#{@sep} */
114
- @regexp_pat2 = /\A"([^"]+)" *#{@sep} */
115
- @regexp_pat3 = /\A"((?:[^"]+|"")+)" *#{@sep} */
116
- @regexp_pat4 = /\A(?:""|) *#{@sep} */
117
- end
118
-
119
- def run
120
- case @block.arity
121
- when 1
122
- @block.call(self)
123
- when -1, 0
124
- instance_exec(&@block)
125
- else
126
- raise "invalid block paramter"
127
- end
128
- header = @header
129
- note = @note
130
- @table.instance_exec{
131
- @names = header["names"]
132
- @header = header
133
- @note = note
134
- }
135
- @table.extend(CA::TableMethods)
136
- @table.column_names = header["names"]
137
- class << @table
138
- attr_reader :note
139
- def header (name=nil)
140
- if name
141
- return @header[name.to_s]
142
- else
143
- return @header
144
- end
145
- end
146
- end
147
- return @table
148
- end
149
-
150
- def column_names (*namelist)
151
- if @header.has_key?("names")
152
- warn "override header['names']"
153
- end
154
- @names = namelist.map(&:to_s)
155
- @header["names"] = @names
156
- return namelist
157
- end
158
-
159
- def header (name = "names")
160
- name = name.to_s
161
- list = csv_feed()
162
- if name == "names"
163
- if @names
164
- raise "already 'names' defined"
165
- end
166
- @names = list
167
- end
168
- @header[name] = list
169
- @headerlist.push(name)
170
- return list
171
- end
172
-
173
- attr_reader :names
174
-
175
- def note (n=1)
176
- list = []
177
- n.times { list << @io.gets(@rs) }
178
- @note << (text = list.join)
179
- return text
180
- end
181
-
182
- def skip (n=1)
183
- n.times { @io.gets(@rs) }
184
- end
185
-
186
- def body (n=nil, cols=nil)
187
- unless n
188
- n = 0x80000000
189
- end
190
- data = []
191
- count = 0
192
-
193
- if cols
194
- @cols = cols
195
- elsif @names
196
- @cols = @names.size
197
- else
198
- list = csv_feed()
199
- if list.nil?
200
- @rows = 0
201
- @table = CArray.object(@rows, @cols)
202
- return
203
- end
204
- data.push(list)
205
- count += 1
206
- @cols = list.size
207
- end
208
-
209
- lsize = nil
210
- while count < n and list = csv_feed(@cols)
211
- lsize = list.size
212
- if lsize == @cols
213
- data.push(list)
214
- elsif lsize <= @cols
215
- record = Array.new(@cols, nil)
216
- record[0,lsize] = list
217
- data.push(record)
218
- else
219
- extra = Array.new(lsize - @cols, nil)
220
- data.each do |row|
221
- row.push(*extra)
222
- end
223
- data.push(list)
224
- @cols = lsize
225
- # raise "csv parse error : too large column number at line #{@io.lineno}"
226
- end
227
- count += 1
228
- end
229
-
230
- @rows = data.size
231
- @table = CArray.object(@rows, @cols){ data }
232
- @table[:eq,""] = nil
233
- end
234
-
235
- def select (*namelist)
236
- @namelist = namelist.empty? ? nil : namelist
237
- case @namelist
238
- when nil
239
- when Array
240
- index = (0...@cols).map.to_a
241
- index_list = @namelist.map{ |x|
242
- case x
243
- when Integer
244
- x
245
- when Range
246
- index[x]
247
- when String, Symbol
248
- if @names and i = @names.index(x.to_s)
249
- i
250
- else
251
- raise "invalid argument #{x}"
252
- end
253
- else
254
- raise "invalid argument"
255
- end
256
- }.flatten
257
- @table = @table[nil, CA_INT(index_list)].to_ca
258
- @header.keys.each do |k|
259
- @header[k] = @header[k].values_at(*index_list)
260
- end
261
- else
262
- raise
263
- end
264
- end
265
-
266
- def process
267
- if @namelist
268
- @namelist.each_with_index do |name, i|
269
- yield(name, @table[nil, i])
270
- end
271
- elsif @names
272
- @names.each_with_index do |name, i|
273
- yield(name, @table[nil, i])
274
- end
275
- else
276
- @table.dim1.times do |i|
277
- yield(i, @table[nil,i])
278
- end
279
- end
280
- end
281
-
282
- def convert (data_type, options={}, &block)
283
- if block_given?
284
- if data_type.is_a?(Class) and data_type < CA::Struct
285
- @table = @table[:i, nil].convert(data_type, &block)
286
- else
287
- @table = @table.convert(data_type, options, &block)
288
- end
289
- else
290
- if data_type.is_a?(Class) and data_type < CA::Struct
291
- @table = @table[:i,nil].convert(data_type) { |b|
292
- data_type.new(*b[0,nil])
293
- }
294
- else
295
- @table = @table.to_type(data_type, options)
296
- end
297
- end
298
- end
299
-
300
- private
301
-
302
- def csv_feed (cols=nil)
303
- if @io.eof?
304
- return nil
305
- end
306
- line = nil
307
- loop do
308
- if newline = @io.gets(@rs)
309
- if line
310
- line << newline
311
- else
312
- line = newline
313
- end
314
- count_quote = line.count('"')
315
- else
316
- line = ""
317
- count_quote = 0
318
- end
319
- if count_quote == 0
320
- line.chomp!
321
- if line.count(' ') == 0
322
- return line.split(@sep, -1) ### /#{@sep}/
323
- else
324
- return line.split(@regexp_simple2, -1) ### / *#{@sep} */
325
- end
326
- end
327
- if count_quote % 2 == 0
328
- line.chomp!
329
- return csv_split(line, cols)
330
- else
331
- if newline
332
- next
333
- else
334
- raise "csv parse error"
335
- end
336
- end
337
- end
338
- end
339
-
340
- def csv_split (text, cols=nil)
341
- if cols
342
- csv = Array.new(cols)
343
- else
344
- csv = []
345
- end
346
- text << @sep
347
- @sc.string = text
348
- i = 0
349
- begin
350
- case
351
- when @sc.scan(@regexp_pat1)
352
- ### /\A([^"#{@sep}][^#{@sep}]*) *#{@sep} */
353
- csv[i] = @sc[1]
354
- when @sc.scan(@regexp_pat2)
355
- ### /\A"([^"]+)" *#{@sep} */
356
- csv[i] = @sc[1]
357
- when @sc.scan(@regexp_pat3)
358
- ### /\A"((?:[^"]+|"")+)" *#{@sep} */
359
- s = @sc[1]
360
- if s =~ /"/
361
- csv[i] = s.gsub(/""/, '"')
362
- else
363
- csv[i] = s
364
- end
365
- when @sc.scan(@regexp_pat4)
366
- ### /\A(?:""|) *#{@sep} */
367
- csv[i] = nil
368
- else
369
- raise "csv parse error"
370
- end
371
- i += 1
372
- end until @sc.eos?
373
- return csv
374
- end
375
-
376
- end
377
- end
378
- end
379
-
380
- module CA
381
-
382
- class CSVWriter # :nodoc:
383
-
384
- def initialize (sep=",", rs=$/, fill="", &block)
385
- @block = block
386
- @sep = sep
387
- @rs = rs
388
- @fill = fill
389
- end
390
-
391
- def write_io (table, io)
392
- return Processor.new(table, io, @sep, @rs, @fill, &@block).run
393
- end
394
-
395
- def write_string (table, string)
396
- write_io(table, StringIO.new(string))
397
- return string
398
- end
399
-
400
- def write_file (table, filename, mode="w")
401
- open(filename, mode) { |io|
402
- return write_io(table, io)
403
- }
404
- end
405
-
406
- class Processor # :nodoc:
407
-
408
- def initialize (table, io, sep, rs, fill, &block)
409
- @io = io
410
- @sep = sep
411
- @rs = rs
412
- @fill = fill
413
- @block = block || proc { body }
414
- if table.has_data_class?
415
- @names = table.members
416
- @table = CArray.merge(CA_OBJECT, table[nil].fields)
417
- else
418
- @names = table.instance_exec{ @names }
419
- if @names.nil?
420
- @names = table.instance_exec{ @column_names }
421
- end
422
- case
423
- when table.rank > 2
424
- @table = table.reshape(false,nil).object
425
- when table.rank == 1
426
- @table = table[:%,1].object ### convert to CA_OBJECT
427
- else
428
- @table = table.object ### convert to CA_OBJECT
429
- end
430
- end
431
- if @table.has_mask?
432
- @table.unmask(@fill)
433
- end
434
- @regexp_simple = /#{@sep}/o
435
- end
436
-
437
- def csv_quote (text)
438
- text = text.dup
439
- if text.gsub!(/"/, '""') or text =~ @regexp_simple ### /#{@sep}|"/
440
- text = '"' + text + '"'
441
- end
442
- return text
443
- end
444
-
445
- def run
446
- case @block.arity
447
- when 1
448
- @block.call(self)
449
- when -1, 0
450
- instance_exec(&@block)
451
- else
452
- raise "invalid block parameter"
453
- end
454
- end
455
-
456
- # set @names
457
- def names (list)
458
- @names = list
459
- end
460
-
461
- # puts header
462
- def header (list = @names)
463
- @io.write list.map{|s| csv_quote(s)}.join(@sep)
464
- @io.write(@rs)
465
- end
466
-
467
- # puts any strings
468
- def puts (*argv)
469
- @io.print(*argv)
470
- @io.write(@rs)
471
- end
472
-
473
- # write value
474
- # If option :strict is set, do csv_quote for string element
475
- def body (strict: true, format: nil)
476
- if strict
477
- case @table.data_type
478
- when CA_OBJECT
479
- table = @table.to_ca
480
- table[:is_kind_of, String].map! { |s| csv_quote(s) }
481
- when CA_FIXLEN
482
- table = @table.object
483
- table.map! { |s| csv_quote(s) }
484
- else
485
- table = @table.object
486
- end
487
- else
488
- table = @table
489
- end
490
- if format
491
- table.dim0.times do |i|
492
- @io.write Kernel::format(format,*table[i,nil].to_a)
493
- @io.write(@rs)
494
- end
495
- else
496
- table.dim0.times do |i|
497
- @io.write table[i,nil].to_a.join(@sep)
498
- @io.write(@rs)
499
- end
500
- end
501
- end
502
-
503
- # pre processing data
504
- def process (namelist = @names)
505
- if namelist
506
- namelist.each_with_index do |name, i|
507
- yield(name, @table[nil, i])
508
- end
509
- else
510
- @table.dim1.times do |i|
511
- yield(i, @table[nil,i])
512
- end
513
- end
514
- end
515
- end
516
- end
517
- end
518
-
519
- class CArray
520
-
521
- def self.load_csv (file, option={}, rs: $/, sep: ",", &block)
522
- option = {:sep=>sep, :rs=>rs}.update(option)
523
- reader = CA::CSVReader.new(option[:sep], option[:rs], &block)
524
- return reader.read_file(file)
525
- end
526
-
527
- def self.from_csv (io, option={}, rs: $/, sep: ",", &block)
528
- option = {:sep=>sep, :rs=>rs}.update(option)
529
- reader = CA::CSVReader.new(option[:sep], option[:rs], &block)
530
- case io
531
- when IO, StringIO
532
- return reader.read_io(io)
533
- when String
534
- return reader.read_string(io)
535
- else
536
- raise "invalid argument"
537
- end
538
- end
539
-
540
- def save_csv (file, option = {}, rs: $/, sep: ",", fill: "", mode: "w", &block)
541
- option = {:sep=>sep, :rs=>rs, :fill=>fill, :mode=>mode}.update(option)
542
- writer = CA::CSVWriter.new(option[:sep], option[:rs], option[:fill], &block)
543
- return writer.write_file(self, file, option[:mode])
544
- end
545
-
546
- def to_csv (io="", option ={}, rs: $/, sep: ",", fill: "", &block)
547
- option = {:sep=>sep, :rs=>rs, :fill=>fill}.update(option)
548
- writer = CA::CSVWriter.new(option[:sep], option[:rs], option[:fill], &block)
549
- case io
550
- when IO, StringIO
551
- return writer.write_io(self, io)
552
- when String
553
- return writer.write_string(self, io)
554
- end
555
- end
556
-
557
- def to_tabular (option = {})
558
- option = {:sep=>" ", :names=>nil}.update(option)
559
- if option[:names]
560
- names = option[:names]
561
- elsif self.respond_to?(:names)
562
- names = self.names
563
- end
564
- sep = option[:sep]
565
- data = self.to_ca.map! {|s| s.to_s }
566
- table = CArray.join([names.to_ca], [data])
567
- length = table.convert{|s| s.length}.max(0)
568
- table.map_with_index! {|s, idx| s.rjust(length[idx[1]]) }.to_csv.gsub(/,/,sep)
569
- end
570
-
571
- end
572
-