001/* ***** BEGIN LICENSE BLOCK *****
002 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
003 *
004 * The contents of this file are subject to the Mozilla Public License Version
005 * 1.1 (the "License"); you may not use this file except in compliance with
006 * the License. You may obtain a copy of the License at
007 * http://www.mozilla.org/MPL/
008 *
009 * Software distributed under the License is distributed on an "AS IS" basis,
010 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
011 * for the specific language governing rights and limitations under the
012 * License.
013 *
014 * The Original Code is Parallel Colt.
015 *
016 * The Initial Developer of the Original Code is
017 * Piotr Wendykier, Emory University.
018 * Portions created by the Initial Developer are Copyright (C) 2007-2009
019 * the Initial Developer. All Rights Reserved.
020 *
021 * Alternatively, the contents of this file may be used under the terms of
022 * either the GNU General Public License Version 2 or later (the "GPL"), or
023 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
024 * in which case the provisions of the GPL or the LGPL are applicable instead
025 * of those above. If you wish to allow use of your version of this file only
026 * under the terms of either the GPL or the LGPL, and not to allow others to
027 * use your version of this file under the terms of the MPL, indicate your
028 * decision by deleting the provisions above and replace them with the notice
029 * and other provisions required by the GPL or the LGPL. If you do not delete
030 * the provisions above, a recipient may use your version of this file under
031 * the terms of any one of the MPL, the GPL or the LGPL.
032 *
033 * ***** END LICENSE BLOCK ***** */
034package edu.emory.mathcs.utils;
035
036import java.io.BufferedWriter;
037import java.io.FileWriter;
038import java.io.IOException;
039import java.util.Date;
040import java.util.Random;
041
042/**
043 * I/O utilities.
044 * 
045 * @author Piotr Wendykier (piotr.wendykier@gmail.com)
046 */
047public class IOUtils {
048
049    private static final String FF = "%.4f";
050
051    private IOUtils() {
052
053    }
054
055    /**
056     * Fills 1D matrix with random numbers.
057     * 
058     * @param N
059     *            size
060     * @param m
061     *            1D matrix
062     */
063    public static void fillMatrix_1D(int N, double[] m) {
064        Random r = new Random(2);
065        for (int i = 0; i < N; i++) {
066            m[i] = r.nextDouble();
067        }
068    }
069
070    /**
071     * Fills 1D matrix with random numbers.
072     * 
073     * @param N
074     *            size
075     * @param m
076     *            1D matrix
077     */
078    public static void fillMatrix_1D(int N, float[] m) {
079        Random r = new Random(2);
080        for (int i = 0; i < N; i++) {
081            m[i] = r.nextFloat();
082        }
083    }
084
085    /**
086     * Fills 2D matrix with random numbers.
087     * 
088     * @param n1
089     *            rows
090     * @param n2
091     *            columns
092     * @param m
093     *            2D matrix
094     */
095    public static void fillMatrix_2D(int n1, int n2, double[] m) {
096        Random r = new Random(2);
097        for (int i = 0; i < n1; i++) {
098            for (int j = 0; j < n2; j++) {
099                m[i * n2 + j] = r.nextDouble();
100            }
101        }
102    }
103
104    /**
105     * Fills 2D matrix with random numbers.
106     * 
107     * @param n1
108     *            rows
109     * @param n2
110     *            columns
111     * @param m
112     *            2D matrix
113     */
114    public static void fillMatrix_2D(int n1, int n2, float[] m) {
115        Random r = new Random(2);
116        for (int i = 0; i < n1; i++) {
117            for (int j = 0; j < n2; j++) {
118                m[i * n2 + j] = r.nextFloat();
119            }
120        }
121    }
122
123    /**
124     * Fills 2D matrix with random numbers.
125     * 
126     * @param n1
127     *            rows
128     * @param n2
129     *            columns
130     * @param m
131     *            2D matrix
132     */
133    public static void fillMatrix_2D(int n1, int n2, double[][] m) {
134        Random r = new Random(2);
135        for (int i = 0; i < n1; i++) {
136            for (int j = 0; j < n2; j++) {
137                m[i][j] = r.nextDouble();
138            }
139        }
140    }
141
142    /**
143     * Fills 2D matrix with random numbers.
144     * 
145     * @param n1
146     *            rows
147     * @param n2
148     *            columns
149     * @param m
150     *            2D matrix
151     */
152    public static void fillMatrix_2D(int n1, int n2, float[][] m) {
153        Random r = new Random(2);
154        for (int i = 0; i < n1; i++) {
155            for (int j = 0; j < n2; j++) {
156                m[i][j] = r.nextFloat();
157            }
158        }
159    }
160
161    /**
162     * Fills 3D matrix with random numbers.
163     * 
164     * @param n1
165     *            slices
166     * @param n2
167     *            rows
168     * @param n3
169     *            columns
170     * @param m
171     *            3D matrix
172     */
173    public static void fillMatrix_3D(int n1, int n2, int n3, double[] m) {
174        Random r = new Random(2);
175        int sliceStride = n2 * n3;
176        int rowStride = n3;
177        for (int i = 0; i < n1; i++) {
178            for (int j = 0; j < n2; j++) {
179                for (int k = 0; k < n3; k++) {
180                    m[i * sliceStride + j * rowStride + k] = r.nextDouble();
181                }
182            }
183        }
184    }
185
186    /**
187     * Fills 3D matrix with random numbers.
188     * 
189     * @param n1
190     *            slices
191     * @param n2
192     *            rows
193     * @param n3
194     *            columns
195     * @param m
196     *            3D matrix
197     */
198    public static void fillMatrix_3D(int n1, int n2, int n3, float[] m) {
199        Random r = new Random(2);
200        int sliceStride = n2 * n3;
201        int rowStride = n3;
202        for (int i = 0; i < n1; i++) {
203            for (int j = 0; j < n2; j++) {
204                for (int k = 0; k < n3; k++) {
205                    m[i * sliceStride + j * rowStride + k] = r.nextFloat();
206                }
207            }
208        }
209    }
210
211    /**
212     * Fills 3D matrix with random numbers.
213     * 
214     * @param n1
215     *            slices
216     * @param n2
217     *            rows
218     * @param n3
219     *            columns
220     * @param m
221     *            3D matrix
222     */
223    public static void fillMatrix_3D(int n1, int n2, int n3, double[][][] m) {
224        Random r = new Random(2);
225        for (int i = 0; i < n1; i++) {
226            for (int j = 0; j < n2; j++) {
227                for (int k = 0; k < n3; k++) {
228                    m[i][j][k] = r.nextDouble();
229                }
230            }
231        }
232    }
233
234    /**
235     * Fills 3D matrix with random numbers.
236     * 
237     * @param n1
238     *            slices
239     * @param n2
240     *            rows
241     * @param n3
242     *            columns
243     * @param m
244     *            3D matrix
245     */
246    public static void fillMatrix_3D(int n1, int n2, int n3, float[][][] m) {
247        Random r = new Random(2);
248        for (int i = 0; i < n1; i++) {
249            for (int j = 0; j < n2; j++) {
250                for (int k = 0; k < n3; k++) {
251                    m[i][j][k] = r.nextFloat();
252                }
253            }
254        }
255    }
256
257    /**
258     * Displays elements of <code>x</code>, assuming that it is 1D complex
259     * array. Complex data is represented by 2 double values in sequence: the
260     * real and imaginary parts.
261     * 
262     * @param x
263     * @param title
264     */
265    public static void showComplex_1D(double[] x, String title) {
266        System.out.println(title);
267        System.out.println("-------------------");
268        for (int i = 0; i < x.length; i = i + 2) {
269            if (x[i + 1] == 0) {
270                System.out.println(String.format(FF, x[i]));
271                continue;
272            }
273            if (x[i] == 0) {
274                System.out.println(String.format(FF, x[i + 1]) + "i");
275                continue;
276            }
277            if (x[i + 1] < 0) {
278                System.out.println(String.format(FF, x[i]) + " - " + (String.format(FF, -x[i + 1])) + "i");
279                continue;
280            }
281            System.out.println(String.format(FF, x[i]) + " + " + (String.format(FF, x[i + 1])) + "i");
282        }
283        System.out.println();
284    }
285
286    /**
287     * Displays elements of <code>x</code>, assuming that it is 2D complex
288     * array. Complex data is represented by 2 double values in sequence: the
289     * real and imaginary parts.
290     * 
291     * @param rows
292     * @param columns
293     * @param x
294     * @param title
295     */
296    public static void showComplex_2D(int rows, int columns, double[] x, String title) {
297        StringBuffer s = new StringBuffer(String.format(title + ": complex array 2D: %d rows, %d columns\n\n", rows, columns));
298        for (int r = 0; r < rows; r++) {
299            for (int c = 0; c < 2 * columns; c = c + 2) {
300                if (x[r * 2 * columns + c + 1] == 0) {
301                    s.append(String.format(FF + "\t", x[r * 2 * columns + c]));
302                    continue;
303                }
304                if (x[r * 2 * columns + c] == 0) {
305                    s.append(String.format(FF + "i\t", x[r * 2 * columns + c + 1]));
306                    continue;
307                }
308                if (x[r * 2 * columns + c + 1] < 0) {
309                    s.append(String.format(FF + " - " + FF + "i\t", x[r * 2 * columns + c], -x[r * 2 * columns + c + 1]));
310                    continue;
311                }
312                s.append(String.format(FF + " + " + FF + "i\t", x[r * 2 * columns + c], x[r * 2 * columns + c + 1]));
313            }
314            s.append("\n");
315        }
316        System.out.println(s.toString());
317    }
318
319    /**
320     * Displays elements of <code>x</code>, assuming that it is 3D complex
321     * array. Complex data is represented by 2 double values in sequence: the
322     * real and imaginary parts.
323     * 
324     * @param n1
325     * @param n2
326     * @param n3
327     * @param x
328     * @param title
329     */
330    public static void showComplex_3D(int n1, int n2, int n3, double[] x, String title) {
331        int sliceStride = n2 * 2 * n3;
332        int rowStride = 2 * n3;
333
334        System.out.println(title);
335        System.out.println("-------------------");
336
337        for (int k = 0; k < 2 * n3; k = k + 2) {
338            System.out.println("(:,:," + k / 2 + ")=\n");
339            for (int i = 0; i < n1; i++) {
340                for (int j = 0; j < n2; j++) {
341                    if (x[i * sliceStride + j * rowStride + k + 1] == 0) {
342                        System.out.print(String.format(FF, x[i * sliceStride + j * rowStride + k]) + "\t");
343                        continue;
344                    }
345                    if (x[i * sliceStride + j * rowStride + k] == 0) {
346                        System.out.print(String.format(FF, x[i * sliceStride + j * rowStride + k + 1]) + "i\t");
347                        continue;
348                    }
349                    if (x[i * sliceStride + j * rowStride + k + 1] < 0) {
350                        System.out.print(String.format(FF, x[i * sliceStride + j * rowStride + k]) + " - " + String.format(FF, -x[i * sliceStride + j * rowStride + k + 1]) + "i\t");
351                        continue;
352                    }
353                    System.out.print(String.format(FF, x[i * sliceStride + j * rowStride + k]) + " + " + String.format(FF, x[i * sliceStride + j * rowStride + k + 1]) + "i\t");
354                }
355                System.out.println("");
356            }
357        }
358        System.out.println("");
359    }
360
361    /**
362     * Displays elements of <code>x</code>. Complex data is represented by 2
363     * double values in sequence: the real and imaginary parts.
364     * 
365     * @param n1
366     * @param n2
367     * @param n3
368     * @param x
369     * @param title
370     */
371    public static void showComplex_3D(int n1, int n2, int n3, double[][][] x, String title) {
372        System.out.println(title);
373        System.out.println("-------------------");
374
375        for (int k = 0; k < 2 * n3; k = k + 2) {
376            System.out.println("(:,:," + k / 2 + ")=\n");
377            for (int i = 0; i < n1; i++) {
378                for (int j = 0; j < n2; j++) {
379                    if (x[i][j][k + 1] == 0) {
380                        System.out.print(String.format(FF, x[i][j][k]) + "\t");
381                        continue;
382                    }
383                    if (x[i][j][k] == 0) {
384                        System.out.print(String.format(FF, x[i][j][k + 1]) + "i\t");
385                        continue;
386                    }
387                    if (x[i][j][k + 1] < 0) {
388                        System.out.print(String.format(FF, x[i][j][k]) + " - " + String.format(FF, -x[i][j][k + 1]) + "i\t");
389                        continue;
390                    }
391                    System.out.print(String.format(FF, x[i][j][k]) + " + " + String.format(FF, x[i][j][k + 1]) + "i\t");
392                }
393                System.out.println("");
394            }
395        }
396        System.out.println("");
397    }
398
399    /**
400     * Displays elements of <code>x</code>, assuming that it is 3D complex
401     * array. Complex data is represented by 2 double values in sequence: the
402     * real and imaginary parts.
403     * 
404     * @param n1
405     * @param n2
406     * @param n3
407     * @param x
408     * @param title
409     */
410    public static void showComplex_3D(int n1, int n2, int n3, float[] x, String title) {
411        int sliceStride = n2 * 2 * n3;
412        int rowStride = 2 * n3;
413
414        System.out.println(title);
415        System.out.println("-------------------");
416
417        for (int k = 0; k < 2 * n3; k = k + 2) {
418            System.out.println("(:,:," + k / 2 + ")=\n");
419            for (int i = 0; i < n1; i++) {
420                for (int j = 0; j < n2; j++) {
421                    if (x[i * sliceStride + j * rowStride + k + 1] == 0) {
422                        System.out.print(String.format(FF, x[i * sliceStride + j * rowStride + k]) + "\t");
423                        continue;
424                    }
425                    if (x[i * sliceStride + j * rowStride + k] == 0) {
426                        System.out.print(String.format(FF, x[i * sliceStride + j * rowStride + k + 1]) + "i\t");
427                        continue;
428                    }
429                    if (x[i * sliceStride + j * rowStride + k + 1] < 0) {
430                        System.out.print(String.format(FF, x[i * sliceStride + j * rowStride + k]) + " - " + String.format(FF, -x[i * sliceStride + j * rowStride + k + 1]) + "i\t");
431                        continue;
432                    }
433                    System.out.print(String.format(FF, x[i * sliceStride + j * rowStride + k]) + " + " + String.format(FF, x[i * sliceStride + j * rowStride + k + 1]) + "i\t");
434                }
435                System.out.println("");
436            }
437        }
438        System.out.println("");
439    }
440
441    /**
442     * Displays elements of <code>x</code>, assuming that it is 1D real array.
443     * 
444     * @param x
445     * @param title
446     */
447    public static void showReal_1D(double[] x, String title) {
448        System.out.println(title);
449        System.out.println("-------------------");
450        for (int j = 0; j < x.length; j++) {
451            System.out.println(String.format(FF, x[j]));
452        }
453        System.out.println();
454    }
455
456    /**
457     * Displays elements of <code>x</code>, assuming that it is 2D real array.
458     * 
459     * @param n1
460     * @param n2
461     * @param x
462     * @param title
463     */
464    public static void showReal_2D(int n1, int n2, double[] x, String title) {
465        System.out.println(title);
466        System.out.println("-------------------");
467        for (int i = 0; i < n1; i++) {
468            for (int j = 0; j < n2; j++) {
469                if (Math.abs(x[i * n2 + j]) < 5e-5) {
470                    System.out.print("0\t");
471                } else {
472                    System.out.print(String.format(FF, x[i * n2 + j]) + "\t");
473                }
474            }
475            System.out.println();
476        }
477        System.out.println();
478    }
479
480    /**
481     * Displays elements of <code>x</code>, assuming that it is 3D real array.
482     * 
483     * @param n1
484     * @param n2
485     * @param n3
486     * @param x
487     * @param title
488     */
489    public static void showReal_3D(int n1, int n2, int n3, double[] x, String title) {
490        int sliceStride = n2 * n3;
491        int rowStride = n3;
492
493        System.out.println(title);
494        System.out.println("-------------------");
495
496        for (int k = 0; k < n3; k++) {
497            System.out.println();
498            System.out.println("(:,:," + k + ")=\n");
499            for (int i = 0; i < n1; i++) {
500                for (int j = 0; j < n2; j++) {
501                    if (Math.abs(x[i * sliceStride + j * rowStride + k]) <= 5e-5) {
502                        System.out.print("0\t");
503                    } else {
504                        System.out.print(String.format(FF, x[i * sliceStride + j * rowStride + k]) + "\t");
505                    }
506                }
507                System.out.println();
508            }
509        }
510        System.out.println();
511    }
512
513    /**
514     * Displays elements of <code>x</code>.
515     * 
516     * @param n1
517     * @param n2
518     * @param n3
519     * @param x
520     * @param title
521     */
522    public static void showReal_3D(int n1, int n2, int n3, double[][][] x, String title) {
523
524        System.out.println(title);
525        System.out.println("-------------------");
526
527        for (int k = 0; k < n3; k++) {
528            System.out.println();
529            System.out.println("(:,:," + k + ")=\n");
530            for (int i = 0; i < n1; i++) {
531                for (int j = 0; j < n2; j++) {
532                    if (Math.abs(x[i][j][k]) <= 5e-5) {
533                        System.out.print("0\t");
534                    } else {
535                        System.out.print(String.format(FF, x[i][j][k]) + "\t");
536                    }
537                }
538                System.out.println();
539            }
540        }
541        System.out.println();
542    }
543
544    /**
545     * Saves elements of <code>x</code> in a file <code>filename</code>,
546     * assuming that it is 1D complex array. Complex data is represented by 2
547     * double values in sequence: the real and imaginary parts.
548     * 
549     * @param x
550     * @param filename
551     */
552    public static void writeToFileComplex_1D(double[] x, String filename) {
553        try {
554            BufferedWriter out = new BufferedWriter(new FileWriter(filename));
555            for (int i = 0; i < x.length; i = i + 2) {
556                if (x[i + 1] == 0) {
557                    out.write(String.format(FF, x[i]));
558                    out.newLine();
559                    continue;
560                }
561                if (x[i] == 0) {
562                    out.write(String.format(FF, x[i + 1]) + "i");
563                    out.newLine();
564                    continue;
565                }
566                if (x[i + 1] < 0) {
567                    out.write(String.format(FF, x[i]) + " - " + String.format(FF, -x[i + 1]) + "i");
568                    out.newLine();
569                    continue;
570                }
571                out.write(String.format(FF, x[i]) + " + " + String.format(FF, x[i + 1]) + "i");
572                out.newLine();
573            }
574            out.newLine();
575            out.close();
576        } catch (IOException e) {
577            e.printStackTrace();
578        }
579    }
580
581    /**
582     * Saves elements of <code>x</code> in a file <code>filename</code>,
583     * assuming that it is 1D complex array. Complex data is represented by 2
584     * double values in sequence: the real and imaginary parts.
585     * 
586     * @param x
587     * @param filename
588     */
589    public static void writeToFileComplex_1D(float[] x, String filename) {
590        try {
591            BufferedWriter out = new BufferedWriter(new FileWriter(filename));
592            for (int i = 0; i < x.length; i = i + 2) {
593                if (x[i + 1] == 0) {
594                    out.write(String.format(FF, x[i]));
595                    out.newLine();
596                    continue;
597                }
598                if (x[i] == 0) {
599                    out.write(String.format(FF, x[i + 1]) + "i");
600                    out.newLine();
601                    continue;
602                }
603                if (x[i + 1] < 0) {
604                    out.write(String.format(FF, x[i]) + " - " + String.format(FF, -x[i + 1]) + "i");
605                    out.newLine();
606                    continue;
607                }
608                out.write(String.format(FF, x[i]) + " + " + String.format(FF, x[i + 1]) + "i");
609                out.newLine();
610            }
611            out.newLine();
612            out.close();
613        } catch (IOException e) {
614            e.printStackTrace();
615        }
616    }
617
618    /**
619     * Saves elements of <code>x</code> in a file <code>filename</code>,
620     * assuming that it is 2D complex array. Complex data is represented by 2
621     * double values in sequence: the real and imaginary parts.
622     * 
623     * @param n1
624     * @param n2
625     * @param x
626     * @param filename
627     */
628    public static void writeToFileComplex_2D(int n1, int n2, double[] x, String filename) {
629        try {
630            BufferedWriter out = new BufferedWriter(new FileWriter(filename));
631            for (int i = 0; i < n1; i++) {
632                for (int j = 0; j < 2 * n2; j = j + 2) {
633                    if ((Math.abs(x[i * 2 * n2 + j]) < 5e-5) && (Math.abs(x[i * 2 * n2 + j + 1]) < 5e-5)) {
634                        if (x[i * 2 * n2 + j + 1] >= 0.0) {
635                            out.write("0 + 0i\t");
636                        } else {
637                            out.write("0 - 0i\t");
638                        }
639                        continue;
640                    }
641
642                    if (Math.abs(x[i * 2 * n2 + j + 1]) < 5e-5) {
643                        if (x[i * 2 * n2 + j + 1] >= 0.0) {
644                            out.write(String.format(FF, x[i * 2 * n2 + j]) + " + 0i\t");
645                        } else {
646                            out.write(String.format(FF, x[i * 2 * n2 + j]) + " - 0i\t");
647                        }
648                        continue;
649                    }
650                    if (Math.abs(x[i * 2 * n2 + j]) < 5e-5) {
651                        if (x[i * 2 * n2 + j + 1] >= 0.0) {
652                            out.write("0 + " + String.format(FF, x[i * 2 * n2 + j + 1]) + "i\t");
653                        } else {
654                            out.write("0 - " + String.format(FF, -x[i * 2 * n2 + j + 1]) + "i\t");
655                        }
656                        continue;
657                    }
658                    if (x[i * 2 * n2 + j + 1] < 0) {
659                        out.write(String.format(FF, x[i * 2 * n2 + j]) + " - " + String.format(FF, -x[i * 2 * n2 + j + 1]) + "i\t");
660                        continue;
661                    }
662                    out.write(String.format(FF, x[i * 2 * n2 + j]) + " + " + String.format(FF, x[i * 2 * n2 + j + 1]) + "i\t");
663                }
664                out.newLine();
665            }
666
667            out.newLine();
668            out.close();
669        } catch (IOException e) {
670            e.printStackTrace();
671        }
672    }
673
674    /**
675     * Saves elements of <code>x</code> in a file <code>filename</code>,
676     * assuming that it is 2D complex array. Complex data is represented by 2
677     * double values in sequence: the real and imaginary parts.
678     * 
679     * @param n1
680     * @param n2
681     * @param x
682     * @param filename
683     */
684    public static void writeToFileComplex_2D(int n1, int n2, float[] x, String filename) {
685        try {
686            BufferedWriter out = new BufferedWriter(new FileWriter(filename));
687            for (int i = 0; i < n1; i++) {
688                for (int j = 0; j < 2 * n2; j = j + 2) {
689                    if ((Math.abs(x[i * 2 * n2 + j]) < 5e-5) && (Math.abs(x[i * 2 * n2 + j + 1]) < 5e-5)) {
690                        if (x[i * 2 * n2 + j + 1] >= 0.0) {
691                            out.write("0 + 0i\t");
692                        } else {
693                            out.write("0 - 0i\t");
694                        }
695                        continue;
696                    }
697
698                    if (Math.abs(x[i * 2 * n2 + j + 1]) < 5e-5) {
699                        if (x[i * 2 * n2 + j + 1] >= 0.0) {
700                            out.write(String.format(FF, x[i * 2 * n2 + j]) + " + 0i\t");
701                        } else {
702                            out.write(String.format(FF, x[i * 2 * n2 + j]) + " - 0i\t");
703                        }
704                        continue;
705                    }
706                    if (Math.abs(x[i * 2 * n2 + j]) < 5e-5) {
707                        if (x[i * 2 * n2 + j + 1] >= 0.0) {
708                            out.write("0 + " + String.format(FF, x[i * 2 * n2 + j + 1]) + "i\t");
709                        } else {
710                            out.write("0 - " + String.format(FF, -x[i * 2 * n2 + j + 1]) + "i\t");
711                        }
712                        continue;
713                    }
714                    if (x[i * 2 * n2 + j + 1] < 0) {
715                        out.write(String.format(FF, x[i * 2 * n2 + j]) + " - " + String.format(FF, -x[i * 2 * n2 + j + 1]) + "i\t");
716                        continue;
717                    }
718                    out.write(String.format(FF, x[i * 2 * n2 + j]) + " + " + String.format(FF, x[i * 2 * n2 + j + 1]) + "i\t");
719                }
720                out.newLine();
721            }
722
723            out.newLine();
724            out.close();
725        } catch (IOException e) {
726            e.printStackTrace();
727        }
728    }
729
730    /**
731     * Saves elements of <code>x</code> in a file <code>filename</code>. Complex
732     * data is represented by 2 double values in sequence: the real and
733     * imaginary parts.
734     * 
735     * @param n1
736     * @param n2
737     * @param x
738     * @param filename
739     */
740    public static void writeToFileComplex_2D(int n1, int n2, double[][] x, String filename) {
741        try {
742            BufferedWriter out = new BufferedWriter(new FileWriter(filename));
743            for (int i = 0; i < n1; i++) {
744                for (int j = 0; j < 2 * n2; j = j + 2) {
745                    if ((Math.abs(x[i][j]) < 5e-5) && (Math.abs(x[i][j + 1]) < 5e-5)) {
746                        if (x[i][j + 1] >= 0.0) {
747                            out.write("0 + 0i\t");
748                        } else {
749                            out.write("0 - 0i\t");
750                        }
751                        continue;
752                    }
753
754                    if (Math.abs(x[i][j + 1]) < 5e-5) {
755                        if (x[i][j + 1] >= 0.0) {
756                            out.write(String.format(FF, x[i][j]) + " + 0i\t");
757                        } else {
758                            out.write(String.format(FF, x[i][j]) + " - 0i\t");
759                        }
760                        continue;
761                    }
762                    if (Math.abs(x[i][j]) < 5e-5) {
763                        if (x[i][j + 1] >= 0.0) {
764                            out.write("0 + " + String.format(FF, x[i][j + 1]) + "i\t");
765                        } else {
766                            out.write("0 - " + String.format(FF, -x[i][j + 1]) + "i\t");
767                        }
768                        continue;
769                    }
770                    if (x[i][j + 1] < 0) {
771                        out.write(String.format(FF, x[i][j]) + " - " + String.format(FF, -x[i][j + 1]) + "i\t");
772                        continue;
773                    }
774                    out.write(String.format(FF, x[i][j]) + " + " + String.format(FF, x[i][j + 1]) + "i\t");
775                }
776                out.newLine();
777            }
778
779            out.newLine();
780            out.close();
781        } catch (IOException e) {
782            e.printStackTrace();
783        }
784    }
785
786    /**
787     * Saves elements of <code>x</code> in a file <code>filename</code>,
788     * assuming that it is 3D complex array. Complex data is represented by 2
789     * double values in sequence: the real and imaginary parts.
790     * 
791     * @param n1
792     * @param n2
793     * @param n3
794     * @param x
795     * @param filename
796     */
797    public static void writeToFileComplex_3D(int n1, int n2, int n3, double[] x, String filename) {
798        int sliceStride = n2 * n3 * 2;
799        int rowStride = n3 * 2;
800        try {
801            BufferedWriter out = new BufferedWriter(new FileWriter(filename));
802            for (int k = 0; k < 2 * n3; k = k + 2) {
803                out.newLine();
804                out.write("(:,:," + k / 2 + ")=");
805                out.newLine();
806                out.newLine();
807                for (int i = 0; i < n1; i++) {
808                    for (int j = 0; j < n2; j++) {
809                        if (x[i * sliceStride + j * rowStride + k + 1] == 0) {
810                            out.write(String.format(FF, x[i * sliceStride + j * rowStride + k]) + "\t");
811                            continue;
812                        }
813                        if (x[i * sliceStride + j * rowStride + k] == 0) {
814                            out.write(String.format(FF, x[i * sliceStride + j * rowStride + k + 1]) + "i\t");
815                            continue;
816                        }
817                        if (x[i * sliceStride + j * rowStride + k + 1] < 0) {
818                            out.write(String.format(FF, x[i * sliceStride + j * rowStride + k]) + " - " + String.format(FF, -x[i * sliceStride + j * rowStride + k + 1]) + "i\t");
819                            continue;
820                        }
821                        out.write(String.format(FF, x[i * sliceStride + j * rowStride + k]) + " + " + String.format(FF, x[i * sliceStride + j * rowStride + k + 1]) + "i\t");
822                    }
823                    out.newLine();
824                }
825            }
826            out.newLine();
827            out.close();
828        } catch (IOException e) {
829            e.printStackTrace();
830        }
831    }
832
833    /**
834     * Saves elements of <code>x</code> in a file <code>filename</code>. Complex
835     * data is represented by 2 double values in sequence: the real and
836     * imaginary parts.
837     * 
838     * @param n1
839     * @param n2
840     * @param n3
841     * @param x
842     * @param filename
843     */
844    public static void writeToFileComplex_3D(int n1, int n2, int n3, double[][][] x, String filename) {
845        try {
846            BufferedWriter out = new BufferedWriter(new FileWriter(filename));
847            for (int k = 0; k < 2 * n3; k = k + 2) {
848                out.newLine();
849                out.write("(:,:," + k / 2 + ")=");
850                out.newLine();
851                out.newLine();
852                for (int i = 0; i < n1; i++) {
853                    for (int j = 0; j < n2; j++) {
854                        if (x[i][j][k + 1] == 0) {
855                            out.write(String.format(FF, x[i][j][k]) + "\t");
856                            continue;
857                        }
858                        if (x[i][j][k] == 0) {
859                            out.write(String.format(FF, x[i][j][k + 1]) + "i\t");
860                            continue;
861                        }
862                        if (x[i][j][k + 1] < 0) {
863                            out.write(String.format(FF, x[i][j][k]) + " - " + String.format(FF, -x[i][j][k + 1]) + "i\t");
864                            continue;
865                        }
866                        out.write(String.format(FF, x[i][j][k]) + " + " + String.format(FF, x[i][j][k + 1]) + "i\t");
867                    }
868                    out.newLine();
869                }
870            }
871            out.newLine();
872            out.close();
873        } catch (IOException e) {
874            e.printStackTrace();
875        }
876    }
877
878    /**
879     * Saves elements of <code>x</code> in a file <code>filename</code>,
880     * assuming that it is 2D real array.
881     * 
882     * @param x
883     * @param filename
884     */
885    public static void writeToFileReal_1D(double[] x, String filename) {
886        try {
887            BufferedWriter out = new BufferedWriter(new FileWriter(filename));
888            for (int j = 0; j < x.length; j++) {
889                out.write(String.format(FF, x[j]));
890                out.newLine();
891            }
892            out.close();
893        } catch (IOException e) {
894            e.printStackTrace();
895        }
896    }
897
898    /**
899     * Saves elements of <code>x</code> in a file <code>filename</code>,
900     * assuming that it is 2D real array.
901     * 
902     * @param x
903     * @param filename
904     */
905    public static void writeToFileReal_1D(float[] x, String filename) {
906        try {
907            BufferedWriter out = new BufferedWriter(new FileWriter(filename));
908            for (int j = 0; j < x.length; j++) {
909                out.write(String.format(FF, x[j]));
910                out.newLine();
911            }
912            out.close();
913        } catch (IOException e) {
914            e.printStackTrace();
915        }
916    }
917
918    /**
919     * Saves elements of <code>x</code> in a file <code>filename</code>,
920     * assuming that it is 2D real array.
921     * 
922     * @param n1
923     * @param n2
924     * @param x
925     * @param filename
926     */
927    public static void writeToFileReal_2D(int n1, int n2, double[] x, String filename) {
928        try {
929            BufferedWriter out = new BufferedWriter(new FileWriter(filename));
930            for (int i = 0; i < n1; i++) {
931                for (int j = 0; j < n2; j++) {
932                    if (Math.abs(x[i * n2 + j]) < 5e-5) {
933                        out.write("0\t");
934                    } else {
935                        out.write(String.format(FF, x[i * n2 + j]) + "\t");
936                    }
937                }
938                out.newLine();
939            }
940            out.close();
941        } catch (IOException e) {
942            e.printStackTrace();
943        }
944    }
945
946    /**
947     * Saves elements of <code>x</code> in a file <code>filename</code>,
948     * assuming that it is 2D real array.
949     * 
950     * @param n1
951     * @param n2
952     * @param x
953     * @param filename
954     */
955    public static void writeToFileReal_2D(int n1, int n2, float[] x, String filename) {
956        try {
957            BufferedWriter out = new BufferedWriter(new FileWriter(filename));
958            for (int i = 0; i < n1; i++) {
959                for (int j = 0; j < n2; j++) {
960                    if (Math.abs(x[i * n2 + j]) < 5e-5) {
961                        out.write("0\t");
962                    } else {
963                        out.write(String.format(FF, x[i * n2 + j]) + "\t");
964                    }
965                }
966                out.newLine();
967            }
968            out.close();
969        } catch (IOException e) {
970            e.printStackTrace();
971        }
972    }
973
974    /**
975     * Saves elements of <code>x</code> in a file <code>filename</code>,
976     * assuming that it is 3D real array.
977     * 
978     * @param n1
979     * @param n2
980     * @param n3
981     * @param x
982     * @param filename
983     */
984    public static void writeToFileReal_3D(int n1, int n2, int n3, double[] x, String filename) {
985        int sliceStride = n2 * n3;
986        int rowStride = n3;
987
988        try {
989            BufferedWriter out = new BufferedWriter(new FileWriter(filename));
990            for (int k = 0; k < n3; k++) {
991                out.newLine();
992                out.write("(:,:," + k + ")=");
993                out.newLine();
994                out.newLine();
995                for (int i = 0; i < n1; i++) {
996                    for (int j = 0; j < n2; j++) {
997                        out.write(String.format(FF, x[i * sliceStride + j * rowStride + k]) + "\t");
998                    }
999                    out.newLine();
1000                }
1001                out.newLine();
1002            }
1003            out.close();
1004        } catch (IOException e) {
1005            e.printStackTrace();
1006        }
1007    }
1008
1009    /**
1010     * Saves benchmark results in a file.
1011     * 
1012     * @param filename
1013     * @param nthread
1014     * @param niter
1015     * @param doWarmup
1016     * @param doScaling
1017     * @param times
1018     * @param sizes
1019     */
1020    public static void writeFFTBenchmarkResultsToFile(String filename, int nthread, int niter, boolean doWarmup, boolean doScaling, int[] sizes, double[] times) {
1021        String[] properties = { "os.name", "os.version", "os.arch", "java.vendor", "java.version" };
1022        try {
1023            BufferedWriter out = new BufferedWriter(new FileWriter(filename, false));
1024            out.write(new Date().toString());
1025            out.newLine();
1026            out.write("System properties:");
1027            out.newLine();
1028            out.write("\tos.name = " + System.getProperty(properties[0]));
1029            out.newLine();
1030            out.write("\tos.version = " + System.getProperty(properties[1]));
1031            out.newLine();
1032            out.write("\tos.arch = " + System.getProperty(properties[2]));
1033            out.newLine();
1034            out.write("\tjava.vendor = " + System.getProperty(properties[3]));
1035            out.newLine();
1036            out.write("\tjava.version = " + System.getProperty(properties[4]));
1037            out.newLine();
1038            out.write("\tavailable processors = " + Runtime.getRuntime().availableProcessors());
1039            out.newLine();
1040            out.write("Settings:");
1041            out.newLine();
1042            out.write("\tused processors = " + nthread);
1043            out.newLine();
1044            out.write("\tTHREADS_BEGIN_N_2D = " + ConcurrencyUtils.getThreadsBeginN_2D());
1045            out.newLine();
1046            out.write("\tTHREADS_BEGIN_N_3D = " + ConcurrencyUtils.getThreadsBeginN_3D());
1047            out.newLine();
1048            out.write("\tnumber of iterations = " + niter);
1049            out.newLine();
1050            out.write("\twarm-up performed = " + doWarmup);
1051            out.newLine();
1052            out.write("\tscaling performed = " + doScaling);
1053            out.newLine();
1054            out.write("--------------------------------------------------------------------------------------------------");
1055            out.newLine();
1056            out.write("sizes=[");
1057            for (int i = 0; i < sizes.length; i++) {
1058                out.write(Integer.toString(sizes[i]));
1059                if (i < sizes.length - 1) {
1060                    out.write(", ");
1061                } else {
1062                    out.write("]");
1063                }
1064            }
1065            out.newLine();
1066            out.write("times(in msec)=[");
1067            for (int i = 0; i < times.length; i++) {
1068                out.write(String.format("%.2f", times[i]));
1069                if (i < times.length - 1) {
1070                    out.write(", ");
1071                } else {
1072                    out.write("]");
1073                }
1074            }
1075            out.newLine();
1076            out.close();
1077        } catch (IOException e) {
1078            e.printStackTrace();
1079        }
1080    }
1081}