View Javadoc

1   /*
2   
3       dsh-matrix-io  Matrix readers and writers.
4       Copyright (c) 2008-2013 held jointly by the individual authors.
5   
6       This library is free software; you can redistribute it and/or modify it
7       under the terms of the GNU Lesser General Public License as published
8       by the Free Software Foundation; either version 3 of the License, or (at
9       your option) any later version.
10  
11      This library is distributed in the hope that it will be useful, but WITHOUT
12      ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
13      FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14      License for more details.
15  
16      You should have received a copy of the GNU Lesser General Public License
17      along with this library;  if not, write to the Free Software Foundation,
18      Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA.
19  
20      > http://www.fsf.org/licensing/licenses/lgpl.html
21      > http://www.opensource.org/licenses/lgpl-license.php
22  
23  */
24  package org.dishevelled.matrix.io.impl;
25  
26  import java.io.IOException;
27  
28  import org.dishevelled.functor.TernaryPredicate;
29  import org.dishevelled.functor.TernaryProcedure;
30  
31  import org.dishevelled.matrix.Matrix2D;
32  
33  /**
34   * Matrix Market format writer for matrices of numbers in two dimensions.
35   *
36   * @author  Michael Heuer
37   * @version $Revision$ $Date$
38   */
39  public final class MatrixMarketWriter
40      extends AbstractMatrix2DWriter<Number>
41  {
42      // TODO:
43      // matrix type (real, complex, integer, pattern) should be {specifiable, automatic}
44      // allow for specifying symmetry structure (general, symmetric, skew-symmetric, Hermitian)
45      // allow for specifying the number format to use when writing values
46  
47      /** Not null predicate. */
48      private static final TernaryPredicate<Long, Long, Object> NOT_NULL = new TernaryPredicate<Long, Long, Object>()
49          {
50              /** {@inheritDoc} */
51              public boolean test(final Long row, final Long column, final Object value)
52              {
53                  return (value != null);
54              }
55          };
56  
57  
58      /** {@inheritDoc} */
59      public <T extends Appendable> T append(final Matrix2D<? extends Number> matrix, final T appendable)
60          throws IOException
61      {
62          if (matrix == null)
63          {
64              throw new IllegalArgumentException("matrix must not be null");
65          }
66          if (appendable == null)
67          {
68              throw new IllegalArgumentException("appendable must not be null");
69          }
70          // append Matrix Market header
71          appendable.append("%%MatrixMarket matrix coordinate real general\n");
72          appendable.append("%\n% Note indices are 1-based.\n%\n");
73  
74          // append coordinate format dimensions
75          appendable.append(String.valueOf(matrix.rows()));
76          appendable.append("\t");
77          appendable.append(String.valueOf(matrix.columns()));
78          appendable.append("\t");
79          appendable.append(String.valueOf(matrix.cardinality()));
80          appendable.append("\n");
81  
82          // append non-null values
83          matrix.forEach(NOT_NULL, new TernaryProcedure<Long, Long, Object>()
84              {
85                  /** {@inheritDoc} */
86                  public void run(final Long row, final Long column, final Object value)
87                  {
88                      // note:  indices are 1-based
89                      try
90                      {
91                          appendable.append(String.valueOf(row + 1L));
92                          appendable.append("\t");
93                          appendable.append(String.valueOf(column + 1L));
94                          appendable.append("\t");
95                          appendable.append(MatrixIOUtils.toCharSequence(value));
96                          appendable.append("\n");
97                      }
98                      catch (IOException e)
99                      {
100                         // TODO:  have to eat this IOException, unfortunately
101                     }
102                 }
103             });
104 
105         return appendable;
106     }
107 }