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 JTransforms. 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 ***** */ 034 035package edu.emory.mathcs.jtransforms.dct; 036 037import edu.emory.mathcs.utils.IOUtils; 038 039/** 040 * Accuracy check of single precision DCT's 041 * 042 * @author Piotr Wendykier (piotr.wendykier@gmail.com) 043 * 044 */ 045@SuppressWarnings("javadoc") 046public class AccuracyCheckFloatDCT { 047 048 private static int[] sizes1D = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, 32, 64, 100, 120, 128, 256, 310, 512, 049 1024, 1056, 2048, 8192, 10158, 16384, 32768, 65536, 131072 }; 050 051 private static int[] sizes2D = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, 32, 64, 100, 120, 128, 256, 310, 511, 052 512, 1024 }; 053 054 private static int[] sizes3D = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, 32, 64, 100, 128 }; 055 056 private static double eps = Math.pow(2, -23); 057 058 private AccuracyCheckFloatDCT() { 059 060 } 061 062 public static void checkAccuracyDCT_1D() { 063 System.out.println("Checking accuracy of 1D DCT..."); 064 for (int i = 0; i < sizes1D.length; i++) { 065 FloatDCT_1D dct = new FloatDCT_1D(sizes1D[i]); 066 double err = 0; 067 float[] a = new float[sizes1D[i]]; 068 IOUtils.fillMatrix_1D(sizes1D[i], a); 069 float[] b = new float[sizes1D[i]]; 070 IOUtils.fillMatrix_1D(sizes1D[i], b); 071 dct.forward(a, true); 072 dct.inverse(a, true); 073 err = computeRMSE(a, b); 074 if (err > eps) { 075 System.err.println("\tsize = " + sizes1D[i] + ";\terror = " + err); 076 } else { 077 System.out.println("\tsize = " + sizes1D[i] + ";\terror = " + err); 078 } 079 a = null; 080 b = null; 081 dct = null; 082 System.gc(); 083 } 084 } 085 086 public static void checkAccuracyDCT_2D() { 087 System.out.println("Checking accuracy of 2D DCT (float[] input)..."); 088 for (int i = 0; i < sizes2D.length; i++) { 089 FloatDCT_2D dct2 = new FloatDCT_2D(sizes2D[i], sizes2D[i]); 090 double err = 0; 091 float[] a = new float[sizes2D[i] * sizes2D[i]]; 092 IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], a); 093 float[] b = new float[sizes2D[i] * sizes2D[i]]; 094 IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], b); 095 dct2.forward(a, true); 096 dct2.inverse(a, true); 097 err = computeRMSE(a, b); 098 if (err > eps) { 099 System.err.println("\tsize = " + sizes2D[i] + " x " + sizes2D[i] + ";\terror = " + err); 100 } else { 101 System.out.println("\tsize = " + sizes2D[i] + " x " + sizes2D[i] + ";\terror = " + err); 102 } 103 a = null; 104 b = null; 105 dct2 = null; 106 System.gc(); 107 } 108 System.out.println("Checking accuracy of 2D DCT (float[][] input)..."); 109 for (int i = 0; i < sizes2D.length; i++) { 110 FloatDCT_2D dct2 = new FloatDCT_2D(sizes2D[i], sizes2D[i]); 111 double err = 0; 112 float[][] a = new float[sizes2D[i]][sizes2D[i]]; 113 IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], a); 114 float[][] b = new float[sizes2D[i]][sizes2D[i]]; 115 IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], b); 116 dct2.forward(a, true); 117 dct2.inverse(a, true); 118 err = computeRMSE(a, b); 119 if (err > eps) { 120 System.err.println("\tsize = " + sizes2D[i] + " x " + sizes2D[i] + ";\terror = " + err); 121 } else { 122 System.out.println("\tsize = " + sizes2D[i] + " x " + sizes2D[i] + ";\terror = " + err); 123 } 124 a = null; 125 b = null; 126 dct2 = null; 127 System.gc(); 128 } 129 130 } 131 132 public static void checkAccuracyDCT_3D() { 133 System.out.println("Checking accuracy of 3D DCT (float[] input)..."); 134 for (int i = 0; i < sizes3D.length; i++) { 135 FloatDCT_3D dct3 = new FloatDCT_3D(sizes3D[i], sizes3D[i], sizes3D[i]); 136 double err = 0; 137 float[] a = new float[sizes3D[i] * sizes3D[i] * sizes3D[i]]; 138 IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], a); 139 float[] b = new float[sizes3D[i] * sizes3D[i] * sizes3D[i]]; 140 IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], b); 141 dct3.forward(a, true); 142 dct3.inverse(a, true); 143 err = computeRMSE(a, b); 144 if (err > eps) { 145 System.err.println("\tsize = " + sizes3D[i] + " x " + sizes3D[i] + " x " + sizes3D[i] + ";\t\terror = " 146 + err); 147 } else { 148 System.out.println("\tsize = " + sizes3D[i] + " x " + sizes3D[i] + " x " + sizes3D[i] + ";\t\terror = " 149 + err); 150 } 151 a = null; 152 b = null; 153 dct3 = null; 154 System.gc(); 155 } 156 157 System.out.println("Checking accuracy of 3D DCT (float[][][] input)..."); 158 for (int i = 0; i < sizes3D.length; i++) { 159 FloatDCT_3D dct3 = new FloatDCT_3D(sizes3D[i], sizes3D[i], sizes3D[i]); 160 double err = 0; 161 float[][][] a = new float[sizes3D[i]][sizes3D[i]][sizes3D[i]]; 162 IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], a); 163 float[][][] b = new float[sizes3D[i]][sizes3D[i]][sizes3D[i]]; 164 IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], b); 165 dct3.forward(a, true); 166 dct3.inverse(a, true); 167 err = computeRMSE(a, b); 168 if (err > eps) { 169 System.err.println("\tsize = " + sizes3D[i] + " x " + sizes3D[i] + " x " + sizes3D[i] + ";\t\terror = " 170 + err); 171 } else { 172 System.out.println("\tsize = " + sizes3D[i] + " x " + sizes3D[i] + " x " + sizes3D[i] + ";\t\terror = " 173 + err); 174 } 175 a = null; 176 b = null; 177 dct3 = null; 178 System.gc(); 179 } 180 } 181 182 private static double computeRMSE(float[] a, float[] b) { 183 if (a.length != b.length) { 184 throw new IllegalArgumentException("Arrays are not the same size"); 185 } 186 double rms = 0; 187 double tmp; 188 for (int i = 0; i < a.length; i++) { 189 tmp = (a[i] - b[i]); 190 rms += tmp * tmp; 191 } 192 return Math.sqrt(rms / a.length); 193 } 194 195 private static double computeRMSE(float[][] a, float[][] b) { 196 if (a.length != b.length || a[0].length != b[0].length) { 197 throw new IllegalArgumentException("Arrays are not the same size"); 198 } 199 double rms = 0; 200 double tmp; 201 for (int r = 0; r < a.length; r++) { 202 for (int c = 0; c < a[0].length; c++) { 203 tmp = (a[r][c] - b[r][c]); 204 rms += tmp * tmp; 205 } 206 } 207 return Math.sqrt(rms / (a.length * a[0].length)); 208 } 209 210 private static double computeRMSE(float[][][] a, float[][][] b) { 211 if (a.length != b.length || a[0].length != b[0].length || a[0][0].length != b[0][0].length) { 212 throw new IllegalArgumentException("Arrays are not the same size"); 213 } 214 double rms = 0; 215 double tmp; 216 for (int s = 0; s < a.length; s++) { 217 for (int r = 0; r < a[0].length; r++) { 218 for (int c = 0; c < a[0][0].length; c++) { 219 tmp = (a[s][r][c] - b[s][r][c]); 220 rms += tmp * tmp; 221 } 222 } 223 } 224 return Math.sqrt(rms / (a.length * a[0].length * a[0][0].length)); 225 } 226 227 public static void main(String[] args) { 228 checkAccuracyDCT_1D(); 229 checkAccuracyDCT_2D(); 230 checkAccuracyDCT_3D(); 231 System.exit(0); 232 } 233}