/encog-core-silverlight/Neural/Data/Buffer/EncogEGBFile.cs

https://github.com/encog/encog-silverlight-core · C# · 496 lines · 294 code · 52 blank · 150 comment · 18 complexity · f16fc606b6f1ca844e8c9debf84eaec6 MD5 · raw file

  1. // Encog(tm) Artificial Intelligence Framework v2.5
  2. // .Net Version
  3. // http://www.heatonresearch.com/encog/
  4. // http://code.google.com/p/encog-java/
  5. //
  6. // Copyright 2008-2010 by Heaton Research Inc.
  7. //
  8. // Released under the LGPL.
  9. //
  10. // This is free software; you can redistribute it and/or modify it
  11. // under the terms of the GNU Lesser General Public License as
  12. // published by the Free Software Foundation; either version 2.1 of
  13. // the License, or (at your option) any later version.
  14. //
  15. // This software is distributed in the hope that it will be useful,
  16. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. // Lesser General Public License for more details.
  19. //
  20. // You should have received a copy of the GNU Lesser General Public
  21. // License along with this software; if not, write to the Free
  22. // Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  23. // 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  24. //
  25. // Encog and Heaton Research are Trademarks of Heaton Research, Inc.
  26. // For information on Heaton Research trademarks, visit:
  27. //
  28. // http://www.heatonresearch.com/copyright.html
  29. using System;
  30. using System.Collections.Generic;
  31. using System.Linq;
  32. using System.Text;
  33. using System.IO;
  34. namespace Encog.Neural.Data.Buffer
  35. {
  36. /// <summary>
  37. /// Reads in little endian form.
  38. /// </summary>
  39. public class EncogEGBFile
  40. {
  41. /// <summary>
  42. /// The size of a double.
  43. /// </summary>
  44. public const int DOUBLE_SIZE = sizeof(double);
  45. /// <summary>
  46. /// The size of the file header.
  47. /// </summary>
  48. public const int HEADER_SIZE = DOUBLE_SIZE * 3;
  49. /// <summary>
  50. /// The file that we are working with.
  51. /// </summary>
  52. private String file;
  53. /// <summary>
  54. /// The number of input values per record.
  55. /// </summary>
  56. private int inputCount;
  57. /// <summary>
  58. /// The number of ideal values per record.
  59. /// </summary>
  60. private int idealCount;
  61. /// <summary>
  62. /// The underlying file.
  63. /// </summary>
  64. private FileStream stream;
  65. /// <summary>
  66. /// The binary reader.
  67. /// </summary>
  68. private BinaryReader binaryReader;
  69. /// <summary>
  70. /// The binary writer.
  71. /// </summary>
  72. private BinaryWriter binaryWriter;
  73. /// <summary>
  74. /// The number of values in a record, this is the input and ideal combined.
  75. /// </summary>
  76. private int recordCount;
  77. /// <summary>
  78. /// The size of a record.
  79. /// </summary>
  80. private int recordSize;
  81. /// <summary>
  82. /// The number of records int he file.
  83. /// </summary>
  84. private int numberOfRecords;
  85. /// <summary>
  86. /// Construct an EGB file.
  87. /// </summary>
  88. /// <param name="file">The file.</param>
  89. public EncogEGBFile(String file)
  90. {
  91. this.file = file;
  92. }
  93. /// <summary>
  94. /// Create a new RGB file.
  95. /// </summary>
  96. /// <param name="inputCount">The input count.</param>
  97. /// <param name="idealCount">The ideal count.</param>
  98. public void Create(int inputCount, int idealCount)
  99. {
  100. try
  101. {
  102. this.inputCount = inputCount;
  103. this.idealCount = idealCount;
  104. double[] input = new double[inputCount];
  105. double[] ideal = new double[idealCount];
  106. this.stream = new FileStream(this.file, FileMode.Create, FileAccess.ReadWrite);
  107. this.binaryWriter = new BinaryWriter(this.stream);
  108. this.binaryReader = null;
  109. this.binaryWriter.Write((byte)'E');
  110. this.binaryWriter.Write((byte)'N');
  111. this.binaryWriter.Write((byte)'C');
  112. this.binaryWriter.Write((byte)'O');
  113. this.binaryWriter.Write((byte)'G');
  114. this.binaryWriter.Write((byte)'-');
  115. this.binaryWriter.Write((byte)'0');
  116. this.binaryWriter.Write((byte)'0');
  117. this.binaryWriter.Write((double)input.Length);
  118. this.binaryWriter.Write((double)ideal.Length);
  119. this.numberOfRecords = 0;
  120. this.recordCount = this.inputCount + this.idealCount;
  121. this.recordSize = this.recordCount * EncogEGBFile.DOUBLE_SIZE;
  122. }
  123. catch (IOException ex)
  124. {
  125. throw new BufferedDataError(ex);
  126. }
  127. }
  128. /// <summary>
  129. /// Open an existing EGB file.
  130. /// </summary>
  131. public void Open()
  132. {
  133. try
  134. {
  135. this.stream = new FileStream(this.file, FileMode.Open, FileAccess.Read);
  136. this.binaryReader = new BinaryReader(this.stream);
  137. this.binaryWriter = null;
  138. bool isEncogFile = true;
  139. isEncogFile = isEncogFile ? this.binaryReader.ReadByte() == 'E' : false;
  140. isEncogFile = isEncogFile ? this.binaryReader.ReadByte() == 'N' : false;
  141. isEncogFile = isEncogFile ? this.binaryReader.ReadByte() == 'C' : false;
  142. isEncogFile = isEncogFile ? this.binaryReader.ReadByte() == 'O' : false;
  143. isEncogFile = isEncogFile ? this.binaryReader.ReadByte() == 'G' : false;
  144. isEncogFile = isEncogFile ? this.binaryReader.ReadByte() == '-' : false;
  145. if (!isEncogFile)
  146. {
  147. throw new BufferedDataError(
  148. "File is not a valid Encog binary file:"
  149. + this.file);
  150. }
  151. char v1 = (char)this.binaryReader.ReadByte();
  152. char v2 = (char)this.binaryReader.ReadByte();
  153. String versionStr = "" + v1 + v2;
  154. try
  155. {
  156. int version = int.Parse(versionStr);
  157. if (version > 0)
  158. {
  159. throw new BufferedDataError(
  160. "File is from a newer version of Encog than is currently in use.");
  161. }
  162. }
  163. catch (Exception)
  164. {
  165. throw new BufferedDataError("File has invalid version number.");
  166. }
  167. this.inputCount = (int)this.binaryReader.ReadDouble();
  168. this.idealCount = (int)this.binaryReader.ReadDouble();
  169. this.recordCount = this.inputCount + this.idealCount;
  170. this.recordSize = this.recordCount * EncogEGBFile.DOUBLE_SIZE;
  171. this.numberOfRecords = (int)((this.stream.Length - EncogEGBFile.HEADER_SIZE) / this.recordSize);
  172. }
  173. catch (IOException ex)
  174. {
  175. throw new BufferedDataError(ex);
  176. }
  177. }
  178. /// <summary>
  179. /// Close the file.
  180. /// </summary>
  181. public void Close()
  182. {
  183. try
  184. {
  185. if (this.binaryWriter != null)
  186. {
  187. this.binaryWriter.Close();
  188. this.binaryWriter = null;
  189. }
  190. if (this.binaryReader != null)
  191. {
  192. this.binaryReader.Close();
  193. this.binaryReader = null;
  194. }
  195. if (this.stream != null)
  196. {
  197. this.stream.Close();
  198. this.stream = null;
  199. }
  200. }
  201. catch (IOException ex)
  202. {
  203. throw new BufferedDataError(ex);
  204. }
  205. }
  206. /// <summary>
  207. /// Calculate the index for the specified row.
  208. /// </summary>
  209. /// <param name="row">The row to calculate for.</param>
  210. /// <returns>The index.</returns>
  211. private int CalculateIndex(int row)
  212. {
  213. return EncogEGBFile.HEADER_SIZE + (row * this.recordSize);
  214. }
  215. /// <summary>
  216. /// Read a row and column.
  217. /// </summary>
  218. /// <param name="row">The row, or record, to read.</param>
  219. /// <param name="col">The column to read.</param>
  220. /// <returns>THe value read.</returns>
  221. private int CalculateIndex(int row, int col)
  222. {
  223. return EncogEGBFile.HEADER_SIZE + (row * this.recordSize)
  224. + (col * EncogEGBFile.DOUBLE_SIZE);
  225. }
  226. /// <summary>
  227. /// Set the current location to the specified row.
  228. /// </summary>
  229. /// <param name="row">The row.</param>
  230. public void SetLocation(int row)
  231. {
  232. try
  233. {
  234. this.stream.Position = CalculateIndex(row);
  235. }
  236. catch (IOException ex)
  237. {
  238. throw new BufferedDataError(ex);
  239. }
  240. }
  241. /// <summary>
  242. /// Write the specified row and column.
  243. /// </summary>
  244. /// <param name="row">The row.</param>
  245. /// <param name="col">The column.</param>
  246. /// <param name="v">The value.</param>
  247. public void Write(int row, int col, double v)
  248. {
  249. try
  250. {
  251. this.stream.Position = CalculateIndex(row, col);
  252. this.binaryWriter.Write(v);
  253. }
  254. catch (IOException ex)
  255. {
  256. throw new BufferedDataError(ex);
  257. }
  258. }
  259. /// <summary>
  260. /// Write an array at the specified record.
  261. /// </summary>
  262. /// <param name="row">The record to write.</param>
  263. /// <param name="v">The array to write.</param>
  264. public void Write(int row, double[] v)
  265. {
  266. try
  267. {
  268. this.stream.Position = CalculateIndex(row, 0);
  269. for (int i = 0; i < v.Length; i++)
  270. {
  271. this.binaryWriter.Write(v[i]);
  272. }
  273. }
  274. catch (IOException ex)
  275. {
  276. throw new BufferedDataError(ex);
  277. }
  278. }
  279. /// <summary>
  280. /// Write an array.
  281. /// </summary>
  282. /// <param name="v">The array to write.</param>
  283. public void Write(double[] v)
  284. {
  285. try
  286. {
  287. for (int i = 0; i < v.Length; i++)
  288. {
  289. this.binaryWriter.Write(v[i]);
  290. }
  291. }
  292. catch (IOException ex)
  293. {
  294. throw new BufferedDataError(ex);
  295. }
  296. }
  297. /// <summary>
  298. /// Write a byte.
  299. /// </summary>
  300. /// <param name="b">The byte to write.</param>
  301. public void Write(byte b)
  302. {
  303. try
  304. {
  305. this.binaryWriter.Write(b);
  306. }
  307. catch (IOException ex)
  308. {
  309. throw new BufferedDataError(ex);
  310. }
  311. }
  312. /// <summary>
  313. /// Read a row and column.
  314. /// </summary>
  315. /// <param name="row">The row to read.</param>
  316. /// <param name="col">The column to read.</param>
  317. /// <returns>The value read.</returns>
  318. public double Read(int row, int col)
  319. {
  320. try
  321. {
  322. this.stream.Position = CalculateIndex(row, col);
  323. return this.binaryReader.ReadDouble();
  324. }
  325. catch (IOException ex)
  326. {
  327. throw new BufferedDataError(ex);
  328. }
  329. }
  330. /// <summary>
  331. /// Read a double array at the specified record.
  332. /// </summary>
  333. /// <param name="row">The record to read.</param>
  334. /// <param name="d">The array to read into.</param>
  335. public void Read(int row, double[] d)
  336. {
  337. try
  338. {
  339. this.stream.Position = CalculateIndex(row, 0);
  340. for (int i = 0; i < recordCount; i++)
  341. {
  342. d[i] = this.binaryReader.ReadDouble();
  343. }
  344. }
  345. catch (IOException ex)
  346. {
  347. throw new BufferedDataError(ex);
  348. }
  349. }
  350. /// <summary>
  351. /// Read an array of doubles.
  352. /// </summary>
  353. /// <param name="d">The array to read into.</param>
  354. public void Read(double[] d)
  355. {
  356. try
  357. {
  358. for (int i = 0; i < d.Length; i++)
  359. {
  360. d[i] = this.binaryReader.ReadDouble();
  361. }
  362. }
  363. catch (IOException ex)
  364. {
  365. throw new BufferedDataError(ex);
  366. }
  367. }
  368. /// <summary>
  369. /// Read a single double.
  370. /// </summary>
  371. /// <returns>The double read.</returns>
  372. public double Read()
  373. {
  374. try
  375. {
  376. return this.binaryReader.ReadDouble();
  377. }
  378. catch (IOException ex)
  379. {
  380. throw new BufferedDataError(ex);
  381. }
  382. }
  383. /// <summary>
  384. /// The input count.
  385. /// </summary>
  386. public int InputCount
  387. {
  388. get
  389. {
  390. return inputCount;
  391. }
  392. }
  393. /// <summary>
  394. /// The ideal count.
  395. /// </summary>
  396. public int IdealCount
  397. {
  398. get
  399. {
  400. return idealCount;
  401. }
  402. }
  403. /// <summary>
  404. /// The stream.
  405. /// </summary>
  406. public FileStream Stream
  407. {
  408. get
  409. {
  410. return this.stream;
  411. }
  412. }
  413. /// <summary>
  414. /// The record count.
  415. /// </summary>
  416. public int RecordCount
  417. {
  418. get
  419. {
  420. return recordCount;
  421. }
  422. }
  423. /// <summary>
  424. /// The record size.
  425. /// </summary>
  426. public int RecordSize
  427. {
  428. get
  429. {
  430. return recordSize;
  431. }
  432. }
  433. /// <summary>
  434. /// The number of records.
  435. /// </summary>
  436. public int NumberOfRecords
  437. {
  438. get
  439. {
  440. return numberOfRecords;
  441. }
  442. }
  443. }
  444. }