package de.gaalop.tba.table;
import de.gaalop.tba.BladeRef;
import de.gaalop.tba.IMultTable;
import de.gaalop.tba.Multivector;
import de.gaalop.tba.table.BitIO.*;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Stores the product tables in a compressed format
* @author christian
*/
public class TableCompressed implements TableReaderIO {
private AbsBitReader reader;
private AbsBitWriter writer;
public TableCompressed(AbsBitReader reader, AbsBitWriter writer) {
this.reader = reader;
this.writer = writer;
}
@Override
public void readFromInputStream(DataInputStream in, IMultTable innerTable, IMultTable outerTable, IMultTable geoTable) {
try {
int dimension = in.readByte();
int bladeCount = (int) Math.pow(2,dimension);
int bitCount = in.readByte();
reader.setDataInputStream(in);
for (int i=0;i<bladeCount;i++)
for (int j=0;j<bladeCount;j++) {
innerTable.setProduct(i, j, readMultivector(reader, dimension, bitCount));
outerTable.setProduct(i, j, readMultivector(reader, dimension, bitCount));
geoTable.setProduct(i, j, readMultivector(reader, dimension, bitCount));
}
in.close();
} catch (IOException ex) {
Logger.getLogger(TableCompressed.class.getName()).log(Level.SEVERE, null, ex);
}
}
/**
* Reads a multivector
* @param in The reader to be used
* @param dimension The dimension of the algebra
* @param bitCount The bit count
* @return The read multivector
* @throws IOException
*/
private Multivector readMultivector(AbsBitReader in, int dimension, int bitCount) throws IOException {
Multivector result = new Multivector();
int size = in.read(bitCount);
for (int i=0;i<size;i++) {
int prefactor = in.read(1);
int index = in.read(dimension);
result.addBlade(new BladeRef((prefactor == 1) ? (byte) -1: (byte) 1, index));
}
return result;
}
/**
* Writes a multivector
* @param product The multivector to be written
* @param dimension The dimension of the algebra
* @param out The writer to be used
* @param bitCount The bit count
* @throws IOException
*/
private void writeMultivector(Multivector product, int dimension, AbsBitWriter out, int bitCount) throws IOException {
int size = product.getBlades().size();
out.write(size, bitCount);
for (BladeRef bR: product.getBlades()) {
out.write((bR.getPrefactor() < 0) ? 1 : 0, 1);
out.write(bR.getIndex(), dimension);
}
}
@Override
public void writeFromInputStream(int bladeCount, int dimension, IMultTable innerTable, IMultTable outerTable, IMultTable geoTable, DataOutputStream out) {
try {
AbsBitWriter w = new SimpleBitWriter();
int bitCount = 32;
File tempFile = File.createTempFile("TableCreator", "txt");
DataOutputStream out1 = new DataOutputStream(new FileOutputStream(tempFile));
w.setDataOutputStream(out1);
int maxNumber = 0;
for (int i=0;i<bladeCount;i++)
for (int j=0;j<bladeCount;j++) {
Multivector innerM = innerTable.getProduct(i, j);
Multivector outerM = outerTable.getProduct(i, j);
Multivector geoM = geoTable.getProduct(i, j);
maxNumber = Math.max(maxNumber, innerM.getBlades().size());
maxNumber = Math.max(maxNumber, outerM.getBlades().size());
maxNumber = Math.max(maxNumber, geoM.getBlades().size());
writeMultivector(innerM, dimension, w, bitCount);
writeMultivector(outerM, dimension, w, bitCount);
writeMultivector(geoM, dimension, w, bitCount);
}
w.finish();
out1.close();
// =====
DataInputStream in = new DataInputStream(new FileInputStream(tempFile));
AbsBitReader r = new SimpleBitReader();
r.setDataInputStream(in);
int number = 2;
int bitCount2 = 1;
while (number < maxNumber+1) {
bitCount2++;
number *= 2;
}
out.writeByte(dimension); //dimension
out.writeByte(bitCount2);
writer.setDataOutputStream(out);
for (int i=0;i<bladeCount;i++)
for (int j=0;j<bladeCount;j++) {
writeMultivector(readMultivector(r, dimension, bitCount), dimension, writer, bitCount2);
writeMultivector(readMultivector(r, dimension, bitCount), dimension, writer, bitCount2);
writeMultivector(readMultivector(r, dimension, bitCount), dimension, writer, bitCount2);
}
writer.finish();
in.close();
tempFile.delete();
} catch (IOException ex) {
Logger.getLogger(TableCompressed.class.getName()).log(Level.SEVERE, null, ex);
}
}
public AbsBitReader getReader() {
return reader;
}
}