size(900,568,P3D);
// The inimmitable graph visualization explorer
public class Adventurer {
public Graph g;
public Adventurer( Graph base ) {
g = base;
make_all_basic_matrices();
}
public void make_all_basic_matrices() {
int max = g.numbering.size();
g.matrix = new Matrix[Graph.MatrixTypeIndex.MATRIX_FIELD_COUNT];
float[] threeArgs = new float[] { (float)Math.random()*max, (float)Math.random()*max, (float)Math.random()*max };
for(int i = 0; i < Graph.MatrixTypeIndex.MATRIX_FIELD_COUNT;i++) {
Algebraicist.form(g, i, threeArgs);
}
}
public Matrix make_random_filter(int rand_base_matrix1, int rand_base_matrix2, int rand_power, int rand_binary ) {
//System.out.println("RF: " + rand_base_matrix1 + "," + rand_base_matrix2 + "," + rand_power + "," + rand_binary);
Matrix f = new Matrix(g.matrix[rand_base_matrix1]);
int max = g.numbering.size();
float[] threeArgs = new float[] { (float)Math.random()*max, (float)Math.random()*max, (float)Math.random()*max };
f = Arithmetician.fastMultiproduct(f, rand_power);
f = Arithmetician.ApplyBinary(rand_binary, f, g.matrix[rand_base_matrix2], threeArgs);
return f;
}
public Matrix make_random_Matrix_filter(int mod_or_not, int[] param_Base_Matrix, int[] param_Unary_Ops, int[] param_Binary_Combinators, int[] zeroOne, float[] threeArgs) {
// We choose a filter length of max 5 matrices
// We choose five matrices, and five unary filters to apply to each matrix
// We choose 4 binary combinator ops to combine these 5 matrices
// We collapse these ops right to left to construct a random filter
// But it is only random in the sense that we choose our exploration of the filterspace randomly (or using a basic GA)
// It is deterministic on the parameters passed in here
// Which in GA are 'genetic code' / feature vector
Matrix[] theFive = new Matrix[5];
int i = 5;
while(--i >= 0)
theFive[i] = g.matrix[param_Base_Matrix[i]];
if(mod_or_not == 0) {
i = 5;
while(--i >= 0)
theFive[i] = Arithmetician.ApplyUnary(param_Unary_Ops[i], theFive[i], threeArgs, zeroOne );
i = 4;
Matrix result = theFive[4];
while(--i >= 0)
result = Arithmetician.ApplyBinary(param_Binary_Combinators[i], theFive[i], result, threeArgs);
return result;
}
else {
i = 5;
while(--i >= 0)
theFive[i] = Arithmetician.ApplyModUnary(param_Unary_Ops[i], theFive[i], threeArgs, zeroOne );
i = 4;
Matrix result = theFive[4];
while(--i >= 0)
result = Arithmetician.ApplyModBinary(param_Binary_Combinators[i], theFive[i], result, threeArgs);
return result;
}
}
}
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
// He makes stuff
public class Algebraicist {
// 5 primitive matrices
public static Matrix form( Graph g, int matrixType, float[] threeArgs ) {
switch(matrixType) {
case(Graph.MatrixTypeIndex.ADJACENCY):
return g.matrix[Graph.MatrixTypeIndex.ADJACENCY] = adjacency(g);
case(Graph.MatrixTypeIndex.DEGREE):
return g.matrix[Graph.MatrixTypeIndex.DEGREE] = degree(g);
case(Graph.MatrixTypeIndex.ADJACENCY_2STEP):
return g.matrix[Graph.MatrixTypeIndex.ADJACENCY_2STEP] = exactlyTwoStepAdjacency(g.matrix[Graph.MatrixTypeIndex.ADJACENCY]);
case(Graph.MatrixTypeIndex.DEGREE_1STEP):
return g.matrix[Graph.MatrixTypeIndex.DEGREE_1STEP] = exactlyOneStepDegree(g.matrix[Graph.MatrixTypeIndex.DEGREE], g.matrix[Graph.MatrixTypeIndex.ADJACENCY]);
case(Graph.MatrixTypeIndex.DEGREE_2STEP):
return g.matrix[Graph.MatrixTypeIndex.DEGREE_2STEP] = exactlyTwoStepDegree(g.matrix[Graph.MatrixTypeIndex.DEGREE], g.matrix[Graph.MatrixTypeIndex.ADJACENCY_2STEP]);
case(Graph.MatrixTypeIndex.SEIDELADJACENCY):
return g.matrix[Graph.MatrixTypeIndex.SEIDELADJACENCY] = seidelAdjacency(g.matrix[Graph.MatrixTypeIndex.ADJACENCY]);
case(Graph.MatrixTypeIndex.AUGMENTEDADJACENCY):
return g.matrix[Graph.MatrixTypeIndex.AUGMENTEDADJACENCY] = augmentedAdjacencyMatrix(g.matrix[Graph.MatrixTypeIndex.ADJACENCY] );
case(Graph.MatrixTypeIndex.SHAREOFDEGREE):
return g.matrix[Graph.MatrixTypeIndex.SHAREOFDEGREE] = shareOfDegree( g, g.matrix[Graph.MatrixTypeIndex.DEGREE] );
case(Graph.MatrixTypeIndex.MINIMUMDISTANCEMATRIX):
return g.matrix[Graph.MatrixTypeIndex.MINIMUMDISTANCEMATRIX] = minimumDistanceMatrix(g.matrix[Graph.MatrixTypeIndex.ADJACENCY]);
case(Graph.MatrixTypeIndex.GENERALIZEDADJACENCY):
return g.matrix[Graph.MatrixTypeIndex.GENERALIZEDADJACENCY] = generalizedAdjacency( threeArgs[0], threeArgs[1], threeArgs[2], g.matrix[Graph.MatrixTypeIndex.ADJACENCY] );
case(Graph.MatrixTypeIndex.WEIGHTEDDEGREE):
return g.matrix[Graph.MatrixTypeIndex.WEIGHTEDDEGREE] = weightedDegree( g.matrix[Graph.MatrixTypeIndex.DEGREE], threeArgs[0] );
case(Graph.MatrixTypeIndex.WEIGHTEDADJACENCY):
return g.matrix[Graph.MatrixTypeIndex.WEIGHTEDADJACENCY] = weightedAdjacency( g.matrix[Graph.MatrixTypeIndex.ADJACENCY], threeArgs[0] );
case(Graph.MatrixTypeIndex.SPIELMANLAZYWALK):
return g.matrix[Graph.MatrixTypeIndex.SPIELMANLAZYWALK] = SpielmanLazywalkMatrix(g.matrix[Graph.MatrixTypeIndex.DEGREE], g.matrix[Graph.MatrixTypeIndex.ADJACENCY]);
case(Graph.MatrixTypeIndex.LAZYWALKSOFTINVERSE):
return g.matrix[Graph.MatrixTypeIndex.LAZYWALKSOFTINVERSE] = lazywalkMatrixSoftInverse(g.matrix[Graph.MatrixTypeIndex.DEGREE], g.matrix[Graph.MatrixTypeIndex.ADJACENCY]);
case(Graph.MatrixTypeIndex.NSTEPWALKS):
return g.matrix[Graph.MatrixTypeIndex.NSTEPWALKS] = Arithmetician.fastMultiproduct(g.matrix[Graph.MatrixTypeIndex.ADJACENCY], (int)threeArgs[0]);
case(Graph.MatrixTypeIndex.TRANSITIONMATRIXRANDOMWALK):
return g.matrix[Graph.MatrixTypeIndex.TRANSITIONMATRIXRANDOMWALK] = transitionMatrixRandomWalk( g.matrix[Graph.MatrixTypeIndex.ADJACENCY], g.matrix[Graph.MatrixTypeIndex.DEGREE] );
case(Graph.MatrixTypeIndex.LAPLACIAN):
return g.matrix[Graph.MatrixTypeIndex.LAPLACIAN] = laplacian(g.matrix[Graph.MatrixTypeIndex.DEGREE], g.matrix[Graph.MatrixTypeIndex.ADJACENCY], threeArgs[0]);
case(Graph.MatrixTypeIndex.SOFTNORMALIZEDLAPLACIAN):
return g.matrix[Graph.MatrixTypeIndex.SOFTNORMALIZEDLAPLACIAN] = SoftNormalizedLaplacian(g.matrix[Graph.MatrixTypeIndex.DEGREE], g.matrix[Graph.MatrixTypeIndex.LAPLACIAN], threeArgs[0]);
case(Graph.MatrixTypeIndex.HARDNORMALIZEDLAPLACIAN):
return g.matrix[Graph.MatrixTypeIndex.HARDNORMALIZEDLAPLACIAN] = HardNormalizedLaplacian(g.matrix[Graph.MatrixTypeIndex.DEGREE], g.matrix[Graph.MatrixTypeIndex.LAPLACIAN], threeArgs[0]);
case(Graph.MatrixTypeIndex.COMMUTETIME):
return g.matrix[Graph.MatrixTypeIndex.COMMUTETIME] = commuteTime(g);
case(Graph.MatrixTypeIndex.DEFORMEDLAPLACIAN):
return g.matrix[Graph.MatrixTypeIndex.DEFORMEDLAPLACIAN] = deformedLaplacian(g.matrix[Graph.MatrixTypeIndex.DEGREE], g.matrix[Graph.MatrixTypeIndex.ADJACENCY], threeArgs[0]);
case(Graph.MatrixTypeIndex.PROJECTIONMATRIX):
return g.matrix[Graph.MatrixTypeIndex.PROJECTIONMATRIX] = projectionMatrix((int)threeArgs[0], (int)threeArgs[1]);
case(Graph.MatrixTypeIndex.MAXIMUMDISTANCEMATRIX):
return g.matrix[Graph.MatrixTypeIndex.MAXIMUMDISTANCEMATRIX] = maximumDistanceMatrix(g.matrix[Graph.MatrixTypeIndex.COMMUTETIME]);
default:
return new Matrix(Matrix.IDENTITY,g.numbering.size(),g.numbering.size());
}
}
public static Matrix adjacency( Graph g ) {
int vertices = g.edgesByVertexA.size();
Set<Graph.Vertex> verticeSet = g.edgesByVertexA.keySet();
Iterator<Graph.Vertex> vertexIterator = verticeSet.iterator();
Matrix am = new Matrix(Matrix.NONE, vertices, vertices);
HashMap<Graph.Vertex,Integer> numbering = g.numbering();
while(vertexIterator.hasNext()) {
Graph.Vertex v = vertexIterator.next();
int vnum = numbering.get(v);
Set<Graph.Edge> vOutEdges = g.edgesByVertexA.get(v);
Set<Graph.Edge> vInEdges = g.edgesByVertexB.get(v);
Iterator<Graph.Edge> vOutIterator = vOutEdges.iterator();
while(vOutIterator.hasNext()) {
Graph.Edge e = vOutIterator.next();
Graph.Vertex b = e.b;
int bnum = numbering.get(b);
am.entry[vnum][bnum] = 1.0f;
}
Iterator<Graph.Edge> vInIterator = vInEdges.iterator();
while(vInIterator.hasNext()) {
Graph.Edge e = vInIterator.next();
Graph.Vertex a = e.a;
int anum = numbering.get(a);
am.entry[anum][vnum] = 1.0f;
}
}
am.updates &= (Matrix.all_changed^Matrix.entry_changed);
return am;
}
public static Matrix incidence( Graph g ) { // VxE
int vertices = g.numbering.size();
int edges = g.edgeNumbering.size();
Matrix im = new Matrix(Matrix.NONE, vertices, edges );
Set<Graph.Edge> edgeSet = g.edgeNumbering.keySet();
Iterator<Graph.Edge> edgeIterator = edgeSet.iterator();
while(edgeIterator.hasNext()) {
Graph.Edge e = edgeIterator.next();
int edgnum = g.edgeNumbering.get(e);
Graph.Vertex a = e.a;
Graph.Vertex b = e.b;
int anum = g.numbering.get(a);
int bnum = g.numbering.get(b);
im.entry[anum][edgnum] = 1.0f;
im.entry[bnum][edgnum] = 1.0f;
}
return im;
}
public static Matrix SignedIncidence( Graph g ) { // VxE
int vertices = g.numbering.size();
int edges = g.edgeNumbering.size();
Matrix im = new Matrix(Matrix.NONE, vertices, edges );
Set<Graph.Edge> edgeSet = g.edgeNumbering.keySet();
Iterator<Graph.Edge> edgeIterator = edgeSet.iterator();
while(edgeIterator.hasNext()) {
Graph.Edge e = edgeIterator.next();
int edgnum = g.edgeNumbering.get(e);
Graph.Vertex a = e.a;
Graph.Vertex b = e.b;
int anum = g.numbering.get(a);
int bnum = g.numbering.get(b);
im.entry[anum][edgnum] = 1.0f;
im.entry[bnum][edgnum] = -1.0f;
}
return im;
}
public static Matrix degree( Graph g ) {
int vertices = g.edgesByVertexA.size();
Matrix dg = new Matrix(Matrix.NONE, vertices, vertices);
HashMap<Graph.Vertex,Integer> numbering = g.numbering();
Set<Graph.Vertex> verticeSet = g.edgesByVertexA.keySet();
Iterator<Graph.Vertex> vertexIterator = verticeSet.iterator();
g.volume = 0.0f;
while(vertexIterator.hasNext()) {
Graph.Vertex v = vertexIterator.next();
int vnum = numbering.get(v);
Set<Graph.Edge> vOutEdges = g.edgesByVertexA.get(v);
Set<Graph.Edge> vInEdges = g.edgesByVertexB.get(v);
g.volume += dg.entry[vnum][vnum] = vOutEdges.size() + vInEdges.size();
}
dg.updates &= (Matrix.all_changed^Matrix.entry_changed);
return dg;
}
public static Matrix edgeAdjacency( Graph g ) { // ExE
Set<Graph.Vertex> verticeSet = g.edgesByVertexA.keySet();
Iterator<Graph.Vertex> vertexIterator = verticeSet.iterator();
int edges = g.edgeNumbering.size();
Matrix eda = new Matrix(Matrix.NONE, edges, edges);
while(vertexIterator.hasNext()) {
Graph.Vertex stupidFuckFace = vertexIterator.next();
Set<Graph.Edge> fuckingMoron = g.edgesByVertexA.get(stupidFuckFace);
Iterator<Graph.Edge> edgeIterator = fuckingMoron.iterator();
while(edgeIterator.hasNext()) {
Graph.Edge e = edgeIterator.next();
int edgnum = g.edgeNumbering.get(e);
Graph.Vertex a = e.a;
Set<Graph.Edge> heIsStillAFuckFace = g.edgesByVertexA.get(a);
Iterator<Graph.Edge> fuckIterator = heIsStillAFuckFace.iterator();
while(fuckIterator.hasNext()) {
Graph.Edge eneighbour = fuckIterator.next();
int eneighbournum = g.edgeNumbering.get(eneighbour);
if(edgnum != eneighbournum)
eda.entry[edgnum][eneighbournum] = 1.0f;
}
if(a!=e.b) {
Graph.Vertex b = e.b;
heIsStillAFuckFace = g.edgesByVertexA.get(b);
fuckIterator = heIsStillAFuckFace.iterator();
while(fuckIterator.hasNext()) {
Graph.Edge eneighbour = fuckIterator.next();
int eneighbournum = g.edgeNumbering.get(eneighbour);
if(edgnum != eneighbournum)
eda.entry[edgnum][eneighbournum] = 1.0f;
}
}
}
}
eda.updates &= (Matrix.all_changed^Matrix.entry_changed);
return eda;
}
public static Matrix edgeDegree( Graph g ) { // ExE
Set<Graph.Vertex> verticeSet = g.edgesByVertexA.keySet();
Iterator<Graph.Vertex> vertexIterator = verticeSet.iterator();
int edges = g.edgeNumbering.size();
Matrix edd = new Matrix(Matrix.NONE, edges, edges);
while(vertexIterator.hasNext()) {
Graph.Vertex stupidFuckFace = vertexIterator.next();
Set<Graph.Edge> fuckingMoron = g.edgesByVertexA.get(stupidFuckFace);
Iterator<Graph.Edge> edgeIterator = fuckingMoron.iterator();
while(edgeIterator.hasNext()) {
Graph.Edge e = edgeIterator.next();
int edgnum = g.edgeNumbering.get(e);
Graph.Vertex a = e.a;
Set<Graph.Edge> heIsStillAFuckFace = g.edgesByVertexA.get(a);
Iterator<Graph.Edge> fuckIterator = heIsStillAFuckFace.iterator();
while(fuckIterator.hasNext()) {
Graph.Edge eneighbour = fuckIterator.next();
int eneighbournum = g.edgeNumbering.get(eneighbour);
if(edgnum != eneighbournum)
edd.entry[edgnum][edgnum] += 1.0f;
}
if(a!=e.b) {
Graph.Vertex b = e.b;
heIsStillAFuckFace = g.edgesByVertexA.get(b);
fuckIterator = heIsStillAFuckFace.iterator();
while(fuckIterator.hasNext()) {
Graph.Edge eneighbour = fuckIterator.next();
int eneighbournum = g.edgeNumbering.get(eneighbour);
if(edgnum != eneighbournum)
edd.entry[edgnum][edgnum] += 1.0f;
}
}
}
}
edd.updates &= (Matrix.all_changed^Matrix.entry_changed);
return edd;
}
// 5 secondary matrix operators
public static Matrix complement( Matrix a ) {
int i = a.rows;
int j = a.columns;
Matrix c = new Matrix(Matrix.NONE, i, j);
while( --i >= 0 ) {
while( --j >= 0 ) {
if( a.entry[i][j] != 0.0f)
c.entry[i][j] = 0.0f;
else
c.entry[i][j] = 1.0f;
}
j = a.columns;
}
return c;
}
public static Matrix exactlyTwoStepAdjacency( Matrix a ) {
int i = a.rows;
int j = a.columns;
int shortest = a.shortest;
Matrix a2 = new Matrix(Matrix.NONE, i, j);
while( --i >= 0 ) {
while( --j >= 0 ) {
int k = shortest;
while ( --k >= 0 ) {
if( a.entry[i][k] != 0.0f && a.entry[k][j] != 0.0f )
a2.entry[i][j] = a.entry[i][k] + a.entry[k][j];
}
}
j = a.columns;
}
return a2;
}
public static Matrix exactlyOneStepDegree( Matrix d, Matrix a ) {
int i = a.rows;
int j = a.columns;
Matrix d1 = new Matrix(Matrix.NONE, i, j);
while( --i >= 0 ) {
while( --j >= 0 ) {
if( a.entry[i][j] != 0.0f)
d1.entry[i][i] += d.entry[j][j];
}
j = a.columns;
}
return d1;
}
public static Matrix exactlyTwoStepDegree( Matrix d, Matrix a2 ) {
int i = a2.rows;
int j = a2.columns;
Matrix d2 = new Matrix(Matrix.NONE, i, j);
while( --i >= 0 ) {
while( --j >= 0 ) {
if( a2.entry[i][j] != 0.0f)
d2.entry[i][i] += d.entry[j][j];
}
j = a2.columns;
}
return d2;
}
public static Matrix seidelAdjacency( Matrix a ) {
int i = a.rows;
int j = a.columns;
Matrix sa = new Matrix(Matrix.NONE, i, j);
while( --i >= 0 ) {
while( --j >= 0 ) {
if(i==j)
sa.entry[i][i] = 0.0f;
else if(a.entry[i][j] != 0.0f)
sa.entry[i][j] = -1.0f;
else
sa.entry[i][j] = 1.0f;
}
j = a.columns;
}
return sa;
}
// 22 Matrix combinators
public static Matrix augmentedAdjacencyMatrix( Matrix incidence ) {
return Arithmetician.productResult(incidence, incidence.transpose());
}
public static Matrix FanChungBoundaryOperator( Matrix SignedIncidence, Matrix degree ) {
int i = SignedIncidence.rows;
int j = SignedIncidence.columns;
Matrix sd = Arithmetician.entrywiseSquareRootResult(degree);
Matrix b = new Matrix(Matrix.NONE, j, i);
while( --i >= 0 ) {
while( --j >= 0 ) {
b.entry[j][i] = SignedIncidence.entry[i][j]/sd.entry[i][i];
}
j = SignedIncidence.columns;
}
return b;
}
public static Matrix shareOfDegree( Graph g, Matrix degree ) {
int i = degree.rows;
int j = degree.columns;
Matrix sd = new Matrix(Matrix.NONE, i, j);
while( --i >= 0 ) {
while( --j >= 0 ) {
sd.entry[i][j] = degree.entry[i][j]/g.volume;
}
j = degree.columns;
}
return sd;
}
public static Matrix minimumDistanceMatrix(Matrix connectivityMetric) {
return Arithmetician.FloydWarshall(connectivityMetric, 1.0f, 50.0f, connectivityMetric.shortest*4.0f*50.0f, 0, Arithmetician.MIN );
}
public static Matrix generalizedAdjacency( float x, float y, float z, Matrix a ) {
//(xI +yA + z(J-I-A))
return Arithmetician.pairwiseSumResult(
Arithmetician.scalarMultiplyResult(
new Matrix(Matrix.IDENTITY, a.rows, a.columns), x),
Arithmetician.pairwiseSumResult(
Arithmetician.scalarMultiplyResult(a, y),
Arithmetician.scalarMultiplyResult(
Arithmetician.pairwiseSubtractResult(
new Matrix(Matrix.COUNTERIDENTITY, a.rows, a.columns),
Arithmetician.pairwiseSumResult(new Matrix(Matrix.IDENTITY, a.rows, a.columns), a)),
z)
));
}
public static Matrix weightedDegree( Matrix degree, float weight ) {
return Arithmetician.scalarMultiplyResult(degree, weight);
}
public static Matrix weightedAdjacency( Matrix adjacency, float weight ) {
return Arithmetician.scalarMultiplyResult(adjacency, weight);
}
public static Matrix SpielmanLazywalkMatrix(Matrix degree, Matrix adjacency) {
return Arithmetician.scalarMultiplyResult(
Arithmetician.pairwiseSumResult(
new Matrix(Matrix.IDENTITY, adjacency.rows, adjacency.columns),
Arithmetician.productResult(adjacency,
Arithmetician.Inverse(degree))),
0.5f);
}
public static Matrix lazywalkMatrixSoftInverse(Matrix degree, Matrix adjacency) {
return Arithmetician.scalarMultiplyResult(
Arithmetician.pairwiseSumResult(
new Matrix(Matrix.IDENTITY, adjacency.rows, adjacency.columns),
Arithmetician.productResult(degree,
Arithmetician.Inverse(adjacency))),
2.0f);
}
public static Matrix nStepWalks( Matrix adjacency, int nsteps ) {
return Arithmetician.fastMultiproduct(adjacency, nsteps);
}
public static Matrix transitionMatrixRandomWalk( Matrix a, Matrix degree ) {
int i = a.rows;
int j = a.columns;
Matrix t = new Matrix(Matrix.NONE, i, j);
while( --i >= 0 ) {
while( --j >= 0 ) {
if( a.entry[i][j] != 0.0f )
t.entry[i][j] = 1.0f/degree.entry[i][i];
}
j = a.columns;
}
return t;
}
public static Matrix laplacian(Matrix degree, Matrix adjacency, float weight) {
if(weight != 1.0f)
return Arithmetician.scalarMultiplyResult(
Arithmetician.pairwiseSubtractResult(degree, adjacency),
weight);
else
return Arithmetician.pairwiseSubtractResult(degree, adjacency);
}
public static Matrix laplaceOperator( Matrix d ) {
int i = d.rows;
int j = d.columns;
Matrix lo = new Matrix(Matrix.NONE, i, j);
while( --i >= 0 ) {
while( --j >= 0 ) {
if(i==j)
lo.entry[i][i] = 1.0f;
else
lo.entry[i][j] = -1.0f/d.entry[i][j];
}
j = d.columns;
}
return lo;
}
public static Matrix SoftNormalizedLaplacian(Matrix degree, Matrix laplacian, float weight ) {
Matrix entryWiseRoot = Arithmetician.entrywiseSquareRootResult(degree);
Matrix entryWiseRootInverse = Arithmetician.entrywiseInversionResult(entryWiseRoot);
if(weight != 1.0f)
return Arithmetician.productResult(
Arithmetician.productResult(entryWiseRootInverse, Arithmetician.scalarMultiplyResult(laplacian, weight)),
entryWiseRoot);
else
return Arithmetician.productResult(
Arithmetician.productResult(entryWiseRootInverse, laplacian),
entryWiseRoot);
}
public static Matrix HardNormalizedLaplacian(Matrix degree, Matrix laplacian, float weight ) {
Matrix[] rootAndInverse = Arithmetician.squareRootInverseSquareRootResult(degree);
if(weight != 1.0f)
return Arithmetician.productResult(
Arithmetician.productResult(rootAndInverse[1], Arithmetician.scalarMultiplyResult(laplacian, weight)),
rootAndInverse[0]);
else
return Arithmetician.productResult(
Arithmetician.productResult(rootAndInverse[1], laplacian),
rootAndInverse[0]);
}
public static Matrix eigenvectors( Matrix m ) {
Arithmetician.PowerIterationDeflate(m, m.shortest, 0.000000001, 0 );
Matrix e = new Matrix(m.eigenvector);
System.arraycopy(m.eigenvalue, 0, e.eigenvalue, 0, m.eigenvalue.length);
return e;
}
public static void show_v (float[] v) {
int i = v.length;
while(--i >= 0)
System.out.print(v[i] + " ");
System.out.println();
}
public static Matrix commuteTime( Graph g ) {
Matrix nl = g.matrix[Graph.MatrixTypeIndex.SOFTNORMALIZEDLAPLACIAN];
Matrix d = Arithmetician.entrywiseSquareRootResult(g.matrix[Graph.MatrixTypeIndex.DEGREE]);
Matrix eigns = eigenvectors(nl);
Matrix ct = new Matrix(Matrix.NONE, d.rows, d.columns);
float vol = g.volume;
int k = nl.shortest;
while(--k >= 0 ) {
int i = d.rows;
while(--i >= 0) {
int j = d.columns;
while(--j >= 0) {
float eki = eigns.entry[k][i]/d.entry[i][i];
float ekj = eigns.entry[k][j]/d.entry[j][j];
ct.entry[i][j] += vol*(eki-ekj)*(eki-ekj)/eigns.eigenvalue[k];
}
}
}
return ct;
}
public static Matrix deformedLaplacian(Matrix d, Matrix a, float deformation ) {
//I - sA + s2(D - I)
return Arithmetician.pairwiseSumResult(
Arithmetician.pairwiseSubtractResult(
new Matrix(Matrix.IDENTITY, a.rows, a.columns ),
Arithmetician.scalarMultiplyResult(a, deformation)),
Arithmetician.scalarMultiplyResult(
Arithmetician.pairwiseSubtractResult(d, new Matrix(Matrix.IDENTITY, d.rows, d.columns)),
deformation*deformation));
}
public static Matrix projectionMatrix( int rows, int columns ) {
float ns = (float)Math.sqrt(rows*columns);
float diag = (ns-1.0f)/ns;
float nondiag = -1.0f/ns;
int i = rows;
int j = columns;
Matrix pm = new Matrix(Matrix.NONE, i, j);
while( --i >= 0 ) {
while( --j >= 0 ) {
if(i==j)
pm.entry[i][i] = diag;
else
pm.entry[i][j] = nondiag;
}
j = columns;
}
return pm;
}
public static Matrix projectedMatrix(Matrix embeddingMetric, float projectionCoefficient ) { // 0.5f
// p = 0.5PEP
return Arithmetician.productResult(
Arithmetician.scalarMultiplyResult(projectionMatrix(embeddingMetric.rows, embeddingMetric.columns), projectionCoefficient),
Arithmetician.productResult( embeddingMetric, projectionMatrix(embeddingMetric.rows, embeddingMetric.columns)));
}
public static Matrix RPaugmentedDegreeMatrix(Matrix d, Matrix mindistance) {
Matrix mindistanceRoot = Arithmetician.entrywiseSquareRootResult(mindistance);
int i = d.rows;
int j = d.columns;
Matrix augd = new Matrix(Matrix.NONE, i, j);
while( --i >= 0 ) {
while( --j >= 0 ) {
if(i==j)
augd.entry[i][i] = d.entry[i][i];
else if ((1 << (int)(mindistanceRoot.entry[i][j])) != 0.0f )
augd.entry[i][j] = d.entry[j][j] / (1 << (int)(mindistanceRoot.entry[i][j])) ;
}
j = d.columns;
}
return augd;
}
public static Matrix maximumDistanceMatrix(Matrix connectivityMetric) {
return Arithmetician.FloydWarshall(connectivityMetric, 1.0f, 50.0f, connectivityMetric.shortest*4.0f*50.0f, 1, Arithmetician.MAX );
}
}
import java.util.Arrays;
public final class Arithmetician {
public static final int MIN = 0;
public static final int MAX = 1;
public int parametrization = (2*3*10*18*9*32);
public class MatrixOperation {
public static final int UNARY = 0;
public static final int SCALAR = 1;
public static final int BINARY = 2;
public static final int MOD = 3;
public class MatrixBinary {
public static final int PAIRWISESUM = 0;
public static final int PAIRWISESUBTRACT = 1;
public static final int HADARMARDPRODUCT = 2;
public static final int PRODUCTPROPAGATED = 3;
public static final int PRODUCT = 4;
public static final int HADAMARDDIVISION = 5;
public static final int AND = 6;
public static final int OR = 7;
public static final int XOR = 8;
public static final int KOR = 9;
public static final int FROBENIUSINNERPRODUCT = 10;
public static final int BINARY_FIELD_COUNT = 11;
}
public class MatrixUnary {
public static final int ENTRYWISEINVERSION = 1;
public static final int EXPONENTIALTRACE = 2;
public static final int SQUAREROOTINVERSESQUAREROOT = 3;
public static final int SOFTSQUAREROOT = 4;
public static final int ENTRYWISENATURALLOG = 5;
public static final int RANDOMFILL = 6;
public static final int L0NORMALIZE = 7;
public static final int L1NORMALIZE = 8;
public static final int L2NORMALIZE = 9;
public static final int LINFNORMALIZE = 10;
public static final int FLOYDWARSHALL = 11;
public static final int POWERITERATIONDEFLATE = 12;
public static final int LUDOLITTLEDECOMPOSITION = 13;
public static final int DETERMINANT = 14;
public static final int INVERSE = 15;
public static final int NOT = 16;
public static final int COMPLEMENT = 17;
public static final int UNARY_FIELD_COUNT = 18;
}
public class MatrixScalar {
public static final int SCALARADD = 0;
public static final int SCALARSUBTRACT = 1;
public static final int SCALARMULTIPLY = 2;
public static final int SCALARDIVIDE = 3;
public static final int HADAMARDPOWER = 4;
public static final int FASTPROPAGATEDMULTIPRODUCT = 5;
public static final int FASTMULTIPRODUCT = 6;
public static final int ENTRYWISEMAPTORANGE = 7;
public static final int THRESHOLD = 8;
}
public class Mod {
public static final int UNARY = 0;
public static final int SCALAR = 1;
public static final int BINARY = 2;
public class MatrixBinary {
public static final int PAIRWISESUM = 0;
public static final int PAIRWISESUBTRACT = 1;
public static final int HADARMARDPRODUCT = 2;
public static final int PRODUCTPROPAGATED = 3;
public static final int PRODUCT = 4;
public static final int HADAMARDDIVISION = 5;
public static final int AND = 6;
public static final int OR = 7;
public static final int XOR = 8;
public static final int KOR = 9;
}
public class MatrixUnary {
public static final int FROBENIUSINNERPRODUCT = 0;
public static final int ENTRYWISEINVERSION = 1;
public static final int EXPONENTIALTRACE = 2;
public static final int SQUAREROOTINVERSESQUAREROOT = 3;
public static final int SOFTSQUAREROOT = 4;
public static final int ENTRYWISENATURALLOG = 5;
public static final int RANDOMFILL = 6;
public static final int L0NORMALIZE = 7;
public static final int L1NORMALIZE = 8;
public static final int L2NORMALIZE = 9;
public static final int LINFNORMALIZE = 10;
public static final int FLOYDWARSHALL = 11;
public static final int POWERITERATIONDEFLATE = 12;
public static final int LUDOLITTLEDECOMPOSITION = 13;
public static final int DETERMINANT = 14;
public static final int INVERSE = 15;
public static final int NOT = 16;
public static final int COMPLEMENT = 17;
}
public class MatrixScalar {
public static final int SCALARADD = 0;
public static final int SCALARSUBTRACT = 1;
public static final int SCALARMULTIPLY = 2;
public static final int SCALARDIVIDE = 3;
public static final int HADAMARDPOWER = 4;
public static final int FASTPROPAGATEDMULTIPRODUCT = 5;
public static final int FASTMULTIPRODUCT = 6;
public static final int ENTRYWISEMAPTORANGE = 7;
public static final int THRESHOLD = 8;
}
}
}
public static void vectorScalarAdd( float[] v, float add ) {
int i = v.length;
while(--i >= 0)
v[i]+=add;
}
public static Matrix ApplyScalar( int opNum, Matrix m, float[] threeArgs) {
switch(opNum) {
case(MatrixOperation.MatrixScalar.SCALARADD):
return scalarAddResult(m, threeArgs[0]);
case(MatrixOperation.MatrixScalar.SCALARSUBTRACT):
return scalarSubtractResult(m, threeArgs[0]);
case(MatrixOperation.MatrixScalar.SCALARMULTIPLY):
return scalarMultiplyResult(m, threeArgs[0]);
case(MatrixOperation.MatrixScalar.SCALARDIVIDE):
return scalarDivideResult(m, threeArgs[0]);
case(MatrixOperation.MatrixScalar.HADAMARDPOWER):
return hadamardPowerResult(m, (int)threeArgs[0]);
case(MatrixOperation.MatrixScalar.FASTPROPAGATEDMULTIPRODUCT):
fastPropagatedMultiproduct(m, (int)threeArgs[0]);
return m;
case(MatrixOperation.MatrixScalar.FASTMULTIPRODUCT):
return fastMultiproduct(m, (int)threeArgs[0]);
case(MatrixOperation.MatrixScalar.ENTRYWISEMAPTORANGE):
return scaleToRangeResult(m, threeArgs[0], threeArgs[1]);
case(MatrixOperation.MatrixScalar.THRESHOLD):
return thresholdResult(m, threeArgs[0], (int)threeArgs[1]);
default:
return new Matrix(m);
}
}
public static Matrix ApplyModScalar( int opNum, Matrix m, float[] threeArgs) {
switch(opNum) {
case(MatrixOperation.MatrixScalar.SCALARADD):
return ModscalarAddResult(m, threeArgs[0], threeArgs[2]);
case(MatrixOperation.MatrixScalar.SCALARSUBTRACT):
return ModscalarSubtractResult(m, threeArgs[0], threeArgs[2]);
case(MatrixOperation.MatrixScalar.SCALARMULTIPLY):
return ModscalarMultiplyResult(m, threeArgs[0], threeArgs[2]);
case(MatrixOperation.MatrixScalar.SCALARDIVIDE):
return ModscalarDivideResult(m, threeArgs[0], threeArgs[2]);
case(MatrixOperation.MatrixScalar.HADAMARDPOWER):
return ModhadamardPowerResult(m, (int)threeArgs[0], threeArgs[2]);
case(MatrixOperation.MatrixScalar.FASTPROPAGATEDMULTIPRODUCT):
ModfastPropagatedMultiproduct(m, (int)threeArgs[0], threeArgs[2]);
return m;
case(MatrixOperation.MatrixScalar.FASTMULTIPRODUCT):
return ModfastMultiproduct(m, (int)threeArgs[0], threeArgs[2]);
case(MatrixOperation.MatrixScalar.ENTRYWISEMAPTORANGE):
return ModscaleToRangeResult(m, threeArgs[0], threeArgs[1], threeArgs[2]);
case(MatrixOperation.MatrixScalar.THRESHOLD):
return ModthresholdResult(m, threeArgs[0], (int)threeArgs[1], threeArgs[2]);
default:
return new Matrix(m);
}
}
public static Matrix ApplyUnary( int opNum, Matrix m, float[] threeArgs, int[] zeroOne) {
switch(opNum) {
case(MatrixOperation.MatrixUnary.ENTRYWISEINVERSION):
return entrywiseInversionResult(m);
case(MatrixOperation.MatrixUnary.EXPONENTIALTRACE):
float result = exponentialTrace(m);
return scalarMultiplyResult(m,result);
case(MatrixOperation.MatrixUnary.SQUAREROOTINVERSESQUAREROOT):
return squareRootInverseSquareRootResult(m)[0];
case(MatrixOperation.MatrixUnary.SOFTSQUAREROOT):
return entrywiseSquareRootResult(m);
case(MatrixOperation.MatrixUnary.ENTRYWISENATURALLOG):
return entrywiseLogarithmResult(m);
case(MatrixOperation.MatrixUnary.RANDOMFILL):
fill_random(m);
return m;
case(MatrixOperation.MatrixUnary.L0NORMALIZE):
L0normalize(m);
return m;
case(MatrixOperation.MatrixUnary.L1NORMALIZE):
L1normalize(m);
return m;
case(MatrixOperation.MatrixUnary.L2NORMALIZE):
L2normalize(m);
return m;
case(MatrixOperation.MatrixUnary.LINFNORMALIZE):
Linfnormalize(m);
return m;
case(MatrixOperation.MatrixUnary.FLOYDWARSHALL):
return FloydWarshall(m, 0.00000001f, threeArgs[0], threeArgs[1], zeroOne[0], zeroOne[1]);
case(MatrixOperation.MatrixUnary.POWERITERATIONDEFLATE):
m.eigenvalue = new float[m.rows];
m.eigenvector = new float[m.rows][m.columns];
PowerIterationDeflate(m, m.shortest, (double)0.00000001f, 1); // 1 populates krylov subspace
return new Matrix(m.eigenvector);
case(MatrixOperation.MatrixUnary.LUDOLITTLEDECOMPOSITION):
return LU_Dolittle_DecompositionResult(m);
case(MatrixOperation.MatrixUnary.DETERMINANT):
result = Determinant(m);
return scalarMultiplyResult(m,result);
case(MatrixOperation.MatrixUnary.INVERSE):
return Inverse(m);
case(MatrixOperation.MatrixUnary.NOT):
return NOTResult(m);
case(MatrixOperation.MatrixUnary.COMPLEMENT):
return complement(m);
default:
return new Matrix(m);
}
}
public static Matrix ApplyModUnary( int opNum, Matrix m, float[] threeArgs, int[] zeroOne) {
switch(opNum) {
case(MatrixOperation.MatrixUnary.ENTRYWISEINVERSION):
return ModentrywiseInversionResult(m, threeArgs[2]);
case(MatrixOperation.MatrixUnary.EXPONENTIALTRACE):
float result = ModexponentialTrace(m, threeArgs[2]);
return ModscalarMultiplyResult(m, result, threeArgs[2]);
case(MatrixOperation.MatrixUnary.SQUAREROOTINVERSESQUAREROOT):
return ModsquareRootInverseSquareRootResult(m, threeArgs[2])[0];
case(MatrixOperation.MatrixUnary.SOFTSQUAREROOT):
return ModentrywiseSquareRootResult(m, threeArgs[2]);
case(MatrixOperation.MatrixUnary.ENTRYWISENATURALLOG):
return ModentrywiseLogarithmResult(m, threeArgs[2]);
case(MatrixOperation.MatrixUnary.RANDOMFILL):
Modfill_random(m, threeArgs[2]);
return m;
case(MatrixOperation.MatrixUnary.L0NORMALIZE):
ModL0normalize(m, threeArgs[2]);
return m;
case(MatrixOperation.MatrixUnary.L1NORMALIZE):
ModL1normalize(m, threeArgs[2]);
return m;
case(MatrixOperation.MatrixUnary.L2NORMALIZE):
ModL2normalize(m, threeArgs[2]);
return m;
case(MatrixOperation.MatrixUnary.LINFNORMALIZE):
ModLinfnormalize(m, threeArgs[2]);
return m;
case(MatrixOperation.MatrixUnary.FLOYDWARSHALL):
return ModFloydWarshall(m, 0.00000001f, threeArgs[0], threeArgs[1], zeroOne[0], zeroOne[1], threeArgs[2]);
case(MatrixOperation.MatrixUnary.POWERITERATIONDEFLATE):
ModPowerIterationDeflate(m, m.shortest, (double)0.00000001f, 1, threeArgs[2]); // 1 populates krylov subspace
return new Matrix(m.eigenvector);
case(MatrixOperation.MatrixUnary.LUDOLITTLEDECOMPOSITION):
return ModLU_Dolittle_DecompositionResult(m, threeArgs[2]);
case(MatrixOperation.MatrixUnary.DETERMINANT):
result = ModDeterminant(m, threeArgs[2]);
return ModscalarMultiplyResult(m,result, threeArgs[2]);
case(MatrixOperation.MatrixUnary.INVERSE):
return ModInverse(m, threeArgs[2]);
case(MatrixOperation.MatrixUnary.NOT):
return ModNOTResult(m, threeArgs[2]);
case(MatrixOperation.MatrixUnary.COMPLEMENT):
return complement(m);
default:
return new Matrix(m);
}
}
public static Matrix ApplyBinary( int opNum, Matrix m, Matrix m2, float[] threeArgs) {
switch(opNum) {
case(MatrixOperation.MatrixBinary.FROBENIUSINNERPRODUCT):
float result = FrobeniusInnerProduct(m, m2);
return scalarMultiplyResult(m,result);
case(MatrixOperation.MatrixBinary.PAIRWISESUM):
return pairwiseSumResult(m, m2);
case(MatrixOperation.MatrixBinary.PAIRWISESUBTRACT):
return pairwiseSubtractResult(m, m2);
case(MatrixOperation.MatrixBinary.HADARMARDPRODUCT):
return hadamardProductResult(m, m2);
case(MatrixOperation.MatrixBinary.PRODUCTPROPAGATED):
productPropagated(m, m2);
return m;
case(MatrixOperation.MatrixBinary.PRODUCT):
return productResult(m, m2);
case(MatrixOperation.MatrixBinary.HADAMARDDIVISION):
return hadamardDivisionResult(m, m2);
case(MatrixOperation.MatrixBinary.AND):
return ANDResult(m, m2);
case(MatrixOperation.MatrixBinary.OR):
return ORResult(m, m2);
case(MatrixOperation.MatrixBinary.XOR):
return XORResult(m, m2);
case(MatrixOperation.MatrixBinary.KOR):
return KORResult(m, m2);
default:
return new Matrix(m);
}
}
//Addition
public static Matrix ApplyModBinary( int opNum, Matrix m, Matrix m2, float[] threeArgs) {
switch(opNum) {
case(MatrixOperation.MatrixBinary.FROBENIUSINNERPRODUCT):
float result = ModFrobeniusInnerProduct(m, m2, threeArgs[2]);
return ModscalarMultiplyResult(m,result, threeArgs[2]);
case(MatrixOperation.MatrixBinary.PAIRWISESUM):
return ModpairwiseSumResult(m, m2, threeArgs[2]);
case(MatrixOperation.MatrixBinary.PAIRWISESUBTRACT):
return ModpairwiseSubtractResult(m, m2, threeArgs[2]);
case(MatrixOperation.MatrixBinary.HADARMARDPRODUCT):
return ModhadamardProductResult(m, m2, threeArgs[2]);
case(MatrixOperation.MatrixBinary.PRODUCTPROPAGATED):
ModproductPropagated(m, m2, threeArgs[2]);
return m;
case(MatrixOperation.MatrixBinary.PRODUCT):
return ModproductResult(m, m2, threeArgs[2]);
case(MatrixOperation.MatrixBinary.HADAMARDDIVISION):
return ModhadamardDivisionResult(m, m2, threeArgs[2]);
case(MatrixOperation.MatrixBinary.AND):
return ModANDResult(m, m2, threeArgs[2]);
case(MatrixOperation.MatrixBinary.OR):
return ModORResult(m, m2, threeArgs[2]);
case(MatrixOperation.MatrixBinary.XOR):
return ModXORResult(m, m2, threeArgs[2]);
case(MatrixOperation.MatrixBinary.KOR):
return ModKORResult(m, m2, threeArgs[2]);
default:
return new Matrix(m);
}
}
public static void scalarAdd(Matrix accumulator, float addend) {
if(addend == Matrix.ZEROF) {
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int shortestColumn = accumulator.columns;
int i = accumulator.rows;
int j = shortestColumn;
while(--i >= 0) {
while(--j >= 0)
accumulator.entry[i][j] += addend;
}
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static void scalarAdd(Matrix accumulator, float addend, int row) {
if(addend == Matrix.ZEROF) {
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int shortestColumn = accumulator.columns;
int i = row;
int j = shortestColumn;
while(--j >= 0)
accumulator.entry[i][j] += addend;
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix scalarAddResult(Matrix adder, float addend) {
Matrix result;
if(addend == Matrix.ZEROF) {
result = new Matrix(adder);
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
int shortestRow = adder.rows;
int shortestColumn = adder.columns;
result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
result.entry[i][j] = adder.entry[i][j] + addend;
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
public static void pairwiseSum(Matrix accumulator, Matrix summand) {
int shortestRow = accumulator.rows < summand.rows ? accumulator.rows : summand.rows;
int shortestColumn = accumulator.columns < summand.columns ? accumulator.columns : summand.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
accumulator.entry[i][j] += summand.entry[i][j];
}
}
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix pairwiseSumResult(Matrix adder, Matrix summand) {
int shortestRow = adder.rows < summand.rows ? adder.rows : summand.rows;
int shortestColumn = adder.columns < summand.columns ? adder.columns : summand.columns;
Matrix result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
result.entry[i][j] = adder.entry[i][j] + summand.entry[i][j];
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
// Subtraction
public static void scalarSubtract(Matrix accumulator, float subtractand) {
if(subtractand == Matrix.ZEROF) {
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int shortestRow = accumulator.rows;
int shortestColumn = accumulator.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
accumulator.entry[i][j] -= subtractand;
}
}
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static void scalarSubtract(Matrix accumulator, float subtractand, int row) {
if(subtractand == Matrix.ZEROF) {
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int shortestColumn = accumulator.columns;
int i = row;
int j = shortestColumn;
while(--j >= 0)
accumulator.entry[i][j] -= subtractand;
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix scalarSubtractResult(Matrix subtractor, float subtractand) {
Matrix result;
if(subtractand == Matrix.ZEROF) {
result = new Matrix(subtractor);
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
int shortestRow = subtractor.rows;
int shortestColumn = subtractor.columns;
result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
result.entry[i][j] = subtractor.entry[i][j] - subtractand;
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
public static void pairwiseSubtract(Matrix accumulator, Matrix subtractand) {
int shortestRow = accumulator.rows < subtractand.rows ? accumulator.rows : subtractand.rows;
int shortestColumn = accumulator.columns < subtractand.columns ? accumulator.columns : subtractand.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
accumulator.entry[i][j] -= subtractand.entry[i][j];
}
}
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix pairwiseSubtractResult(Matrix subtractor, Matrix subtractand) {
int shortestRow = subtractor.rows < subtractand.rows ? subtractor.rows : subtractand.rows;
int shortestColumn = subtractor.columns < subtractand.columns ? subtractor.columns : subtractand.columns;
Matrix result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
result.entry[i][j] = subtractor.entry[i][j] - subtractand.entry[i][j];
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
// Multiplication
public static void scalarMultiply(Matrix accumulator, float multiplier) {
int shortestRow = accumulator.rows;
int shortestColumn = accumulator.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
accumulator.entry[i][j] *= multiplier;
}
}
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static void scalarMultiply(Matrix accumulator, float multiplier, int row) {
int shortestColumn = accumulator.columns;
int i = row;
int j = shortestColumn;
while(--j >= 0)
accumulator.entry[i][j] *= multiplier;
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix scalarMultiplyResult(Matrix multiplicand, float multiplier) {
int shortestRow = multiplicand.rows;
int shortestColumn = multiplicand.columns;
Matrix result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
result.entry[i][j] = multiplicand.entry[i][j] * multiplier;
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
public static float FrobeniusInnerProduct( Matrix multiplicand, Matrix multiplier ) {
int shortestRow = multiplicand.rows < multiplier.rows ? multiplicand.rows : multiplier.rows;
int shortestColumn = multiplicand.columns < multiplier.columns ? multiplicand.columns : multiplier.columns;
int i = shortestRow;
float accumulator = 0.0f;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
accumulator += multiplicand.entry[i][j]*multiplier.entry[i][j];
}
}
return accumulator;
}
public static void hadamardProduct(Matrix accumulator, Matrix multiplicand) {
int shortestRow = accumulator.rows < multiplicand.rows ? accumulator.rows : multiplicand.rows;
int shortestColumn = accumulator.columns < multiplicand.columns ? accumulator.columns : multiplicand.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
accumulator.entry[i][j] *= multiplicand.entry[i][j];
}
}
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix hadamardProductResult(Matrix multiplier, Matrix multiplicand) {
int shortestRow = multiplier.rows < multiplicand.rows ? multiplier.rows : multiplicand.rows;
int shortestColumn = multiplier.columns < multiplicand.columns ? multiplier.columns : multiplicand.columns;
Matrix result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
result.entry[i][j] = multiplier.entry[i][j] * multiplicand.entry[i][j];
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
public static void productPropagated(Matrix accumulator, Matrix multiplier) {
int shortestRow = accumulator.rows < multiplier.rows ? accumulator.rows : multiplier.rows;
int shortestColumn = accumulator.columns < multiplier.columns ? accumulator.columns : multiplier.columns;
int shortest = shortestRow < shortestColumn ? shortestRow : shortestColumn;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
int k = shortest;
float entrySum = 0.0f;
while(--k >= 0) {
entrySum += accumulator.entry[i][k]*multiplier.entry[k][j];
}
accumulator.entry[i][j] = entrySum;
}
}
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix productResult(Matrix multiplicand, Matrix multiplier) {
int shortest = multiplicand.columns < multiplier.rows ? multiplicand.columns : multiplier.rows;
int i = multiplicand.rows;
int j = multiplier.columns;
Matrix result = new Matrix(Matrix.NONE, i, j);
while(--i >= 0) {
j = multiplier.columns;
while(--j >= 0) {
int k = shortest;
float entrySum = 0.0f;
while(--k >= 0) {
entrySum += multiplicand.entry[i][k]*multiplier.entry[k][j];
}
result.entry[i][j] = entrySum;
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
// Division
public static void entrywiseInversion( Matrix divisor ) {
int shortestRow = divisor.rows;
int shortestColumn = divisor.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
float divisorij = divisor.entry[i][j];
if(divisorij != Matrix.ZEROF)
divisor.entry[i][j] = Matrix.IDENTITYF / divisorij;
else
divisor.entry[i][j] = Matrix.IDENTITYF;
}
}
}
public static Matrix entrywiseInversionResult ( Matrix divisor ) {
int shortestRow = divisor.rows;
int shortestColumn = divisor.columns;
Matrix result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
float divisorij = divisor.entry[i][j];
if(divisorij != Matrix.ZEROF)
result.entry[i][j] = Matrix.IDENTITYF / divisorij;
else
result.entry[i][j] = Matrix.IDENTITYF;
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
public static void scalarDivide(Matrix accumulator, float divisor) {
int shortestRow = accumulator.rows;
int shortestColumn = accumulator.columns;
if(divisor == Matrix.ZEROF) {
Arrays.fill(accumulator.entry, Matrix.IDENTITYF);
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0)
accumulator.entry[i][j] /= divisor;
}
}
public static Matrix scalarDivideResult(Matrix dividend, float divisor) {
int shortestRow = dividend.rows;
int shortestColumn = dividend.columns;
Matrix result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
if(divisor != Matrix.ZEROF)
result.entry[i][j] = dividend.entry[i][j] / divisor;
else
result.entry[i][j] = Matrix.IDENTITYF;
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
public static void hadamardDivision(Matrix accumulator, Matrix divisor) {
int shortestRow = accumulator.rows < divisor.rows ? accumulator.rows : divisor.rows;
int shortestColumn = accumulator.columns < divisor.columns ? accumulator.columns : divisor.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
if(divisor.entry[i][j] != Matrix.ZEROF)
accumulator.entry[i][j] /= divisor.entry[i][j];
else
accumulator.entry[i][j] = Matrix.ZEROF;
}
}
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix hadamardDivisionResult(Matrix dividend, Matrix divisor) {
int shortestRow = dividend.rows < divisor.rows ? dividend.rows : divisor.rows;
int shortestColumn = dividend.columns < divisor.columns ? dividend.columns : divisor.columns;
Matrix result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
if(divisor.entry[i][j] != Matrix.ZEROF)
result.entry[i][j] = dividend.entry[i][j] / divisor.entry[i][j];
else
result.entry[i][j] = Matrix.IDENTITYF;
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
// Powers
public static void hadamardPower(Matrix accumulator, int power) {
int shortestRow = accumulator.rows;
int shortestColumn = accumulator.columns;
if(power == 0) {
accumulator.make_ones();
return;
}
if(power == 1)
return;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
int p = power;
while(--p > 0)
accumulator.entry[i][j] *= accumulator.entry[i][j];
}
}
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix hadamardPowerResult(Matrix multiplier, int power) {
int shortestRow = multiplier.rows;
int shortestColumn = multiplier.columns;
if(power == 1)
return new Matrix(multiplier);
Matrix result = new Matrix(Matrix.ONES, shortestRow, shortestColumn);
if(power == 0)
return result;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
int p = power;
while(--p >= 0)
result.entry[i][j] *= multiplier.entry[i][j];
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
public static int[] radix(int num, int base) {
int b = 1; int b1 = base;
int rem = 0; int rem1 = num % b1;
int bit = 0;
int[] bits = new int[10];
while(b <= num) {
bits[bit] = (rem1 - rem)/b;
b=b1;b1*=base;
rem=rem1; rem1 = num % b1;
bit++;
if(bit >= bits.length) {
int[] temp = new int[bit<<1];
System.arraycopy(temp, 0, bits, 0, bit);
bits = temp;
}
}
return bits;
}
public static float exponentialTrace( Matrix m ) {
float result = 1.0f;
float trace = m.trace();
int itrace = (int)trace;
float diff = trace - itrace;
int[] bits = radix(itrace, 2);
int iteration = 0;
float lastPow = 2.71828183f;
int lastPowIndex = 0;
while(++iteration < bits.length) {
int bit = bits[iteration];
if(bit == 1) {
int squaresRequired = iteration - lastPowIndex;
while(--squaresRequired >= 0)
lastPow *= lastPow;
result *= lastPow;
}
}
float extra = -(float)Math.log(diff);
if(extra != 0.0f)
result *= extra;
return result;
}
public static void polysquarePropagated(Matrix base, int times) {
while(--times >= 0)
productPropagated(base, base);
}
public static void fastPropagatedMultiproduct(Matrix base, int exponent) {
int[] operations = radix(exponent, 2);
int lastProductIndex = 0, jmax = operations.length;
Matrix partialPowers;
if(operations[0] == 0)
partialPowers = new Matrix(Matrix.IDENTITY, base.rows, base.columns);
else
partialPowers = new Matrix(base);
for(int j = 1; j < jmax;j++) {
int bit = operations[j];
if(bit == 1) {
polysquarePropagated(partialPowers, j-lastProductIndex);
lastProductIndex = j;
productPropagated(base, partialPowers);
}
}
}
public static Matrix polysquare(Matrix base, int times) {
while(--times >= 0)
base = productResult(base, base);
return base;
}
public static Matrix fastMultiproduct(Matrix base, int exponent) {
int[] operations = radix(exponent, 2);
int lastProductIndex = 0, jmax = operations.length;
Matrix partialPowers;
if(operations[0] == 0)
partialPowers = new Matrix(Matrix.IDENTITY, base.rows, base.columns);
else
partialPowers = new Matrix(base);
for(int j = 1; j < jmax;j++) {
int bit = operations[j];
if(bit == 1) {
polysquare(partialPowers, j-lastProductIndex);
lastProductIndex = j;
base = productResult(base, partialPowers);
}
}
return base;
}
public static Matrix squareRootReturnInverseSquareRoot(Matrix y) {
Matrix z = new Matrix(Matrix.IDENTITY, y.rows, y.columns);
int j = (int)Math.sqrt(y.rows) + 1;
while(--j >= 0) {
scalarMultiply(pairwiseSumResult(y,Inverse(z)), 0.5f);
scalarMultiply(pairwiseSumResult(z,Inverse(y)), 0.5f);
}
y.updates &= (Matrix.all_changed^Matrix.entry_changed);
z.updates &= (Matrix.all_changed^Matrix.entry_changed);
return z;
}
public static Matrix[] squareRootInverseSquareRootResult(Matrix x) {
Matrix y = new Matrix(x);
Matrix z = new Matrix(Matrix.IDENTITY, y.rows, y.columns);
int j = (int)Math.sqrt(y.rows) + 1;
while(--j >= 0) {
scalarMultiply(pairwiseSumResult(y,Inverse(z)), 0.5f);
scalarMultiply(pairwiseSumResult(z,Inverse(y)), 0.5f);
}
y.updates &= (Matrix.all_changed^Matrix.entry_changed);
z.updates &= (Matrix.all_changed^Matrix.entry_changed);
return new Matrix[] { y, z };
}
public static void entrywiseSquareRoot(Matrix x) {
int shortestRow = x.rows;
int shortestColumn = x.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
float xij = x.entry[i][j];
float sign;
if(xij != 0.0f)
sign = xij/Math.abs(xij);
else
sign = 1.0f;
x.entry[i][j] = (float)( sign*Math.sqrt(Math.abs(xij)) );
}
}
x.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix entrywiseSquareRootResult(Matrix x) {
int shortestRow = x.rows;
int shortestColumn = x.columns;
int i = shortestRow;
Matrix result = new Matrix(Matrix.NONE, x.rows, x.columns);
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
float xij = x.entry[i][j];
float sign;
if(xij != 0.0f)
sign = xij/Math.abs(xij);
else
sign = 1.0f;
result.entry[i][j] = (float)( sign*Math.sqrt(Math.abs(xij)) );
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
// Logarithm
public static void entrywiseLogarithm( Matrix m ) {
int shortestRow = m.rows;
int shortestColumn = m.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
float eij = m.entry[i][j];
float sign;
if(eij != 0.0f)
sign = eij/Math.abs(eij);
else
sign = 1.0f;
m.entry[i][j] = (float)(sign*Math.log(eij));
}
}
m.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix entrywiseLogarithmResult( Matrix m ) {
int shortestRow = m.rows;
int shortestColumn = m.columns;
int i = shortestRow;
Matrix result = new Matrix(m);
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
float xij = m.entry[i][j];
float sign;
if(xij != 0.0f)
sign = xij/Math.abs(xij);
else
sign = 1.0f;
result.entry[i][j] = (float)(sign*Math.log(xij));
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
// Mapping
public static void scaleToRange(Matrix m, float low, float high) {
float[] minmax = m.minmax();
float newrange = high-low;
float oldrange = minmax[1]-minmax[0];
float range = oldrange == 0.0f ? 1.0f : newrange/oldrange;
scalarSubtract(m, minmax[0]);
scalarMultiply(m, range );
scalarAdd(m, low );
}
public static void scaleToRangeRows(Matrix m, float low, float high) {
int i = m.rows;
while(--i >= 0) {
float[] minmax = m.minmaxRow(i);
float newrange = high-low;
float oldrange = minmax[1]-minmax[0];
float range = oldrange == 0.0f ? 1.0f : newrange/oldrange;
scalarSubtract(m, minmax[0], i);
scalarMultiply(m, range, i );
scalarAdd(m, low, i );
}
}
public static void scaleToRangeRow(Matrix m, int row, float low, float high) {
int i = row;
float[] minmax = m.minmaxRow(i);
float newrange = high-low;
float oldrange = minmax[1]-minmax[0];
float range = oldrange == 0.0f ? 1.0f : newrange/oldrange;
scalarSubtract(m, minmax[0], i);
scalarMultiply(m, range, i );
scalarAdd(m, low, i );
}
public static Matrix scaleToRangeResult(Matrix m, float low, float high) {
float[] minmax = m.minmax();
float newrange = high-low;
float oldrange = minmax[1]-minmax[0];
float range = oldrange == 0.0f ? 1.0f : newrange/oldrange;
Matrix result = new Matrix(Matrix.NONE, m.rows, m.columns);
result = scalarSubtractResult(m, minmax[0]);
scalarMultiply(result, range );
scalarAdd(result, low );
return result;
}
// Random
public static void fill_random(Matrix m) {
int i = m.rows;
while(--i >= 0 ) {
int j = m.columns;
while(--j >= 0 )
m.entry[i][j] = (float)Math.random();
}
}
public static void fill_random( float[] v) {
int j = v.length;
while(--j >= 0 ) v[j] = (float)Math.random();
}
// Norms & normalization vectors and matrices : 0, 1, 2, inf
public static void Linfnormalize( Matrix m ) {
int i = m.rows;
int j = m.columns;
if( i == 0 || j == 0)
return;
float max = Math.abs(m.entry[0][0]);
while( --i >= 0 ) {
while( --j >= 0 ) {
float eij = Math.abs(m.entry[i][j]);
if(eij > max)
max = eij;
}
j = m.columns;
}
i = m.rows;
if(max != 0.0f) {
while( --i >= 0 ) {
j = m.columns;
while( --j >= 0 ) {
m.entry[i][j] /= max;
}
}
}
}
public static void Linfnormalize( float[] v ) {
int j = v.length;
if(j == 0)
return;
float max = Math.abs(v[0]);
while(--j > 0) {
float vj = Math.abs(v[j]);
if(vj > max)
max = vj;
}
j = v.length;
if(max == 0.0f)
return;
while(--j >= 0) v[j] /= max;
}
public static float Linfnorm( Matrix m ) {
int i = m.rows;
int j = m.columns;
if( i == 0 || j == 0)
return 0.0f;
float max = Math.abs(m.entry[0][0]);
while( --i >= 0 ) {
while( --j >= 0 ) {
float eij = Math.abs(m.entry[i][j]);
if(eij > max)
max = eij;
}
j = m.columns;
}
if(m.norms == null)
m.norms = new float[4];
m.norms[3] = max;
return max;
}
public static float Linfnorm( float[] v ) {
int j = v.length;
if(j == 0)
return 0.0f;
float max = Math.abs(v[0]);
while(--j > 0) {
float vj = Math.abs(v[j]);
if(vj > max)
max = vj;
}
return max;
}
public static void L2normalize( Matrix m ) {
int i = m.rows;
float sumSquares = 0.0f;
while( --i >= 0 ) {
int j = m.columns;
while( --j >= 0 ) {
sumSquares += m.entry[i][j]*m.entry[i][j];
}
}
sumSquares = (float)Math.sqrt(sumSquares);
i = m.rows;
if(sumSquares == 0.0f)
return;
while( --i >= 0 ) {
int j = m.columns;
while( --j >= 0 ) {
m.entry[i][j] /= sumSquares;
}
}
}
public static void L2normalize( float [] v ) {
int j = v.length;
float sumSquares = 0.0f;
while(--j >= 0) sumSquares += v[j]*v[j];
j = v.length;
sumSquares = (float)Math.sqrt(sumSquares);
if(sumSquares == 0.0f)
return;
while(--j >= 0) v[j] /= sumSquares;
}
public static float L2norm( Matrix m ) {
int i = m.rows;
float sumSquares = 0.0f;
while( --i >= 0 ) {
int j = m.columns;
while( --j >= 0 ) {
sumSquares += m.entry[i][j];
}
}
sumSquares = (float)Math.sqrt(sumSquares);
if(m.norms == null)
m.norms = new float[4];
m.norms[2] = sumSquares;
return sumSquares;
}
public static float L2norm( float [] v ) {
int j = v.length;
float sumSquares = 0.0f;
while(--j >= 0) sumSquares += v[j]*v[j];
return (float)Math.sqrt(sumSquares);
}
public static void L1normalize( Matrix m ) {
int i = m.rows;
float sum = 0.0f;
while( --i >= 0 ) {
int j = m.columns;
while( --j >= 0 ) {
sum += Math.abs(m.entry[i][j]);
}
}
i = m.rows;
if(sum == 0.0f)
return;
while( --i >= 0 ) {
int j = m.columns;
while( --j >= 0 ) {
m.entry[i][j] /= sum;
}
}
}
public static void L1normalize( float[] v ) {
int j = v.length;
float sum = 0.0f;
while(--j >= 0) sum += Math.abs(v[j]);
j = v.length;
if(sum == 0.0f)
return;
while(--j >= 0) v[j] /= sum;
}
public static float L1norm( Matrix m ) {
int i = m.rows;
float sum = 0.0f;
while( --i >= 0 ) {
int j = m.columns;
while( --j >= 0 ) {
sum += Math.abs(m.entry[i][j]);
}
}
if(m.norms == null)
m.norms = new float[4];
m.norms[1] = sum;
return sum;
}
public static float L1norm( float[] v ) {
int j = v.length;
float sum = 0.0f;
while(--j >= 0) sum += Math.abs(v[j]);
return sum;
}
public static void L0normalize( Matrix m ) {
int i = m.rows;
float sum = 0.0f;
while( --i >= 0 ) {
int j = m.columns;
while( --j >= 0 ) {
if(m.entry[i][j] != Matrix.ZEROF)
sum += 1.0f;
}
}
i = m.rows;
if(sum == 0.0f)
return;
while( --i >= 0 ) {
int j = m.columns;
while( --j >= 0 ) {
m.entry[i][j] /= sum;
}
}
}
public static void L0normalize( float[] v ) {
int j = v.length;
float sum = 0.0f;
while(--j >= 0)
if(v[j] != 0.0f)
sum += 1.0f;
j = v.length;
if(sum == 0.0f)
return;
while(--j >= 0) v[j] /= sum;
}
public static float L0norm( Matrix m ) {
int i = m.rows;
float sum = 0.0f;
while( --i >= 0 ) {
int j = m.columns;
while( --j >= 0 ) {
if(m.entry[i][j] != Matrix.ZEROF)
sum += 1.0f;
}
}
if(m.norms == null)
m.norms = new float[4];
m.norms[0] = sum;
return sum;
}
public static float L0norm( float[] v ) {
int j = v.length;
float sum = 0.0f;
while(--j >= 0)
if(v[j] != 0.0f)
sum += 1.0f;
return sum;
}
// Algorithms
public static Matrix FloydWarshall( Matrix connectivityMetric, float epsilon, float connected_bound, float disconnected_bound, int strictness, int minmax ) {
epsilon = Math.abs(epsilon);
float connected = connected_bound;
float disconnected = disconnected_bound;
int i = connectivityMetric.rows;
int maxspan = connectivityMetric.shortest;
Matrix fw = new Matrix(Matrix.NONE, i, connectivityMetric.columns);
while(--i >= 0) {
int j = connectivityMetric.columns;
int max = (minmax == MIN) ? 0 : i;
while(--j >= max ) {
float eij = connectivityMetric.entry[i][j];
if( strictness == 0 && j < maxspan && i < maxspan ) {
eij += connectivityMetric.entry[j][i];
}
if( eij != Matrix.ZEROF && eij >= -epsilon && eij <= epsilon )
fw.entry[i][j] = connected;
else
fw.entry[i][j] = disconnected;
}
}
int k = maxspan;
while( --k >= 0 ) {
i = connectivityMetric.rows;
while( --i >= 0 ) {
float current_distance_part = fw.entry[i][k];
int j = connectivityMetric.columns;
while( -- j >= 0 ) {
if(i==j)
fw.entry[i][j] = 0.0f;
else {
float current_distance = fw.entry[i][j];
float current_distance_whole;
switch(minmax) {
case(MIN):
current_distance_whole = current_distance_part + fw.entry[k][j];
fw.entry[i][j] = current_distance < current_distance_whole ? current_distance : current_distance_whole;
break;
case(MAX):
current_distance_whole = current_distance_part < fw.entry[k][j] ? current_distance_part : fw.entry[k][j];
fw.entry[i][j] = current_distance > current_distance_whole ? current_distance : current_distance_whole;
break;
}
}
}
}
}
i = connectivityMetric.rows;
while( --i >= 0 ) {
int j = connectivityMetric.columns;
while( --j >= 0 )
fw.entry[i][j] *= fw.entry[i][j];
}
return fw;
}
public static void PowerIterationDeflate(Matrix m, int eigens_to_compute, double epsilons, int populateKrylovSubspace ) {
int iteration = 0, i = -1;
int maxIteration = m.shortest;
m.krylovs = new float[populateKrylovSubspace][m.columns];
while(++i < eigens_to_compute ) {
Matrix next_eigen_approximation, current_eigen_approximation = new Matrix(Matrix.NONE, 1, m.columns );
double prev, current = epsilons; float eigenvalue_approximation;
fill_random( current_eigen_approximation );
L2normalize( current_eigen_approximation );
int iIteration = 0;
do {
prev = current;
next_eigen_approximation = new Matrix(current_eigen_approximation);
current_eigen_approximation = productResult(m, next_eigen_approximation.transpose()).transpose();
if(iteration<populateKrylovSubspace)
System.arraycopy(current_eigen_approximation.entry[0],0,m.krylovs[iteration++],0,m.columns);
eigenvalue_approximation = FrobeniusInnerProduct(next_eigen_approximation, current_eigen_approximation);
L2normalize(current_eigen_approximation);
current = FrobeniusInnerProduct(next_eigen_approximation,current_eigen_approximation);
} while( (current < (1-epsilons) && Math.abs( current/prev ) > (1 + epsilons)) && iIteration++ < maxIteration );
m.eigenvalue[i] = eigenvalue_approximation;
Deflate(m, current_eigen_approximation, eigenvalue_approximation );
scalarMultiply(current_eigen_approximation, (float)Math.sqrt(Math.abs(eigenvalue_approximation)));
int shortest = current_eigen_approximation.entry[0].length < m.eigenvector[i].length ? current_eigen_approximation.entry[0].length : m.eigenvector[i].length;
System.arraycopy( current_eigen_approximation.entry[0], 0, m.eigenvector[i], 0, shortest );
}
}
public static void show_v (float[] v) {
int i = v.length;
while(--i >= 0)
System.out.print(v[i] + " ");
System.out.println();
}
public static void Deflate( Matrix base, Matrix eigen_vector, float eigen_value ) {
Matrix r1 = scalarMultiplyResult(eigen_vector, eigen_value);
Matrix result = productResult( eigen_vector.transpose(), r1 );
pairwiseSubtract( base, result );
}
public static Matrix DeflateResult( Matrix base, Matrix eigen_vector, float eigen_value ) {
Matrix result = productResult( eigen_vector, scalarMultiplyResult(eigen_vector, eigen_value).transpose() );
result = pairwiseSubtractResult( base, result );
return result;
}
public static void LU_Dolittle_Decomposition( Matrix m ) {
int rows = m.rows; int columns = m.columns;
for(int i = 0; i < rows;i++ ) {
for(int j = i; j < columns; j++ ) {
for(int k = 0; k < i-1; k++ )
m.entry[i][j] -= m.entry[i][k]*m.entry[k][j];
}
for(int j = i+1; j < rows; j++ ) {
for(int k = 0; k < i-1; k++ )
m.entry[j][i] -= m.entry[j][k]*m.entry[k][i];
if(m.entry[i][i] != 0.0f)
m.entry[j][i] /= m.entry[i][i];
}
}
}
public static Matrix LU_Dolittle_DecompositionResult( Matrix m ) {
int rows = m.rows; int columns = m.columns;
Matrix lowerupper = new Matrix(Matrix.IDENTITY, rows, columns );
for(int i = 0; i < rows;i++ ) {
for(int j = i; j < columns; j++ ) {
lowerupper.entry[i][j] = m.entry[i][j];
for(int k = 0; k < i-1; k++ )
lowerupper.entry[i][j] -= lowerupper.entry[i][k]*lowerupper.entry[k][j];
}
for(int j = i+1; j < rows; j++ ) {
lowerupper.entry[j][i] = m.entry[j][i];
for(int k = 0; k < i-1; k++ )
lowerupper.entry[j][i] -= lowerupper.entry[j][k]*lowerupper.entry[j][i];
if(lowerupper.entry[i][i] != 0.0f)
lowerupper.entry[j][i] /= lowerupper.entry[i][i];
}
}
return lowerupper;
}
public static Matrix[] LU_Dolittle_DecompositionResultPair( Matrix m ) {
int rows = m.rows; int columns = m.columns;
Matrix lower = new Matrix(Matrix.IDENTITY, rows, columns );
Matrix upper = new Matrix(Matrix.NONE, rows, columns );
for(int i = 0; i < rows;i++ ) {
for(int j = i; j < columns; j++ ) {
upper.entry[i][j] = m.entry[i][j];
for(int k = 0; k < i-1; k++ )
upper.entry[i][j] -= lower.entry[i][k]*upper.entry[k][j];
}
for(int j = i+1; j < rows; j++ ) {
lower.entry[j][i] = m.entry[j][i];
for(int k = 0; k < i-1; k++ )
lower.entry[j][i] -= lower.entry[j][k]*upper.entry[j][i];
if(lower.entry[i][i] != 0.0f)
lower.entry[j][i] /= upper.entry[i][i];
}
}
return new Matrix[] { lower, upper };
}
public static float diagonalDet( Matrix triangular ) {
float det = 1.0f;
int i = triangular.shortest;
while(--i >= 0 )
det *= triangular.entry[i][i];
triangular.det = det;
return det;
}
public static float Determinant( Matrix m ) {
Matrix[] lowerupper = LU_Dolittle_DecompositionResultPair(m);
float detLower = diagonalDet(lowerupper[0]);
float detUpper = diagonalDet(lowerupper[1]);
m.det = detLower*detUpper;
return m.det;
}
public static Matrix Inverse( Matrix a ) {
Matrix m = new Matrix(a);
Matrix w = new Matrix( Matrix.NONE, m.rows, m.columns );
Matrix l = new Matrix( Matrix.NONE, m.rows, m.columns );
Matrix u = new Matrix( Matrix.NONE, m.rows, m.columns );
for(int k = 0; k < m.shortest; k++ ) {
l.entry[k][k] = Matrix.IDENTITY;
for(int i = k+1; i < m.shortest; i++ ) {
float coeff = Matrix.IDENTITYF;
if(m.entry[k][k] != 0.0f)
coeff = m.entry[i][k]/m.entry[k][k];
l.entry[i][k] = coeff;
for(int j = k+1; j < m.shortest; j++ )
m.entry[i][j] -= coeff*m.entry[k][j];
}
}
for(int j = 0; j < m.shortest; j++ ) {
for(int i = 0; i < j; i++ ) {
u.entry[i][j] = m.entry[i][j];
}
}
float b[] = new float[m.shortest];
float d[] = new float[m.shortest];
float x[] = new float[m.shortest];
for(int k = 0; k < m.columns; k++ ) {
for(int i = 1; i < m.shortest; i++ ) {
b[k] = 1.0f;
d[1] = b[1];
for(int j = 1; j < i-1; j++ ) {
d[i] = b[i];
d[i] -= l.entry[i][j]*d[j];
}
}
if(u.entry[m.shortest-1][m.shortest-1] != 0.0f)
x[m.shortest-1] = d[m.shortest-1]/u.entry[m.shortest-1][m.shortest-1];
int i = m.shortest;
while(--i >= 0 ) {
x[i] = d[i];
int j = m.shortest;
while(--j > i ) {
x[i] = x[i] - u.entry[i][j]*x[j];
}
if(u.entry[i][i] != 0.0f)
x[i] /= u.entry[i][i];
}
for(i = 0; i < m.shortest; i++ ) {
w.entry[i][k] = x[i];
}
b[k] = 0.0f;
}
return w;
}
// Thresholding
public static void threshold ( Matrix a, float threshold, int directed ) {
int shortestRow = a.rows;
int shortestColumn = a.columns ;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
float aij = a.entry[i][j];
if(directed==0)
aij = Math.abs(a.entry[i][j]);
if(aij < threshold)
a.entry[i][j] = 0.0f;
else
a.entry[i][j] = 1.0f;
}
}
a.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix thresholdResult ( Matrix a, float threshold, int directed ) {
int shortestRow = a.rows;
int shortestColumn = a.columns;
Matrix result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
float aij = a.entry[i][j];
if(directed==0)
aij = Math.abs(a.entry[i][j]);
if(aij < threshold)
result.entry[i][j] = 0.0f;
else
result.entry[i][j] = 1.0f;
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
// Pair/Entry-Wise Fuzzy Binary arithmetic
// a AND 0 = 0
// a or 0 = a
// a XOR 0 = a
// a XOR a = 0
// a AND b = a*b
// a OR b = a+b
// a XOR b = (a/b + b/a)
// a KOR b = -ab + b/a
// NOT a = 0
// a NAND B = a/b
// a NOR b = a + 1/b
public static void AND( Matrix a, Matrix b ) {
int shortestRow = a.rows < b.rows ? a.rows : b.rows;
int shortestColumn = a.columns < b.columns ? a.columns : b.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
a.entry[i][j] = a.entry[i][j]*b.entry[i][j];
}
}
a.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix ANDResult ( Matrix a, Matrix b ) {
int shortestRow = a.rows < b.rows ? a.rows : b.rows;
int shortestColumn = a.columns < b.columns ? a.columns : b.columns;
Matrix result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
result.entry[i][j] = a.entry[i][j]*b.entry[i][j];
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
public static void OR( Matrix a, Matrix b ) {
int shortestRow = a.rows < b.rows ? a.rows : b.rows;
int shortestColumn = a.columns < b.columns ? a.columns : b.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
a.entry[i][j] = a.entry[i][j]+b.entry[i][j];
}
}
a.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix ORResult ( Matrix a, Matrix b ) {
int shortestRow = a.rows < b.rows ? a.rows : b.rows;
int shortestColumn = a.columns < b.columns ? a.columns : b.columns;
Matrix result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
result.entry[i][j] = a.entry[i][j]+b.entry[i][j];
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
public static void XOR( Matrix a, Matrix b ) {
int shortestRow = a.rows < b.rows ? a.rows : b.rows;
int shortestColumn = a.columns < b.columns ? a.columns : b.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
float aij = a.entry[i][j];
float bij = b.entry[i][j];
if(aij == 0) {
if(bij == 0 )
a.entry[i][j] = 0.0f;
else
a.entry[i][j] = bij;
}
else {
if(bij != 0 )
a.entry[i][j] = aij/bij + bij/aij;
}
}
}
a.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix XORResult ( Matrix a, Matrix b ) {
int shortestRow = a.rows < b.rows ? a.rows : b.rows;
int shortestColumn = a.columns < b.columns ? a.columns : b.columns;
Matrix result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
float aij = a.entry[i][j];
float bij = b.entry[i][j];
if(aij == 0) {
if(bij == 0 )
result.entry[i][j] = 0.0f;
else
result.entry[i][j] = bij;
}
else {
if(bij != 0 )
result.entry[i][j] = aij/bij + bij/aij;
}
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
public static void KOR( Matrix a, Matrix b ) {
int shortestRow = a.rows < b.rows ? a.rows : b.rows;
int shortestColumn = a.columns < b.columns ? a.columns : b.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
float aij = a.entry[i][j];
float bij = b.entry[i][j];
if(aij != 0)
a.entry[i][j] = -aij*bij + bij/aij;
}
}
a.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix KORResult ( Matrix a, Matrix b ) {
int shortestRow = a.rows < b.rows ? a.rows : b.rows;
int shortestColumn = a.columns < b.columns ? a.columns : b.columns;
Matrix result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
float aij = a.entry[i][j];
float bij = b.entry[i][j];
if(aij != 0)
result.entry[i][j] = -aij*bij + bij/aij;
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
public static void NOT ( Matrix a ) {
int shortestRow = a.rows;
int shortestColumn = a.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
float aij = a.entry[i][j];
if(aij != 0)
a.entry[i][j] = 1/-aij;
}
}
a.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix NOTResult ( Matrix a ) {
int shortestRow = a.rows;
int shortestColumn = a.columns;
Matrix result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
float aij = a.entry[i][j];
if(aij != 0)
result.entry[i][j] = 1.0f/-aij;
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
// General
public static Matrix complement ( Matrix m ) {
float[] mm = m.minmax();
float min = mm[0];
float max = mm[1];
float avg = (min+max)/2.0f;
Matrix result = new Matrix(Matrix.NONE, m.rows, m.columns);
int shortestRow = m.rows;
int shortestColumn = m.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
float mij = m.entry[i][j];
if(mij < avg)
result.entry[i][j] = max;
else
result.entry[i][j] = min;
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
// Modular arithmetic
//Addition
public static void ModscalarAdd(Matrix accumulator, float addend, float modulus ) {
if(addend == Matrix.ZEROF || modulus == Matrix.ZEROF) {
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int shortestRow = accumulator.rows;
int shortestColumn = accumulator.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
accumulator.entry[i][j] += addend;
accumulator.entry[i][j] %= modulus;
}
}
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix ModscalarAddResult(Matrix adder, float addend, float modulus ) {
Matrix result;
if(addend == Matrix.ZEROF || modulus == Matrix.ZEROF) {
result = new Matrix(adder);
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
int shortestRow = adder.rows;
int shortestColumn = adder.columns;
result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
result.entry[i][j] = adder.entry[i][j] + addend;
result.entry[i][j] %= modulus;
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
public static void ModpairwiseSum(Matrix accumulator, Matrix summand, float modulus ) {
if(modulus == Matrix.ZEROF) {
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int shortestRow = accumulator.rows < summand.rows ? accumulator.rows : summand.rows;
int shortestColumn = accumulator.columns < summand.columns ? accumulator.columns : summand.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
accumulator.entry[i][j] += summand.entry[i][j];
accumulator.entry[i][j] %= modulus;
}
}
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix ModpairwiseSumResult(Matrix adder, Matrix summand, float modulus ) {
if(modulus == Matrix.ZEROF) {
adder.updates &= (Matrix.all_changed^Matrix.entry_changed);
return adder;
}int shortestRow = adder.rows < summand.rows ? adder.rows : summand.rows;
int shortestColumn = adder.columns < summand.columns ? adder.columns : summand.columns;
Matrix result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
result.entry[i][j] = adder.entry[i][j] + summand.entry[i][j];
result.entry[i][j] %= modulus;
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
// Subtraction
public static void ModscalarSubtract(Matrix accumulator, float subtractand, float modulus ) {
if(modulus == Matrix.ZEROF || subtractand == Matrix.ZEROF) {
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int shortestRow = accumulator.rows;
int shortestColumn = accumulator.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
accumulator.entry[i][j] -= subtractand;
accumulator.entry[i][j] %= modulus;
}
}
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix ModscalarSubtractResult(Matrix subtractor, float subtractand, float modulus ) {
Matrix result;
if(modulus == Matrix.ZEROF || subtractand == Matrix.ZEROF) {
result = new Matrix(subtractor);
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
int shortestRow = subtractor.rows;
int shortestColumn = subtractor.columns;
result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
result.entry[i][j] = subtractor.entry[i][j] - subtractand;
result.entry[i][j] %= modulus;
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
public static void ModpairwiseSubtract(Matrix accumulator, Matrix subtractand, float modulus ) {
if(modulus == Matrix.ZEROF) {
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int shortestRow = accumulator.rows < subtractand.rows ? accumulator.rows : subtractand.rows;
int shortestColumn = accumulator.columns < subtractand.columns ? accumulator.columns : subtractand.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
accumulator.entry[i][j] -= subtractand.entry[i][j];
accumulator.entry[i][j] %= modulus;
}
}
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix ModpairwiseSubtractResult(Matrix subtractor, Matrix subtractand, float modulus ) {
Matrix result;
if(modulus == Matrix.ZEROF) {
result = new Matrix(subtractor);
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
int shortestRow = subtractor.rows < subtractand.rows ? subtractor.rows : subtractand.rows;
int shortestColumn = subtractor.columns < subtractand.columns ? subtractor.columns : subtractand.columns;
result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
result.entry[i][j] = subtractor.entry[i][j] - subtractand.entry[i][j];
result.entry[i][j] %= modulus;
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
// Multiplication
public static void ModscalarMultiply(Matrix accumulator, float multiplier, float modulus ) {
if(modulus == Matrix.ZEROF) {
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int shortestRow = accumulator.rows;
int shortestColumn = accumulator.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
accumulator.entry[i][j] *= multiplier;
accumulator.entry[i][j] %= modulus;
}
}
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix ModscalarMultiplyResult(Matrix multiplicand, float multiplier, float modulus ) {
Matrix result;
if(modulus == Matrix.ZEROF) {
result = new Matrix(multiplicand);
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
int shortestRow = multiplicand.rows;
int shortestColumn = multiplicand.columns;
result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
result.entry[i][j] = multiplicand.entry[i][j] * multiplier;
result.entry[i][j] %= modulus;
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
public static float ModFrobeniusInnerProduct( Matrix multiplicand, Matrix multiplier, float modulus ) {
if(modulus == Matrix.ZEROF) {
return modulus;
}
int shortestRow = multiplicand.rows < multiplier.rows ? multiplicand.rows : multiplier.rows;
int shortestColumn = multiplicand.columns < multiplier.columns ? multiplicand.columns : multiplier.columns;
int i = shortestRow;
float accumulator = 0.0f;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
accumulator += multiplicand.entry[i][j]*multiplier.entry[i][j];
}
}
return accumulator % modulus;
}
public static void ModhadamardProduct(Matrix accumulator, Matrix multiplicand, float modulus ) {
if(modulus == Matrix.ZEROF) {
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int shortestRow = accumulator.rows < multiplicand.rows ? accumulator.rows : multiplicand.rows;
int shortestColumn = accumulator.columns < multiplicand.columns ? accumulator.columns : multiplicand.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
accumulator.entry[i][j] *= multiplicand.entry[i][j];
accumulator.entry[i][j] %= modulus;
}
}
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix ModhadamardProductResult(Matrix multiplier, Matrix multiplicand, float modulus ) {
Matrix result;
if(modulus == Matrix.ZEROF) {
result = new Matrix(multiplicand);
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
int shortestRow = multiplier.rows < multiplicand.rows ? multiplier.rows : multiplicand.rows;
int shortestColumn = multiplier.columns < multiplicand.columns ? multiplier.columns : multiplicand.columns;
result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
result.entry[i][j] = multiplier.entry[i][j] * multiplicand.entry[i][j];
result.entry[i][j] %= modulus;
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
public static void ModproductPropagated(Matrix accumulator, Matrix multiplier, float modulus ) {
if(modulus == Matrix.ZEROF) {
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int shortestRow = accumulator.rows < multiplier.rows ? accumulator.rows : multiplier.rows;
int shortestColumn = accumulator.columns < multiplier.columns ? accumulator.columns : multiplier.columns;
int shortest = shortestRow < shortestColumn ? shortestRow : shortestColumn;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
int k = shortest;
float entrySum = 0.0f;
while(--k >= 0) {
entrySum += accumulator.entry[i][k]*multiplier.entry[k][j];
}
accumulator.entry[i][j] = entrySum;
accumulator.entry[i][j] %= modulus;
}
}
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix ModproductResult(Matrix multiplicand, Matrix multiplier, float modulus ) {
Matrix result;
if(modulus == Matrix.ZEROF) {
result = new Matrix(multiplicand);
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
int shortest = multiplicand.columns < multiplier.rows ? multiplicand.columns : multiplier.rows;
int i = multiplicand.rows;
int j = multiplier.columns;
result = new Matrix(Matrix.NONE, i, j);
while(--i >= 0) {
j = multiplier.columns;
while(--j >= 0) {
int k = shortest;
float entrySum = 0.0f;
while(--k >= 0) {
entrySum += multiplicand.entry[i][k]*multiplier.entry[k][j];
}
result.entry[i][j] = entrySum;
result.entry[i][j] %= modulus;
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
// Division
public static void ModentrywiseInversion( Matrix divisor, float modulus ) {
if(modulus == Matrix.ZEROF) {
divisor.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int shortestRow = divisor.rows;
int shortestColumn = divisor.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
float divisorij = divisor.entry[i][j];
if(divisorij != Matrix.ZEROF)
divisor.entry[i][j] = Matrix.IDENTITYF / divisorij;
else
divisor.entry[i][j] = Matrix.IDENTITYF;
divisor.entry[i][j] %= modulus;
}
}
}
public static Matrix ModentrywiseInversionResult ( Matrix divisor, float modulus ) {
int shortestRow = divisor.rows;
int shortestColumn = divisor.columns;
Matrix result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
float divisorij = divisor.entry[i][j];
if(divisorij != Matrix.ZEROF)
result.entry[i][j] = Matrix.IDENTITYF / divisorij;
else
result.entry[i][j] = Matrix.IDENTITYF;
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
public static void ModscalarDivide(Matrix accumulator, float divisor, float modulus) {
if(modulus == Matrix.ZEROF) {
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int shortestRow = accumulator.rows;
int shortestColumn = accumulator.columns;
if(divisor == Matrix.ZEROF) {
Arrays.fill(accumulator.entry, Matrix.IDENTITYF);
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0)
accumulator.entry[i][j] /= divisor;
}
}
public static Matrix ModscalarDivideResult(Matrix dividend, float divisor, float modulus) {
Matrix result;
if(modulus == Matrix.ZEROF) {
result = new Matrix(dividend);
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
int shortestRow = dividend.rows;
int shortestColumn = dividend.columns;
result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
if(divisor != Matrix.ZEROF)
result.entry[i][j] = dividend.entry[i][j] / divisor;
else
result.entry[i][j] = Matrix.IDENTITYF;
result.entry[i][j] %= modulus;
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
public static void ModhadamardDivision(Matrix accumulator, Matrix divisor, float modulus) {
if(modulus == Matrix.ZEROF) {
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int shortestRow = accumulator.rows < divisor.rows ? accumulator.rows : divisor.rows;
int shortestColumn = accumulator.columns < divisor.columns ? accumulator.columns : divisor.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
if(divisor.entry[i][j] != Matrix.ZEROF)
accumulator.entry[i][j] /= divisor.entry[i][j];
else
accumulator.entry[i][j] = Matrix.ZEROF;
accumulator.entry[i][j] %= modulus;
}
}
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix ModhadamardDivisionResult(Matrix dividend, Matrix divisor, float modulus) {
Matrix result;
if(modulus == Matrix.ZEROF) {
result = new Matrix(dividend);
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
int shortestRow = dividend.rows < divisor.rows ? dividend.rows : divisor.rows;
int shortestColumn = dividend.columns < divisor.columns ? dividend.columns : divisor.columns;
result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
if(divisor.entry[i][j] != Matrix.ZEROF)
result.entry[i][j] = dividend.entry[i][j] / divisor.entry[i][j];
else
result.entry[i][j] = Matrix.ZEROF;
result.entry[i][j] %= modulus;
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
// Powers
public static void ModhadamardPower(Matrix accumulator, int power, float modulus) {
if(modulus == Matrix.ZEROF) {
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int shortestRow = accumulator.rows;
int shortestColumn = accumulator.columns;
if(power == 0) {
accumulator.make_ones();
return;
}
if(power == 1)
return;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
int p = power;
while(--p > 0) {
accumulator.entry[i][j] *= accumulator.entry[i][j];
accumulator.entry[i][j] %= modulus;
}
}
}
accumulator.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix ModhadamardPowerResult(Matrix multiplier, int power, float modulus) {
Matrix result;
if(modulus == Matrix.ZEROF) {
result = new Matrix(multiplier);
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
int shortestRow = multiplier.rows;
int shortestColumn = multiplier.columns;
if(power == 1)
return new Matrix(multiplier);
result = new Matrix(Matrix.ONES, shortestRow, shortestColumn);
if(power == 0)
return result;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
int p = power;
while(--p >= 0) {
result.entry[i][j] *= multiplier.entry[i][j];
result.entry[i][j] %= modulus;
}
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
public static int[] Modradix(int num, int base, float modulus) {
if(modulus == Matrix.ZEROF) {
return new int[10];
}
int b = 1; int b1 = base;
int rem = 0; int rem1 = num % b1;
int bit = 0;
int[] bits = new int[10];
while(b <= num) {
bits[bit] = ((rem1 - rem)/b) % (int)modulus;
b=b1;b1*=base;
rem=rem1; rem1 = num % b1;
bit++;
if(bit >= bits.length) {
int[] temp = new int[bit<<1];
System.arraycopy(bits, 0, temp, 0, bit);
bits = temp;
}
}
return bits;
}
public static float ModexponentialTrace( Matrix m, float modulus ) {
if(modulus == Matrix.ZEROF)
return modulus;
float result = 1.0f;
float trace = m.trace();
int itrace = (int)trace;
float diff = trace - itrace;
int[] bits = radix(itrace, 2);
int iteration = 0;
float lastPow = 2.71828183f;
int lastPowIndex = 0;
while(iteration++ < bits.length) {
int bit = bits[iteration];
if(bit == 1) {
int squaresRequired = iteration - lastPowIndex;
while(--squaresRequired >= 0)
lastPow = (lastPow * lastPow) % modulus;
result = (result * lastPow) % modulus;
}
}
float extra = -(float)Math.log(diff);
if(extra != 0.0f)
result *= extra;
return result % modulus;
}
public static void mod(Matrix base, float modulus ) {
if(modulus == Matrix.ZEROF) {
base.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int shortestRow = base.rows;
int shortestColumn = base.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
base.entry[i][j] %= modulus;
}
}
base.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix modResult( Matrix base, float modulus ) {
Matrix result;
if(modulus == Matrix.ZEROF) {
result = new Matrix(base);
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
int shortestRow = base.rows;
int shortestColumn = base.columns;
result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0)
result.entry[i][j] %= modulus;
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
public static void ModpolysquarePropagated(Matrix base, int times, float modulus) {
if(modulus == Matrix.ZEROF) {
base.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
while(--times >= 0) {
productPropagated(base, base);
mod(base, modulus);
}
}
public static void ModfastPropagatedMultiproduct(Matrix base, int exponent, float modulus) {
if(modulus == Matrix.ZEROF) {
base.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int[] operations = radix(exponent, 2);
int lastProductIndex = 0, jmax = operations.length;
Matrix partialPowers;
if(operations[0] == 0)
partialPowers = new Matrix(Matrix.IDENTITY, base.rows, base.columns);
else
partialPowers = new Matrix(base);
for(int j = 1; j < jmax;j++) {
int bit = operations[j];
if(bit == 1) {
ModpolysquarePropagated(partialPowers, j-lastProductIndex, modulus);
lastProductIndex = j;
ModproductPropagated(base, partialPowers, modulus);
mod(base,modulus);
}
}
}
public static Matrix Modpolysquare(Matrix base, int times, float modulus) {
if(modulus == Matrix.ZEROF) {
Matrix result = new Matrix(base);
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
while(--times >= 0) {
base = productResult(base, base);
base = modResult(base, modulus);
}
base.updates &= (Matrix.all_changed^Matrix.entry_changed);
return base;
}
public static Matrix ModfastMultiproduct(Matrix base, int exponent, float modulus) {
if(modulus == Matrix.ZEROF) {
Matrix result = new Matrix(base);
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
int[] operations = radix(exponent, 2);
int lastProductIndex = 0, jmax = operations.length;
Matrix partialPowers;
if(operations[0] == 0)
partialPowers = new Matrix(Matrix.IDENTITY, base.rows, base.columns);
else
partialPowers = new Matrix(base);
for(int j = 1; j < jmax;j++) {
int bit = operations[j];
if(bit == 1) {
Modpolysquare(partialPowers, j-lastProductIndex, modulus);
lastProductIndex = j;
base = ModproductResult(base, partialPowers, modulus);
base = modResult(base,modulus);
}
}
return base;
}
public static Matrix ModsquareRootReturnInverseSquareRoot(Matrix y, float modulus) {
if(modulus == Matrix.ZEROF) {
y.updates &= (Matrix.all_changed^Matrix.entry_changed);
return ModInverse(y, modulus);
}
Matrix z = new Matrix(Matrix.IDENTITY, y.rows, y.columns);
int j = (int)Math.sqrt(y.rows) + 1;
while(--j >= 0) {
scalarMultiply(pairwiseSumResult(y,Inverse(z)), 0.5f);
scalarMultiply(pairwiseSumResult(z,Inverse(y)), 0.5f);
}
y.updates &= (Matrix.all_changed^Matrix.entry_changed);
z.updates &= (Matrix.all_changed^Matrix.entry_changed);
return z;
}
public static Matrix[] ModsquareRootInverseSquareRootResult(Matrix x, float modulus) {
if(modulus == Matrix.ZEROF) {
Matrix result = new Matrix(x);
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return new Matrix[] {result, ModInverse(result, modulus)};
}
Matrix y = new Matrix(x);
Matrix z = new Matrix(Matrix.IDENTITY, y.rows, y.columns);
int j = (int)Math.sqrt(y.rows) + 1;
while(--j >= 0) {
scalarMultiply(pairwiseSumResult(y,Inverse(z)), 0.5f);
scalarMultiply(pairwiseSumResult(z,Inverse(y)), 0.5f);
}
y.updates &= (Matrix.all_changed^Matrix.entry_changed);
z.updates &= (Matrix.all_changed^Matrix.entry_changed);
return new Matrix[] { y, z };
}
public static void ModentrywiseSquareRoot(Matrix x, float modulus) {
if(modulus == Matrix.ZEROF)
return;
int shortestRow = x.rows;
int shortestColumn = x.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
float xij = x.entry[i][j] % modulus;
float sign = xij/Math.abs(xij);
x.entry[i][j] = (float)( sign*Math.sqrt(Math.abs(xij)) );
}
}
x.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix ModentrywiseSquareRootResult(Matrix x, float modulus) {
if(modulus == Matrix.ZEROF)
return new Matrix(x);
int shortestRow = x.rows;
int shortestColumn = x.columns;
int i = shortestRow;
Matrix result = new Matrix(Matrix.NONE, x.rows, x.columns);
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
float xij = x.entry[i][j] % modulus;
float sign = xij/Math.abs(xij);
result.entry[i][j] = (float)( sign*Math.sqrt(Math.abs(xij)) );
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
// Logarithm
public static void ModentrywiseLogarithm( Matrix m, float modulus ) {
if(modulus == Matrix.ZEROF) {
return;
}
int shortestRow = m.rows;
int shortestColumn = m.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
float eij = m.entry[i][j];
float sign = eij/Math.abs(eij);
m.entry[i][j] = (float)(sign*Math.log(eij));
}
}
m.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix ModentrywiseLogarithmResult( Matrix m, float modulus ) {
if(modulus == Matrix.ZEROF) {
m.updates &= (Matrix.all_changed^Matrix.entry_changed);
return m;
}
int shortestRow = m.rows;
int shortestColumn = m.columns;
int i = shortestRow;
Matrix result = new Matrix(m);
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
float eij = m.entry[i][j];
float sign = eij/Math.abs(eij);
result.entry[i][j] = (float)(sign*Math.log(eij));
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
// Mapping
public static void ModscaleToRange(Matrix m, float low, float high, float modulus) {
if(modulus == Matrix.ZEROF) {
m.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
float[] minmax = m.minmax();
float newrange = high-low;
float oldrange = minmax[1]-minmax[0];
float range = oldrange == 0.0f ? 1.0f : newrange/oldrange;
mod(m,modulus);
scalarSubtract(m, minmax[0]);
scalarMultiply(m, range );
scalarAdd(m, low );
}
public static Matrix ModscaleToRangeResult(Matrix m, float low, float high, float modulus) {
if(modulus == Matrix.ZEROF) {
Matrix result = new Matrix(m);
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
float[] minmax = m.minmax();
float newrange = high-low;
float oldrange = minmax[1]-minmax[0];
float range = oldrange == 0.0f ? 1.0f : newrange/oldrange;
Matrix result = new Matrix(Matrix.NONE, m.rows, m.columns);
result = ModscalarSubtractResult(m, minmax[0], modulus);
ModscalarMultiply(result, range, modulus );
ModscalarAdd(result, low, modulus );
return result;
}
// Random
public static void Modfill_random(Matrix m, float modulus) {
if(modulus == Matrix.ZEROF) {
m.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int i = m.rows;
while(--i >= 0 ) {
int j = m.columns;
while(--j >= 0 )
m.entry[i][j] = (float)Math.random() % modulus;
}
}
public static void Modfill_random( float[] v, float modulus) {
if(modulus == Matrix.ZEROF) {
return;
}
int j = v.length;
while(--j >= 0 ) v[j] = (float)Math.random() % modulus;
}
// Norms & normalization vectors and matrices : 0, 1, 2, inf
public static void ModLinfnormalize( Matrix m, float modulus ) {
if(modulus == Matrix.ZEROF) {
m.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int i = m.rows;
int j = m.columns;
if( i == 0 || j == 0)
return;
float max = Math.abs(m.entry[0][0]);
while( --i >= 0 ) {
while( --j >= 0 ) {
float eij = Math.abs(m.entry[i][j]);
if(eij > max)
max = eij;
}
j = m.columns;
}
i = m.rows;
while( --i >= 0 ) {
j = m.columns;
while( --j >= 0 ) {
m.entry[i][j] /= max;
}
}
}
public static void ModLinfnormalize( float[] v, float modulus ) {
if(modulus == Matrix.ZEROF) {
return;
}
int j = v.length;
if(j == 0)
return;
float max = Math.abs(v[0]);
while(--j > 0) {
float vj = Math.abs(v[j]);
if(vj > max)
max = vj;
}
j = v.length;
while(--j >= 0) v[j] /= max;
}
public static float ModLinfnorm( Matrix m, float modulus ) {
if(modulus == Matrix.ZEROF) {
m.updates &= (Matrix.all_changed^Matrix.entry_changed);
return modulus;
}
int i = m.rows;
int j = m.columns;
if( i == 0 || j == 0)
return 0.0f;
float max = Math.abs(m.entry[0][0]);
while( --i >= 0 ) {
while( --j >= 0 ) {
float eij = Math.abs(m.entry[i][j]);
if(eij > max)
max = eij;
}
j = m.columns;
}
if(m.norms == null)
m.norms = new float[4];
m.norms[3] = max;
return max;
}
public static float ModLinfnorm( float[] v, float modulus ) {
if(modulus == Matrix.ZEROF) {
return modulus;
}
int j = v.length;
if(j == 0)
return 0.0f;
float max = Math.abs(v[0]);
while(--j > 0) {
float vj = Math.abs(v[j]);
if(vj > max)
max = vj;
}
return max;
}
public static void ModL2normalize( Matrix m, float modulus ) {
if(modulus == Matrix.ZEROF) {
m.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int i = m.rows;
float sumSquares = 0.0f;
while( --i >= 0 ) {
int j = m.columns;
while( --j >= 0 ) {
sumSquares += m.entry[i][j]*m.entry[i][j];
}
}
sumSquares = (float)Math.sqrt(sumSquares);
i = m.rows;
while( --i >= 0 ) {
int j = m.columns;
while( --j >= 0 ) {
m.entry[i][j] /= sumSquares;
}
}
}
public static void ModL2normalize( float [] v, float modulus ) {
if(modulus == Matrix.ZEROF) {
return;
}
int j = v.length;
float sumSquares = 0.0f;
while(--j >= 0) sumSquares += v[j]*v[j];
j = v.length;
sumSquares = (float)Math.sqrt(sumSquares);
while(--j >= 0) v[j] /= sumSquares;
}
public static float ModL2norm( Matrix m, float modulus ) {
if(modulus == Matrix.ZEROF) {
m.updates &= (Matrix.all_changed^Matrix.entry_changed);
return modulus;
}
int i = m.rows;
float sumSquares = 0.0f;
while( --i >= 0 ) {
int j = m.columns;
while( --j >= 0 ) {
sumSquares += (m.entry[i][j]*m.entry[i][j])%modulus;
}
}
sumSquares = (float)Math.sqrt(sumSquares);
if(m.norms == null)
m.norms = new float[4];
m.norms[2] = sumSquares;
return sumSquares;
}
public static float ModL2norm( float [] v, float modulus ) {
if(modulus == Matrix.ZEROF) {
return modulus;
}
int j = v.length;
float sumSquares = 0.0f;
while(--j >= 0) sumSquares += (v[j]*v[j])%modulus;
return (float)Math.sqrt(sumSquares);
}
public static void ModL1normalize( Matrix m, float modulus ) {
if(modulus == Matrix.ZEROF) {
m.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int i = m.rows;
float sum = 0.0f;
while( --i >= 0 ) {
int j = m.columns;
while( --j >= 0 ) {
sum += Math.abs(m.entry[i][j]);
}
}
i = m.rows;
while( --i >= 0 ) {
int j = m.columns;
while( --j >= 0 ) {
m.entry[i][j] /= sum;
}
}
}
public static void ModL1normalize( float[] v, float modulus ) {
if(modulus == Matrix.ZEROF) {
return;
}
int j = v.length;
float sum = 0.0f;
while(--j >= 0) sum += Math.abs(v[j]);
j = v.length;
while(--j >= 0) v[j] /= sum;
}
public static float ModL1norm( Matrix m, float modulus ) {
if(modulus == Matrix.ZEROF) {
m.updates &= (Matrix.all_changed^Matrix.entry_changed);
return modulus;
}
int i = m.rows;
float sum = 0.0f;
while( --i >= 0 ) {
int j = m.columns;
while( --j >= 0 ) {
sum += Math.abs(m.entry[i][j]);
}
}
if(m.norms == null)
m.norms = new float[4];
m.norms[1] = sum;
return sum;
}
public static float ModL1norm( float[] v, float modulus ) {
if(modulus == Matrix.ZEROF) {
return modulus;
}
int j = v.length;
float sum = 0.0f;
while(--j >= 0) sum += Math.abs(v[j]);
return sum;
}
public static void ModL0normalize( Matrix m, float modulus ) {
if(modulus == Matrix.ZEROF) {
m.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int i = m.rows;
float sum = 0.0f;
while( --i >= 0 ) {
int j = m.columns;
while( --j >= 0 ) {
if(m.entry[i][j] != Matrix.ZEROF)
sum += 1.0f;
}
}
i = m.rows;
while( --i >= 0 ) {
int j = m.columns;
while( --j >= 0 ) {
m.entry[i][j] /= sum;
}
}
}
public static void ModL0normalize( float[] v, float modulus ) {
if(modulus == Matrix.ZEROF) {
return;
}
int j = v.length;
float sum = 0.0f;
while(--j >= 0)
if(v[j] != 0.0f)
sum += 1.0f;
j = v.length;
while(--j >= 0) v[j] /= sum;
}
public static float ModL0norm( Matrix m, float modulus ) {
if(modulus == Matrix.ZEROF) {
m.updates &= (Matrix.all_changed^Matrix.entry_changed);
return modulus;
}
int i = m.rows;
float sum = 0.0f;
while( --i >= 0 ) {
int j = m.columns;
while( --j >= 0 ) {
if(m.entry[i][j] != Matrix.ZEROF)
sum += 1.0f;
}
}
if(m.norms == null)
m.norms = new float[4];
m.norms[0] = sum;
return sum;
}
public static float ModL0norm( float[] v, float modulus ) {
if(modulus == Matrix.ZEROF) {
return modulus;
}
int j = v.length;
float sum = 0.0f;
while(--j >= 0)
if(v[j] != 0.0f)
sum += 1.0f;
return sum;
}
// Algorithms
public static Matrix ModFloydWarshall( Matrix base, float epsilon, float connected_bound, float disconnected_bound, int strictness, int minmax, float modulus ) {
if(modulus == Matrix.ZEROF) {
Matrix result = new Matrix(base);
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
epsilon = Math.abs(epsilon);
float connected = connected_bound;
float disconnected = disconnected_bound;
int i = base.rows;
int maxspan = base.shortest;
Matrix fw = new Matrix(Matrix.NONE, i, base.columns);
while(--i >= 0) {
int j = base.columns;
while(--j >= 0 ) {
float eij = base.entry[i][j];
if( strictness == 0 && j < maxspan && i < maxspan ) {
eij += base.entry[j][i];
}
if( eij > -epsilon && eij < epsilon )
fw.entry[i][j] = connected;
else
fw.entry[i][j] = disconnected;
}
}
int k = maxspan;
while( --k >= 0 ) {
i = base.rows;
while( --i >= 0 ) {
float current_distance_part = fw.entry[i][k];
int j = base.columns;
while( -- j >= 0 ) {
if(i==j)
fw.entry[i][j] = 0.0f;
else {
float current_distance = fw.entry[i][j];
float current_distance_whole = current_distance_part + fw.entry[k][j];
switch(minmax) {
case(MIN):
fw.entry[i][j] = current_distance < current_distance_whole ? current_distance : current_distance_whole;
break;
case(MAX):
fw.entry[i][j] = current_distance > current_distance_whole ? current_distance : current_distance_whole;
break;
}
fw.entry[i][j] %= modulus;
}
}
}
}
i = base.rows;
while( --i >= 0 ) {
int j = base.columns;
while( --j >= 0 )
fw.entry[i][j] *= fw.entry[i][j];
}
return fw;
}
public static void ModPowerIterationDeflate(Matrix m, int eigens_to_compute, double epsilons, int populateKrylovSubspace, float modulus ) {
if(modulus == Matrix.ZEROF) {
m.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int iteration = 0;
m.krylovs = new float[populateKrylovSubspace][m.columns];
while(--eigens_to_compute >= 0) {
Matrix next_eigen_approximation, current_eigen_approximation = new Matrix(Matrix.NONE, 1, m.columns );
double prev, current = epsilons; float eigenvalue_approximation;
fill_random( current_eigen_approximation );
L2normalize( current_eigen_approximation );
do {
prev = current;
next_eigen_approximation = new Matrix(current_eigen_approximation);
current_eigen_approximation = ModproductResult(m, next_eigen_approximation, modulus);
if(iteration<populateKrylovSubspace)
System.arraycopy(current_eigen_approximation.entry[0],0,m.krylovs[iteration++],0,m.columns);
eigenvalue_approximation = ModFrobeniusInnerProduct(next_eigen_approximation, current_eigen_approximation, modulus);
ModL2normalize(current_eigen_approximation, modulus);
current = ModFrobeniusInnerProduct(next_eigen_approximation,current_eigen_approximation, modulus);
} while( (current < (1-epsilons) && Math.abs( current/prev ) > (1 + epsilons)) );
ModscalarMultiply(current_eigen_approximation, (float)Math.sqrt(Math.abs(eigenvalue_approximation)), modulus);
m.eigenvalue[eigens_to_compute] = eigenvalue_approximation;
System.arraycopy( current_eigen_approximation.entry[0], 0, m.eigenvector[eigens_to_compute],0, m.columns );
if(eigens_to_compute > 0)
m = ModDeflateResult(m, current_eigen_approximation, eigenvalue_approximation, modulus );
}
}
public static Matrix ModDeflateResult( Matrix base, Matrix eigen_vector, float eigen_value, float modulus ) {
if(modulus == Matrix.ZEROF) {
Matrix result = new Matrix(base);
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
Matrix result = ModproductResult( eigen_vector, scalarMultiplyResult(eigen_vector, eigen_value).transpose(), modulus );
result = ModpairwiseSubtractResult( base, result, modulus );
return result;
}
public static void ModLU_Dolittle_Decomposition( Matrix m, float modulus ) {
if(modulus == Matrix.ZEROF) {
m.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int rows = m.rows; int columns = m.columns;
for(int i = 0; i < rows;i++ ) {
for(int j = i; j < columns; j++ ) {
for(int k = 0; k < i-1; k++ ) {
m.entry[i][j] -= m.entry[i][k]*m.entry[k][j];
m.entry[i][j] %= modulus;
}
}
for(int j = i+1; j < rows; j++ ) {
for(int k = 0; k < i-1; k++ )
m.entry[j][i] -= m.entry[j][k]*m.entry[k][i];
m.entry[j][i] /= m.entry[i][i];
m.entry[j][i] %= modulus;
}
}
}
public static Matrix ModLU_Dolittle_DecompositionResult( Matrix m, float modulus ) {
if(modulus == Matrix.ZEROF) {
Matrix result = new Matrix(m);
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
int rows = m.rows; int columns = m.columns;
Matrix lowerupper = new Matrix(Matrix.IDENTITY, rows, columns );
for(int i = 0; i < rows;i++ ) {
for(int j = i; j < columns; j++ ) {
lowerupper.entry[i][j] = m.entry[i][j];
for(int k = 0; k < i-1; k++ ) {
lowerupper.entry[i][j] -= lowerupper.entry[i][k]*lowerupper.entry[k][j];
lowerupper.entry[i][j] %= modulus;
}
}
for(int j = i+1; j < rows; j++ ) {
lowerupper.entry[j][i] = m.entry[j][i];
for(int k = 0; k < i-1; k++ )
lowerupper.entry[j][i] -= lowerupper.entry[j][k]*lowerupper.entry[j][i];
lowerupper.entry[j][i] /= lowerupper.entry[i][i];
lowerupper.entry[j][i] %= modulus;
}
}
return lowerupper;
}
public static Matrix[] ModLU_Dolittle_DecompositionResultPair( Matrix m, float modulus ) {
if(modulus == Matrix.ZEROF) {
Matrix result = new Matrix(m);
Matrix id = new Matrix(Matrix.IDENTITY, m.rows, m.columns );
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
id.updates &= (Matrix.all_changed^Matrix.entry_changed);
return new Matrix[] { result, id };
}
int rows = m.rows; int columns = m.columns;
Matrix lower = new Matrix(Matrix.IDENTITY, rows, columns );
Matrix upper = new Matrix(Matrix.NONE, rows, columns );
for(int i = 0; i < rows;i++ ) {
for(int j = i; j < columns; j++ ) {
upper.entry[i][j] = m.entry[i][j];
for(int k = 0; k < i-1; k++ ) {
upper.entry[i][j] -= lower.entry[i][k]*upper.entry[k][j];
upper.entry[i][j] %= modulus;
}
}
for(int j = i+1; j < rows; j++ ) {
lower.entry[j][i] = m.entry[j][i];
for(int k = 0; k < i-1; k++ )
lower.entry[j][i] -= lower.entry[j][k]*upper.entry[j][i];
lower.entry[j][i] /= upper.entry[i][i];
lower.entry[j][i] %= modulus;
}
}
return new Matrix[] { lower, upper };
}
public static float ModdiagonalDet( Matrix triangular, float modulus ) {
if(modulus == Matrix.ZEROF) {
triangular.updates &= (Matrix.all_changed^Matrix.entry_changed);
return modulus;
}
float det = 1.0f;
int i = triangular.shortest;
while(--i >= 0 )
det = (det * triangular.entry[i][i]) % modulus;
triangular.det = det;
return det;
}
public static float ModDeterminant( Matrix m, float modulus ) {
if(modulus == Matrix.ZEROF) {
m.updates &= (Matrix.all_changed^Matrix.entry_changed);
return modulus;
}
Matrix[] lowerupper = ModLU_Dolittle_DecompositionResultPair(m, modulus);
float detLower = ModdiagonalDet(lowerupper[0], modulus);
float detUpper = ModdiagonalDet(lowerupper[1], modulus);
m.det = (detLower*detUpper) % modulus;
return m.det;
}
public static Matrix ModInverse( Matrix a, float modulus ) {
if(modulus == Matrix.ZEROF) {
Matrix result = new Matrix(a);
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
Matrix m = new Matrix(a);
Matrix w = new Matrix( Matrix.NONE, m.rows, m.columns );
Matrix l = new Matrix( Matrix.NONE, m.rows, m.columns );
Matrix u = new Matrix( Matrix.NONE, m.rows, m.columns );
for(int k = 0; k < m.shortest; k++ ) {
l.entry[k][k] = Matrix.IDENTITY;
for(int i = k+1; i < m.shortest; i++ ) {
float coeff = m.entry[i][k]/m.entry[k][k];
l.entry[i][k] = coeff;
for(int j = k+1; j < m.shortest; j++ ) {
m.entry[i][j] -= coeff*m.entry[k][j];
m.entry[i][j] %= modulus;
}
}
}
for(int j = 0; j < m.shortest; j++ ) {
for(int i = 0; i < j; i++ ) {
u.entry[i][j] = m.entry[i][j] % modulus;
}
}
float b[] = new float[m.shortest];
float d[] = new float[m.shortest];
float x[] = new float[m.shortest];
for(int k = 0; k < m.columns; k++ ) {
d[1] = b[1];
b[k] = 1.0f;
for(int i = 1; i < m.shortest; i++ ) {
for(int j = 1; j < i-1; j++ ) {
d[i] = b[i];
d[i] -= l.entry[i][j]*d[j];
d[i] %= modulus;
}
}
x[m.shortest-1] = d[m.shortest-1]/u.entry[m.shortest-1][m.shortest-1];
for(int i = m.shortest; i >= 0; i-- ) {
x[i] = d[i];
for(int j = m.shortest; j > i; j-- ) {
x[i] = x[i] - u.entry[i][j]*x[j];
x[i] %= modulus;
}
x[i] /= u.entry[i][i];
}
for(int i = 0; i < m.shortest; i++ ) {
w.entry[i][k] = x[i];
w.entry[i][k] %= modulus;
}
b[k] = 0.0f;
}
return w;
}
// Thresholding
public static void Modthreshold ( Matrix a, float threshold, int directed, float modulus ) {
if(modulus == Matrix.ZEROF) {
a.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int shortestRow = a.rows;
int shortestColumn = a.columns ;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
float aij = a.entry[i][j];
if(directed==0)
aij = Math.abs(a.entry[i][j]);
if((aij % modulus ) < threshold)
a.entry[i][j] = 0.0f;
else
a.entry[i][j] = 1.0f;
}
}
a.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix ModthresholdResult ( Matrix a, float threshold, int directed, float modulus ) {
if(modulus == Matrix.ZEROF) {
Matrix result = new Matrix(a);
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
int shortestRow = a.rows;
int shortestColumn = a.columns;
Matrix result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
float aij = a.entry[i][j];
if(directed==0)
aij = Math.abs(a.entry[i][j]);
if((aij % modulus) < threshold)
result.entry[i][j] = 0.0f;
else
result.entry[i][j] = 1.0f;
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
// Pair/Entry-Wise Fuzzy Binary arithmetic
// a AND 0 = 0
// a or 0 = a
// a XOR 0 = a
// a XOR a = 0
// a AND b = a*b
// a OR b = a+b
// a XOR b = (a/b + b/a)
// a KOR b = -ab + b/a
// NOT a = 0
// a NAND B = a/b
// a NOR b = a + 1/b
public static void ModAND( Matrix a, Matrix b, float modulus ) {
if(modulus == Matrix.ZEROF) {
a.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int shortestRow = a.rows < b.rows ? a.rows : b.rows;
int shortestColumn = a.columns < b.columns ? a.columns : b.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
a.entry[i][j] = a.entry[i][j]*b.entry[i][j];
a.entry[i][j] %= modulus;
}
}
a.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix ModANDResult ( Matrix a, Matrix b, float modulus ) {
if(modulus == Matrix.ZEROF) {
Matrix result = new Matrix(a);
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
int shortestRow = a.rows < b.rows ? a.rows : b.rows;
int shortestColumn = a.columns < b.columns ? a.columns : b.columns;
Matrix result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
result.entry[i][j] = a.entry[i][j]*b.entry[i][j];
result.entry[i][j] %= modulus;
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
public static void ModOR( Matrix a, Matrix b, float modulus ) {
if(modulus == Matrix.ZEROF) {
a.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int shortestRow = a.rows < b.rows ? a.rows : b.rows;
int shortestColumn = a.columns < b.columns ? a.columns : b.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
a.entry[i][j] = (a.entry[i][j]+b.entry[i][j]) % modulus;
}
}
a.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix ModORResult ( Matrix a, Matrix b, float modulus ) {
if(modulus == Matrix.ZEROF) {
Matrix result = new Matrix(a);
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
int shortestRow = a.rows < b.rows ? a.rows : b.rows;
int shortestColumn = a.columns < b.columns ? a.columns : b.columns;
Matrix result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
result.entry[i][j] = a.entry[i][j]+b.entry[i][j];
result.entry[i][j] %= modulus;
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
public static void ModXOR( Matrix a, Matrix b, float modulus ) {
if(modulus == Matrix.ZEROF) {
a.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int shortestRow = a.rows < b.rows ? a.rows : b.rows;
int shortestColumn = a.columns < b.columns ? a.columns : b.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
float aij = a.entry[i][j];
float bij = b.entry[i][j];
if(aij == 0) {
if(bij == 0 )
a.entry[i][j] = 0.0f;
else
a.entry[i][j] = bij;
}
else {
if(bij != 0 )
a.entry[i][j] = aij/bij + bij/aij;
}
a.entry[i][j] %= modulus;
}
}
a.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix ModXORResult ( Matrix a, Matrix b, float modulus ) {
if(modulus == Matrix.ZEROF) {
Matrix result = new Matrix(a);
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
int shortestRow = a.rows < b.rows ? a.rows : b.rows;
int shortestColumn = a.columns < b.columns ? a.columns : b.columns;
Matrix result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
float aij = a.entry[i][j];
float bij = b.entry[i][j];
if(aij == 0) {
if(bij == 0 )
result.entry[i][j] = 0.0f;
else
result.entry[i][j] = bij;
}
else {
if(bij != 0 )
result.entry[i][j] = aij/bij + bij/aij;
}
result.entry[i][j] %= modulus;
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
public static void ModKOR( Matrix a, Matrix b, float modulus ) {
if(modulus == Matrix.ZEROF) {
a.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int shortestRow = a.rows < b.rows ? a.rows : b.rows;
int shortestColumn = a.columns < b.columns ? a.columns : b.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
float aij = a.entry[i][j];
float bij = b.entry[i][j];
if(aij != 0) {
a.entry[i][j] = -aij*bij + bij/aij;
a.entry[i][j] %= modulus;
}
}
}
a.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix ModKORResult ( Matrix a, Matrix b, float modulus ) {
if(modulus == Matrix.ZEROF) {
Matrix result = new Matrix(a);
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
int shortestRow = a.rows < b.rows ? a.rows : b.rows;
int shortestColumn = a.columns < b.columns ? a.columns : b.columns;
Matrix result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
float aij = a.entry[i][j];
float bij = b.entry[i][j];
if(aij != 0) {
result.entry[i][j] = -aij*bij + bij/aij;
result.entry[i][j] %= modulus;
}
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
public static void ModNOT ( Matrix a, float modulus ) {
if(modulus == Matrix.ZEROF) {
a.updates &= (Matrix.all_changed^Matrix.entry_changed);
return;
}
int shortestRow = a.rows;
int shortestColumn = a.columns;
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
float aij = a.entry[i][j];
if(aij != 0) {
a.entry[i][j] = 1/-aij;
a.entry[i][j] %= modulus;
}
}
}
a.updates &= (Matrix.all_changed^Matrix.entry_changed);
}
public static Matrix ModNOTResult ( Matrix a, float modulus ) {
if(modulus == Matrix.ZEROF) {
Matrix result = new Matrix(a);
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
int shortestRow = a.rows;
int shortestColumn = a.columns;
Matrix result = new Matrix(Matrix.NONE, shortestRow, shortestColumn);
int i = shortestRow;
while(--i >= 0) {
int j = shortestColumn;
while(--j >= 0) {
float aij = a.entry[i][j];
if(aij != 0) {
result.entry[i][j] = 1.0f/-aij;
result.entry[i][j] %= modulus;
}
}
}
result.updates &= (Matrix.all_changed^Matrix.entry_changed);
return result;
}
}
import processing.core.*;
import java.util.ArrayList;
public class AspektWorld extends PApplet {
public static final int BIG_STROKE = 10;
public static final int MIDDLE_STROKE = 3;
public static final int SMALL_STROKE = 3;
// private static final long serialVersionUID = 61803L;
public final static int FORWARD = 1;
public final static int BACKWARD = 2;
public final static int RIGHTWARD = 4;
public final static int LEFTWARD = 8;
public final static int UPWARD = 16;
public final static int DOWNWARD = 32;
static public void main(String args[]) {
PApplet.main(new String[] { "--bgcolor=#D4D0C8", "AspektWorld" });
}
public int direction = 0;
public int last_direction = 0;
public float lmx,lmy,dx,dy;
public final static float MAX_SPEED = 20.0f;
public final static float MIN_SPEED = 1.0f;
public float speed = 20.0f;
public float wd = 1600;
public float hh = 900;
public float dp = 1000;
public PVector forward_heading;
public PVector back_heading,left_heading,right_heading,up_heading,down_heading;
public PVector straight_up, straight_left, straight_down, straight_right, straight_forward, straight_back;
public int appletMode=1;
public int diameter = 100;
public float scalar;
public int longest;
public double ttheta;
// public Rotation r;
public int double_click;
public float sbxs,sbys;
public ArrayList<Line> lines;
public int edgeColor = 0;
public int mouseLookOn = 0;
public int verticesOn = 1;
public int edgesOn = 1;
public Graph.Vertex hoverNode;
public PMatrix3D currCameraMatrix;
public PGraphics3D g3;
public int in_a_control = 0;
public int basics_panel_active = 0;
public int matrix_panel_active = 0;
public int ev_panel_active = 0;
public int instructions_panel_active = 0;
public int ev1_sz, ev2_sz, ev3_sz, ev4_sz, ev5_sz;
public int ev_sz = 138, ev_sz_actv = 150;
public int mpa_sz, mpl_sz, mpd_sz;
public int m_sz = 100, m_sz_actv = 168;
public int mpa_sd, mpl_sd, mpd_sd;
public float m_actv_delta = (m_sz_actv-m_sz)/2.0f;
public int counter = 0;
public PFont face;
public float th_constant;
public Visionary cs;
PVector pos;
public Graph g1;
public void attach_graph_to_local_coordinate_master() {
int i = g1.v.length;
while(--i>=0)
g1.v[i].posa = pos;
i = g1.e.length;
}
/**
public void check_nodes_press() {
boolean result = false;
float cz = (float)cam.getDistance();
float[] la = cam.getLookAt();
float[] cam_rots = cam.getRotations();
float mx = mouseX-width/2.0f;
float my = mouseY-height/2.0f;
peasy.org.apache.commons.math.geometry.PVector cl = new peasy.org.apache.commons.math.geometry.PVector(la[0],la[1],la[2]);
Rotation inv_cam = new Rotation(RotationOrder.ZYX, -cam_rots[2], -cam_rots[1], -cam_rots[0]);
int ns = g1.nodes.size();
float ndx,ndy,ndz,dx,dy,shifts;
Node lh = null;
float lhndz = -height;
for(int i = 0; i < ns;i++) {
Node nd = (Node)g1.nodes.get(i);
if(nd == null)
continue;
peasy.org.apache.commons.math.geometry.PVector ndp = new peasy.org.apache.commons.math.geometry.PVector(nd.position.x,nd.position.y,nd.position.z);
ndp = inv_cam.applyTo(ndp.subtract(cl));
ndx = (float)(((ndp.x))); ndy = (float)(((ndp.y))); ndz = (float)(((ndp.z)));
//applet
//float shifts = (float)((height-64)/(cz-ndp.z));
shifts = (float)((height-100)/(cz-ndz));
dx = (float)mx - ndx*shifts;
dy = (float)my - ndy*shifts;
if(g1.hoverOnlyOn == 0)
result = shifts*shifts*nd.radiusq > dx*dx + dy*dy;
else
result = 0.5*shifts*nd.radiusq > dx*dx + dy*dy;
if(result) {
if(ndz > lhndz && (cz-ndz)>40) {
lh = nd;
lhndz = ndz;
}
}
}
if(lh != null) {
Node nd = lh;
counter++;
if(nd.partial_display >= 0 && g1.hideOn == 0) {
//g1.load_more(nd);
nd.show_hidden();
}
else if(g1.hideOn == 1) {
nd.hide();
}
else if(nd.selected == 0) {
if(g1.allPaths == 1 || (g1.pointToPointOn == 1 && g1.directedOn == 0))
g1.select_all_paths(nd,2);
else if(g1.selectNode != null && g1.pointToPointOn == 1 && g1.directedOn == 1){
g1.silence_all_paths(2);
g1.select_all_paths(g1.selectNode, nd,2);
}
g1.selectNode = nd;
nd.selected = 1;
nd.counter = counter;
spread_activity(nd);
}
else {
if(g1.allPaths == 1 || g1.pointToPointOn == 1)
g1.silence_all_paths(2);
g1.selectNode = null;
nd.hovered = 0;
nd.selected = 0;
nd.counter = 0;
retract_activity(nd);
}
}
else if(mouseEvent.getClickCount()==2) {
silence_grid();
g1.silence_all_paths(2);
}
else if(mouseEvent.getClickCount()==3) {
cam.reset();
}
}
**/
public void check_matrices_pass() {
float mx = mouseX;
float my = mouseY;
float m1x = (longest == 1)? 53 : 53;
float m1y = (longest==1)? height-253 : 53;
float m2x = (longest == 1)? width/2 : 53;
float m2y = (longest==1)? height-253 : height/2-100;
float m3x = (longest == 1)? width-253 : 53;
float m3y = (longest==1)? height-253 : height-253;
if( mx < m1x + mpa_sz && mx > m1x && my < m1y + mpa_sz && my > m1y ) {
if(mpa_sz == m_sz)
mpa_sz = m_sz_actv;
}
else if(mpa_sd == 0)
mpa_sz = m_sz;
if( mx < m2x + mpl_sz && mx > m2x && my < m2y + mpl_sz && my > m2y ) {
if(mpl_sz == m_sz)
mpl_sz = m_sz_actv;
}
else if(mpl_sd == 0)
mpl_sz = m_sz;
if( mx < m3x + mpd_sz && mx > m3x && my < m3y + mpd_sz && my > m3y ) {
if(mpd_sz == m_sz)
mpd_sz = m_sz_actv;
}
else if(mpd_sd == 0)
mpd_sz = m_sz;
}
public void check_matrices_press() {
float mx = mouseX;
float my = mouseY;
float m1x = (longest == 1)? 53 : 53;
float m1y = (longest==1)? height-253 : 53;
float m2x = (longest == 1)? width/2 : 53;
float m2y = (longest==1)? height-253 : height/2-100;
float m3x = (longest == 1)? width-253 : 53;
float m3y = (longest==1)? height-253 : height-253;
if( mx < m1x + mpa_sz && mx > m1x ) {
if( my < m1y + mpa_sz && my > m1y ) {
if(mpa_sd == 0) {
mpa_sz = m_sz_actv;
mpa_sd = 1;
}
else {
mpa_sz = m_sz;
mpa_sd = 0;
}
return;
}
}
if( mx < m2x + mpl_sz && mx > m2x ) {
if( my < m2y + mpl_sz && my > m2y ) {
if(mpl_sd == 0) {
mpl_sz = m_sz_actv;
mpl_sd = 1;
}
else {
mpl_sz = m_sz;
mpl_sd = 0;
}
return;
}
}
if( mx < m3x + mpd_sz && mx > m3x ) {
if( my < m3y + mpd_sz && my > m3y ) {
if(mpd_sd == 0) {
mpd_sz = m_sz_actv;
mpd_sd = 1;
}
else {
mpd_sz = m_sz;
mpd_sd = 0;
}
return;
}
}
}
public void check_nodes_pass() {
boolean result = false;
float cz = pos.mag();
float mx = mouseX-width/2.0f;
float my = mouseY-height/2.0f;
PVector cl = new PVector(0,0,0);
cl.set(forward_heading);
//inv_cam.invert();
int ns = g1.v.length;
float ndx,ndy,ndz,dx,dy,shifts;
PMatrix3D inv_cam = new PMatrix3D(g3.camera);
if(hoverNode != null) {
hoverNode.hover = 0;
hoverNode.radius/=1.618;
hoverNode = null;
}
PVector ndt = new PVector(), ndp = new PVector();
for(int i = 0; i < ns;i++) {
Graph.Vertex nd = g1.v[i];
ndp.set(nd.pos);
ndp.add(pos);
ndp.sub(cl);
cz = ndp.mag();
//ndt.set(ndp);
inv_cam.mult(ndp, ndt);
ndx = (((ndt.x))); ndy = (((ndt.y))); ndz = (((ndt.z)));
//applet
//float shifts = (float)((height-64)/(cz-ndp.getZ()));
shifts = ((2*height-112)/(cz-ndz));
dx = mx - ndx*shifts;
dy = my - ndy*shifts;
/**
currCameraMatrix = new PMatrix3D(g3.camera);
camera();
fill(nd.color);
rect(ndx*shifts+width/2,ndy*shifts+height/2,nd.radius*shifts,nd.radius*shifts);
g3.camera = currCameraMatrix;
//popMatrix();
**/
result = shifts*nd.radius*nd.radius > dx*dx + dy*dy;
if(result) {
if(hoverNode != null) {
hoverNode.radius /= 1.618;
hoverNode.hover = 0;
hoverNode = null;
}
hoverNode = nd;
nd.hover = 1;
nd.radius *= 1.618;
}
}
}
@Override
public void draw() {
in_a_control = 0;
background(0);
draw_grid();
g1.draw();
//currCameraMatrix = new PMatrix3D(g3.camera);
//camera();
//if(matrix_panel_active != 0)
// draw_matrix_panel();
//draw_controls();
//g3.camera = currCameraMatrix;
update_heading();
}
public void draw_ev(int index, ArrayList y, float xc, float yc, int sz ) {
rectMode(CORNER);
strokeWeight(1);
stroke(360,255,250,255);
noFill();
rect(xc-sz-3,yc-105,sz,105);
plot_v(y, xc+3, yc, sz, -1, true);
}
public void draw_grid() {
int linum = lines.size();
for(int i = 0; i < linum;i++) {
Line lin = lines.get(i);
lin.draw();
}
}
public void draw_instructions() {
float th = 1.618f*th_constant;
float xo = width/8;
float yo = height/4;
textSize(20);
fill(0,0,50,150);
rectMode(CORNER);
rect(xo,yo,screenWidth*2/3,22*th);
rectMode(CENTER);
fill(120,250,250,230);
text("k - toggle directed",xo+33,yo+th);
text(", - layout",xo+33,yo+2*th);
text("b - re-box",xo+33,yo+3*th);
text("f - display an xml or xml map file",xo+33,yo+4*th);
text("j - highlight connected component (use with d)",xo+33,yo+5*th);
text("p - highlight all paths. To use: select a vertex, toggle p, hover or select another vertex",xo+33,yo+6*th);
text("esc - quit",xo+33,yo+7*th);
text("r - new random graph",xo+33,yo+8*th);
text("mouse : left-drag to rotate, centre-button-drag to translate, right-drag to zoom",xo+33,yo+9*th);
text("mouse : click to select/unselect, double click to unselect all",xo+33,yo+10*th);
text("mouse : triple click to reset model.",xo+33,yo+11*th);
text("h - toggle Focus mode",xo+33,yo+12*th);
text("e - toggle edges display",xo+33,yo+13*th);
text("v - toggle vertices display",xo+33,yo+14*th);
text("i - toggle hide mode (click on a vertext to hide it)",xo+33,yo+15*th);
text(" when off, clicking on partially displayed vertices unhides their neighbours",xo+33,yo+16*th);
text("left menu panel - control of matrices chosen for layout : adjacency, laplacian, shortest distance",xo+33,yo+17*th);
text("bottom menu panel - control of edge length, vertext size",xo+33,yo+18*th);
text(" toggle size norming (normed by default), color range",xo+33,yo+19*th);
text(" toggle color norming (normed by default)",xo+33,yo+20*th);
text("right menu panel - view of eigen values (left), and first 5 eigenvectors",xo+33,yo+21*th);
}
public void draw_matrix_panel() {
float m1x = (longest == 1)? 53 : 53;
float m1y = (longest==1)? height-253 : 53;
show_matrix_f( 0, m1x, m1y, mpa_sz );
float m2x = (longest == 1)? width/2 : 53;
float m2y = (longest==1)? height-253 : height/2-100;
show_matrix_f( 1, m2x, m2y, mpl_sz );
float m3x = (longest == 1)? width-253 : 53;
float m3y = (longest==1)? height-253 : height-253;
show_matrix_f( 2, m3x, m3y, mpd_sz );
}
public void dvals() {
pos = new PVector(0,0,0);
lmx = 0.0f; lmy = 0.0f;
//int boxnum = boxes.size();
forward_heading = new PVector(250,10,250);
straight_up = new PVector(0,1,0);
straight_down = new PVector(0,-1,0);
straight_left = new PVector(-1,0,0);
straight_right = new PVector(1,0,0);
straight_forward = new PVector(0,0,1);
straight_back = new PVector(0,0,-1);
make_normals();
//cam.lookAt(forward_heading.x, forward_heading.y, forward_heading.z, 1.0f);
camera(0,0,0, forward_heading.x, forward_heading.y, forward_heading.z, 0.0f, 1.0f, 0.0f);
}
public void input() {
float mx = mouseX;
float my = mouseY;
//if(result < height*height/4 ) {
if(mouseLookOn==1)
cursor(CROSS);
else
cursor(HAND);
mx = map(mx, 0, width, -1, 1);
my = map(my, 0, height, -1, 1);
//}
//else {
// cursor(HAND);
// return;
//}
float xang = mx * Math.abs(mx) / (10*PI);
float yang = my * Math.abs(my) / (12*PI);
if(mouseLookOn==1) {
right_heading.mult(speed*sin(xang));
forward_heading.mult(cos(xang));
forward_heading.add(right_heading);
straight_up.mult(speed*sin(yang));
forward_heading.mult(cos(yang));
forward_heading.add(straight_up);
}
//cam.lookAt(forward_heading.x, forward_heading.y, forward_heading.z, 1.0f);
camera(0,0,0, forward_heading.x, forward_heading.y, forward_heading.z, 0.0f, 1.0f, 0.0f);
forward_heading.normalize();
update_normals();
forward_heading.mult(speed);
}
/**
public void draw_touchpads ( ) {
float cz = (float)cam.getDistance();
float[] pos = cam.getPosition();
float[] la = cam.getLookAt();
float[] cam_rots = cam.getRotations();
peasy.org.apache.commons.math.geometry.PVector cl = new peasy.org.apache.commons.math.geometry.PVector(la[0],la[1],la[2]);
peasy.org.apache.commons.math.geometry.PVector cp = new peasy.org.apache.commons.math.geometry.PVector(-pos[0],-pos[1],-pos[2]);
Rotation inv_cam = new Rotation(RotationOrder.ZYX, -cam_rots[2], -cam_rots[1], -cam_rots[0]);
int ns = g1.nodes.size();
for(int i = 0; i < ns;i++) {
Node nd = (Node)g1.nodes.get(i);
if(nd == null)
continue;
peasy.org.apache.commons.math.geometry.PVector ndp = new peasy.org.apache.commons.math.geometry.PVector(nd.position.x,nd.position.y,nd.position.z);
ndp = inv_cam.applyTo(ndp.subtract(cl));
fill(nd.selectcolor);
float ndx = (float)(((ndp.x)));
float ndy = (float)(((ndp.y)));
float ndz = (float)(((ndp.z)));
// for applet
//float shifts = 1.0f;
//if(online)
// float shifts = (float)((height-64)/(cz-ndp.z));
//else
float shifts = (float)((height-100)/(cz-ndp.z));
rect((float)(ndx*shifts+width/2.0),(float)(ndy*shifts+height/2.0),(float)nd.radius*shifts, (float)nd.radius*shifts);
text(nd.num+"",(float)(ndx*shifts+width/2.0),(float)ndy*shifts+height/2.0-nd.radius*shifts/1.618);
}
}
**/
/**
public void draw_texts ( ) {
float cz = (float)cam.getDistance();
float[] pos = cam.getPosition();
float[] la = cam.getLookAt();
float[] cam_rots = cam.getRotations();
peasy.org.apache.commons.math.geometry.PVector cl = new peasy.org.apache.commons.math.geometry.PVector(la[0],la[1],la[2]);
peasy.org.apache.commons.math.geometry.PVector cp = new peasy.org.apache.commons.math.geometry.PVector(-pos[0],-pos[1],-pos[2]);
Rotation inv_cam = new Rotation(RotationOrder.ZYX, -cam_rots[2], -cam_rots[1], -cam_rots[0]);
int ns = g1.nodes.size();
for(int i = 0; i < ns;i++) {
Node nd = (Node)g1.nodes.get(i);
if(nd == null)
continue;
if(nd.selected + nd.hovered == 0)
continue;
if(nd.label.length() + nd.special.length() == 0)
continue;
peasy.org.apache.commons.math.geometry.PVector ndp = new peasy.org.apache.commons.math.geometry.PVector(nd.position.x,nd.position.y,nd.position.z);
ndp = inv_cam.applyTo(ndp.subtract(cl));
fill(nd.selectcolor);
float ndx = (float)(((ndp.x)));
float ndy = (float)(((ndp.y)));
float ndz = (float)(((ndp.z)));
// for applet
//float shifts = 1.0f;
//if(online)
// float shifts = (float)((height-64)/(cz-ndp.z));
//else
float shifts = (float)((height-100)/(cz-ndp.z));
strokeWeight(1);
stroke(color(0,0,255,255));
textSize(20);
float tw = textWidth(nd.label) <textWidth(nd.special) ? textWidth(nd.special)*1.2f : textWidth(nd.label)*1.2f;
float th = textAscent();
//textSize(10);
fill(0,0,50,255);
rectMode(CORNER);
float tsx = tw*0.309;
float tsh = th*0.618;
rect((float)(ndx*shifts+width/2.0f)+sbxs,(float)ndy*shifts+height/2.0f-th+sbys, tw*1.618, 3.236*th);
rectMode(CENTER);
fill(color(0,0,255,200));
text(nd.label,(float)(ndx*shifts+width/2.0f)+tsx+sbxs,(float)ndy*shifts+height/2.0f+sbys+tsh);
textSize(14);
text(nd.special,(float)(ndx*shifts+width/2.0f)+tsx+sbxs,(float)ndy*shifts+height/2.0f+sbys+tsh+th);
if(nd.partial_display >= 0) {
if(nd.storage_type == nd.MEM_STORAGE)
text(" +" + nd.undirectededges.size() );
else if(nd.storage_type == nd.LEGACY_STORAGE)
text(" +" + nd.serial.getChildCount() );
}
}
}
**/
@Override
public void keyPressed(){
if(key != CODED)
switch(key) {
case('w'):case('W'):direction |=FORWARD; last_direction = FORWARD; break;
case('d'):case('D'):direction |=RIGHTWARD; last_direction = RIGHTWARD; break;
case('s'):case('S'):direction |=BACKWARD; last_direction = BACKWARD; break;
case('a'):case('A'):direction |=LEFTWARD; last_direction = LEFTWARD; break;
case(' '):direction |=UPWARD; last_direction = UPWARD; break;
case('c'):case('C'):direction |=DOWNWARD; last_direction = DOWNWARD; break;
case('r'):case('R'):
cs.reEmbedWithSameFilter();
break;
case('1'):
cs.basicMatrixEmbed();
break;
case('2'):
cs.basicMatrixProjectedEmbed();
break;
case('3'):
cs.eigeneeringEmbed();
break;
case('4'):
cs.randomFilterEmbed();
break;
case('['):
cs.offset = cs.offset - 1;
if(cs.offset < 0)
cs.offset = 0;
//println(cs.offset);
cs.reEmbedWithSameFilter();
break;
case(']'):
cs.offset = cs.offset + 1;
if(cs.offset > cs.g1.v.length-5)
cs.offset = 0;
//println(cs.offset);
cs.reEmbedWithSameFilter();
break;
case('`'):case('~'):
mouseLookOn ^= 1;
break;
case('v'):case('V'):
verticesOn ^= 1;
break;
case('b'):case('B'):
cs.boxit();
break;
case('e'):case('E'):
edgesOn ^= 1;
break;
}
else {
switch(keyCode) {
case(SHIFT):
if(speed > MIN_SPEED) {
speed = MIN_SPEED;
break;
}
}
}
}
@Override
public void keyReleased(){
if(key != CODED)
switch(key) {
case('w'):case('W'):direction ^=FORWARD; last_direction = FORWARD; break;
case('d'):case('D'):direction ^=RIGHTWARD; last_direction = RIGHTWARD; break;
case('s'):case('S'):direction ^=BACKWARD; last_direction = BACKWARD; break;
case('a'):case('A'):direction ^=LEFTWARD; last_direction = LEFTWARD; break;
case(' '):direction ^=UPWARD; last_direction = UPWARD; break;
case('c'):case('C'):direction ^=DOWNWARD; last_direction = DOWNWARD; break;
}
else
switch(keyCode) {
case(SHIFT):
if(speed < MAX_SPEED) {
speed = MAX_SPEED;
break;
}
}
}
public void make_grid() {
float spacing = 100;
lines = new ArrayList((int)(2*(wd+dp)/spacing + 1));
stroke(200,255,255,255);
for(float i = -wd*2; i <= wd*2; i+=spacing) {
Line nl = new Line(this, i,0,-2*wd,i,0,2*wd);
nl.posa = pos;
lines.add(nl);
}
for(float i = -wd*2; i <= wd*2; i+= spacing) {
Line nl = new Line(this, -2*wd,0,i,2*wd,0,i);
nl.posa = pos;
lines.add(nl);
}
stroke(0,0,0,255);
}
public void make_normals() {
back_heading = new PVector(-forward_heading.x, -forward_heading.y, -forward_heading.z);
up_heading = new PVector(0,speed,0);
down_heading = new PVector(0,-speed,0);
right_heading = forward_heading.cross(up_heading);
left_heading = forward_heading.cross(down_heading);
}
@Override
public void mouseClicked() {
if(mouseEvent.getClickCount() == 3) {
dvals();
}
}
@Override
public void mouseDragged(){}
@Override
public void mouseMoved() {
if(matrix_panel_active==1)
check_matrices_pass();
//check_nodes_pass();
}
@Override
public void mousePressed() {
if(matrix_panel_active==1)
check_matrices_press();
//check_nodes_press();
}
@Override
public void mouseReleased() { }
public void plot_v(ArrayList y, float xc, float yc, int sz, int highlight, boolean anchored) {
int ys = y.size();
int xstep = sz/ys;
if(xstep < 1)
xstep = 1;
float lx = xc;
float ly = yc;
if(anchored) {
strokeWeight(1);
stroke(360,255,250,255);
line(lx,ly,lx+ys*xstep,ly);
}
for(int i = 0; i < ys;i++) {
float vi = (Float)y.get(i);
float xi = xc+i*xstep;
float yi = yc-vi;
strokeWeight(1);
stroke(255,255,255,255);
if(!anchored) {
if(i > 0)
line(lx,ly,xi,yi);
}
else
line(lx,ly,xi,yi);
if(i == highlight)
rect(xi,yi,7,7);
lx = xi;
ly = yi;
}
if(anchored) {
line(lx,ly,xc+ys*xstep,yc);
}
}
@Override
public void setup() {
// For applet
face = createFont("MingLiU",40);
textSize(20);
th_constant = textAscent();
textFont(face);
int xw = (screenWidth*15)/16;
int yh = (screenHeight*7)/8;
//applet
//m_sz = 100;
//m_sz_actv = 110;
//m_actv_delta = (m_sz_actv-m_sz)/2.0f;
//if(!online)
//size(xw,yh, P3D);
//else
size(900,568,P3D);
sbxs = width/50;
sbys = -height/50;
rectMode(CENTER);
colorMode(HSB,360,255,255,255);
longest = width < height ? 1 : 0;
scalar = width < height ? width : height;
//tthea = tan(scalar);
g3 = (PGraphics3D)g;
background(0);
cs = new Visionary(this);
cs.randomGraph();
cs.randomizeLayoutColorSize();
g1 = cs.g1;
dvals();
attach_graph_to_local_coordinate_master();
make_normals();
make_grid();
update_heading();
// not for applet
}
public void setup_matrix_panel() {
mpa_sz = m_sz;
mpa_sd = 0;
mpl_sz = m_sz;
mpl_sd = 0;
mpd_sz = m_sz_actv;
mpd_sd = 1;
}
public void show_matrix_f( int index, float xc, float yc, int sz ) {
PGraphics m=null; // = (PGraphics)g1.matrix_cache.get(index);
if(m != null) {
if(sz == m_sz) {
// image((PImage)g1.matrix_cache.get(index), xc, yc, sz, sz);
}
else if(sz == m_sz_actv) {
// image((PImage)g1.matrix_cache.get(index), xc, yc, sz, sz);
}
}
else {
rectMode(CORNER);
fill(0,0,128,128);
rect(xc+m_sz/5,yc+m_sz/5,m_sz/2,m_sz/2);
rectMode(CENTER);
}
}
public void silence_grid( ) {
}
public void update_heading() {
input();
check_nodes_pass();
update_v();
}
public void update_normals() {
back_heading.set(-forward_heading.x, -forward_heading.y, -forward_heading.z);
up_heading.set(0,speed,0);
down_heading.set(0,-speed,0);
straight_left.set(-1,0,0);
straight_right.set(1,0,0);
straight_forward.set(0,0,1);
straight_back.set(0,0,-1);
straight_up.set(0,1,0);
straight_down.set(0,-1,0);
right_heading = forward_heading.cross(straight_up);
left_heading = forward_heading.cross(straight_down);
back_heading.mult(speed);
right_heading.mult(speed);
left_heading.mult(speed);
}
/**
public void check_nodes_pass() {
boolean result = false;
float cz = (float)cam.getDistance();
float[] la = cam.getLookAt();
float[] cam_rots = cam.getRotations();
float mx = mouseX-width/2.0f;
float my = mouseY-height/2.0f;
peasy.org.apache.commons.math.geometry.PVector cl = new peasy.org.apache.commons.math.geometry.PVector(la[0],la[1],la[2]);
Rotation inv_cam = new Rotation(RotationOrder.ZYX, -cam_rots[2], -cam_rots[1], -cam_rots[0]);
int ns = g1.nodes.size();
float ndx,ndy,ndz,dx,dy,shifts;
Node lh = null;
float lhndz = -height;
if(g1.hoverNode != null) {
if(g1.allPaths == 1 || (g1.pointToPointOn == 1))
g1.silence_all_paths(1);
retract_activity(g1.hoverNode);
g1.hoverNode.hovered = 0;
g1.hoverNode = null;
}
for(int i = 0; i < ns;i++) {
Node nd = (Node)g1.nodes.get(i);
if(nd == null)
continue;
peasy.org.apache.commons.math.geometry.PVector ndp = new peasy.org.apache.commons.math.geometry.PVector(nd.position.x,nd.position.y,nd.position.z);
ndp = inv_cam.applyTo(ndp.subtract(cl));
ndx = (float)(((ndp.x))); ndy = (float)(((ndp.y))); ndz = (float)(((ndp.z)));
//applet
//float shifts = (float)((height-64)/(cz-ndp.z));
shifts = (float)((height-100)/(cz-ndz));
dx = (float)mx - ndx*shifts;
dy = (float)my - ndy*shifts;
if(g1.hoverOnlyOn == 0)
result = shifts*shifts*nd.radiusq > dx*dx + dy*dy;
else
result = 0.5*shifts*nd.radiusq > dx*dx + dy*dy;
if(result) {
if(ndz > lhndz && (cz-ndz) > 40) {
lh = nd;
lhndz = ndz;
}
}
}
if(lh != null) {
Node nd = lh;
if(g1.hoverNode != null) {
if(g1.allPaths == 1 || g1.pointToPointOn == 1)
g1.silence_all_paths(1);
g1.hoverNode.hovered = 0;
retract_activity(g1.hoverNode);
g1.hoverNode = null;
}
if(g1.allPaths == 1 || (g1.pointToPointOn == 1 && g1.directedOn == 0))
g1.select_all_paths(nd,1);
else if(g1.selectNode != null && g1.pointToPointOn == 1 && g1.directedOn == 1) {
g1.select_all_paths(g1.selectNode, nd,1);
}
g1.hoverNode = nd;
nd.hovered = 1;
spread_activity(nd);
}
}
**/
public void update_selected() {
int ns = g1.v.length;
for(int i = 0; i < ns;i++) {
Graph.Vertex n = g1.v[i];
if(n == null)
continue;
}
}
public void update_v() {
switch(direction) {
case FORWARD:pos.sub(forward_heading); break;
case BACKWARD:pos.sub(back_heading); break;
case LEFTWARD:pos.sub(left_heading); break;
case RIGHTWARD:pos.sub(right_heading); break;
case UPWARD:pos.add(up_heading); break;
case DOWNWARD:pos.add(down_heading); break;
case FORWARD|LEFTWARD:pos.sub(forward_heading);pos.sub(left_heading); break;
case FORWARD|RIGHTWARD:pos.sub(forward_heading);pos.sub(right_heading); break;
case BACKWARD|LEFTWARD:pos.sub(back_heading);pos.sub(left_heading); break;
case BACKWARD|RIGHTWARD:pos.sub(back_heading);pos.sub(right_heading); break;
case UPWARD|FORWARD:pos.sub(forward_heading);pos.add(up_heading); break;
case UPWARD|BACKWARD:pos.sub(back_heading);pos.add(up_heading); break;
case UPWARD|LEFTWARD:pos.add(up_heading);pos.sub(left_heading); break;
case UPWARD|RIGHTWARD:pos.add(up_heading);pos.sub(right_heading); break;
case DOWNWARD|FORWARD:pos.sub(forward_heading);pos.add(down_heading); break;
case DOWNWARD|BACKWARD:pos.sub(back_heading);pos.add(down_heading); break;
case DOWNWARD|LEFTWARD:pos.add(down_heading);pos.sub(left_heading); break;
case DOWNWARD|RIGHTWARD:pos.add(down_heading);pos.sub(right_heading); break;
case UPWARD|FORWARD|RIGHTWARD:pos.sub(forward_heading);pos.add(up_heading);pos.sub(right_heading);break;
case UPWARD|FORWARD|LEFTWARD:pos.sub(forward_heading);pos.add(up_heading);pos.sub(left_heading); break;
case UPWARD|BACKWARD|RIGHTWARD:pos.sub(back_heading);pos.add(up_heading);pos.sub(right_heading); break;
case UPWARD|BACKWARD|LEFTWARD:pos.sub(back_heading);pos.add(up_heading);pos.sub(left_heading); break;
case DOWNWARD|FORWARD|LEFTWARD:pos.sub(forward_heading);pos.add(down_heading);pos.sub(left_heading); break;
case DOWNWARD|FORWARD|RIGHTWARD:pos.sub(forward_heading);pos.add(down_heading);pos.sub(right_heading); break;
case DOWNWARD|BACKWARD|LEFTWARD:pos.sub(back_heading);pos.add(down_heading);pos.sub(left_heading); break;
case DOWNWARD|BACKWARD|RIGHTWARD:pos.sub(back_heading);pos.add(down_heading);pos.sub(right_heading); break;
case LEFTWARD|RIGHTWARD:
if(last_direction==LEFTWARD)
pos.sub(left_heading);
else
pos.sub(right_heading);
break;
case FORWARD|BACKWARD:
if(last_direction==FORWARD)
pos.sub(forward_heading);
else
pos.sub(back_heading);
break;
case UPWARD|DOWNWARD:
if(last_direction==UPWARD)
pos.add(up_heading);
else
pos.add(down_heading);
break;
}
if(pos.y < height/4)
pos.y = height/4;
}
}
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import processing.core.PVector;
// The local image of the global concept
public class Graph { // implements Comparable<Graph> .... just joking
public class MatrixTypeIndex {
public static final int ADJACENCY = 0;
public static final int DEGREE = 1;
public static final int ADJACENCY_2STEP = 2;
public static final int DEGREE_1STEP = 3;
public static final int DEGREE_2STEP = 4;
public static final int SEIDELADJACENCY = 5;
public static final int AUGMENTEDADJACENCY = 6;
public static final int SHAREOFDEGREE = 7;
public static final int MINIMUMDISTANCEMATRIX = 8;
public static final int GENERALIZEDADJACENCY = 9;
public static final int WEIGHTEDDEGREE = 10;
public static final int WEIGHTEDADJACENCY = 11;
public static final int SPIELMANLAZYWALK = 12;
public static final int LAZYWALKSOFTINVERSE = 13;
public static final int NSTEPWALKS = 14;
public static final int TRANSITIONMATRIXRANDOMWALK = 15;
public static final int LAPLACIAN = 16;
public static final int SOFTNORMALIZEDLAPLACIAN = 17;
public static final int HARDNORMALIZEDLAPLACIAN = 18;
public static final int COMMUTETIME = 19;
public static final int DEFORMEDLAPLACIAN = 20;
public static final int PROJECTIONMATRIX = 21;
public static final int MAXIMUMDISTANCEMATRIX = 22;
public static final int MATRIX_FIELD_COUNT = 23;
}
public class EdgeBattle {
public static final int ESCHER = -8;
public static final int ONEFROMTHREE = -5;
public static final int TOTALFAIL = -2;
public static final int DEPENDSWHICHWAYYOULOOKATIT = 1;
public static final int PARALLEL = 4;
}
public class Vertex {
public int id; public PVector pos, posa; public int color; public float radius; public int hover;
public Vertex() {
id = 0;
hover = 0;
pos = new PVector(0,0,0);
}
public void draw() {
aspektWorld.pushMatrix();
aspektWorld.fill(color);
aspektWorld.stroke(color);
aspektWorld.strokeWeight(aspektWorld.SMALL_STROKE);
aspektWorld.translate(posa.x + pos.x,posa.y + pos.y, posa.z + pos.z);
aspektWorld.box(radius);
aspektWorld.popMatrix();
}
}
public class Edge {
public final int edgeColorB = aspektWorld.color(141,250,250,250);
public Vertex a; public Vertex b; public int[] strength;
public Edge( Vertex av, Vertex bv ) {
a = av; b = bv; strength = new int[6];
}
public void draw() {
if(a.hover==1) {
aspektWorld.strokeWeight(aspektWorld.BIG_STROKE);
aspektWorld.stroke(edgeColorB);
}
else {
aspektWorld.strokeWeight(aspektWorld.SMALL_STROKE);
aspektWorld.stroke(a.color);
}
aspektWorld.line(a.posa.x + a.pos.x,a.posa.y + a.pos.y,a.posa.z + a.pos.z,
a.posa.x + b.pos.x,a.posa.y + b.pos.y,a.posa.z + b.pos.z);
}
}
public HashMap<Vertex, Set<Edge>> edgesByVertexA, edgesByVertexB;
public HashMap<Vertex,Integer> numbering;
public HashMap<Edge,Integer> edgeNumbering;
public Matrix[] matrix;
public Vertex[] v;
public Edge[] e;
public float volume;
private final AspektWorld aspektWorld;
public Graph(AspektWorld aspektWorld) {
this.aspektWorld = aspektWorld;
edgesByVertexA = new HashMap<Vertex, Set<Edge>>();
edgesByVertexB = new HashMap<Vertex, Set<Edge>>();
matrix = new Matrix[MatrixTypeIndex.MATRIX_FIELD_COUNT];
}
public HashMap<Graph.Vertex,Integer> numbering() {
if(numbering != null)
return numbering;
int vertices = edgesByVertexA.size();
Set<Graph.Vertex> verticeSet = edgesByVertexA.keySet();
Iterator<Graph.Vertex> vertexIterator = verticeSet.iterator();
numbering = new HashMap<Graph.Vertex,Integer> ();
int i = vertices;
while(--i >= 0)
numbering.put(vertexIterator.next(), new Integer(i));
return numbering;
}
public HashMap<Graph.Edge, Integer> edgeNumbering() {
if(edgeNumbering != null)
return edgeNumbering;
Set<Graph.Vertex> verticeSet = edgesByVertexA.keySet();
Iterator<Graph.Vertex> vertexIterator = verticeSet.iterator();
edgeNumbering = new HashMap<Edge,Integer> ();
int edges = 0;
while(vertexIterator.hasNext()) {
Graph.Vertex stupidFuckFace = vertexIterator.next();
Set<Graph.Edge> fuckingMoron = edgesByVertexA.get(stupidFuckFace);
Iterator<Graph.Edge> edgeIterator = fuckingMoron.iterator();
while(edgeIterator.hasNext()) {
Edge e = edgeIterator.next();
if(!edgeNumbering.containsKey(e))
edgeNumbering.put(e,edges++);
}
}
return edgeNumbering;
}
public void addVertex( Vertex a ) {
if(edgesByVertexA.containsKey(a))
return;
edgesByVertexA.put( a, new HashSet<Edge>() );
edgesByVertexB.put( a, new HashSet<Edge>() );
}
public void cutVertex( Vertex a ) {
edgesByVertexA.remove( a );
edgesByVertexB.remove( a );
}
public void addEdge( Edge e ) {
edgesByVertexA.get(e.a).add(e);
edgesByVertexB.get(e.b).add(e);
}
public void cutEdge( Edge e ) {
edgesByVertexA.get(e.a).remove(e);
edgesByVertexB.get(e.b).remove(e);
}
public float degree ( Vertex v ) {
int index = numbering.get(v);
return matrix[Graph.MatrixTypeIndex.DEGREE].entry[index][index];
}
public void crystallizeGraph() {
numbering();
edgeNumbering();
Set<Vertex> vertices = numbering.keySet();
v = new Vertex[vertices.size()];
vertices.toArray(v);
Set<Edge> edges = edgeNumbering.keySet();
e = new Edge[edges.size()];
edges.toArray(e);
}
public void draw() {
// TODO Auto-generated method stub
int i = e.length;
if(aspektWorld.edgesOn==1)
while(--i >= 0)
e[i].draw();
else
while(--i >= 0)
if(e[i].a.hover==1)
e[i].draw();
i = v.length;
if(aspektWorld.verticesOn==1)
while(--i >= 0)
v[i].draw();
}
}
import processing.core.PVector;
class Line {
/**
*
*/
private final AspektWorld aspektWorld;
public PVector another, posa;
public PVector yetanother;
public int lc;
public Line( AspektWorld aspektWorld, float ax, float ay, float az, float tx, float ty, float tz ) {
this.aspektWorld = aspektWorld;
another = new PVector(ax,ay,az);
yetanother = new PVector(tx,ty,tz);
lc = this.aspektWorld.color (180,200,200,200);
}
public void draw() {
this.aspektWorld.stroke(lc);
this.aspektWorld.strokeWeight(aspektWorld.MIDDLE_STROKE);
this.aspektWorld.line(posa.x+another.x,posa.y+another.y,posa.z+another.z,posa.x+yetanother.x,posa.y+yetanother.y,posa.z+yetanother.z);
}
}
import java.util.Arrays;
public class Matrix {
public int rows, columns, shortest, symmetric;
public int i, j;
public static final int NONE = -1;
public static final int ZERO = 0;
public static final int IDENTITY = 1;
public static final int COUNTERIDENTITY = 2;
public static final int ONES = 3;
public static final int entry_changed = 1;
public static final int det_changed = 2;
public static final int eigen_changed = 4;
public static final int norms_changed = 8;
public static final int lu_changed = 16;
public static final int inverse_changed = 32;
public static final int minmax_changed = 64;
public static final int all_changed = 127;
public static final float ZEROF = 0.0f;
public static final float IDENTITYF = 1.0f;
public float eij;
public float entry[][];
public float trace;
public float det;
public float[] minmax;
public float eigenvector[][];
public float eigenvalue[];
public float krylovs[][];
public float norms[];
public float lu_entry[][];
public float inverse_entry[][];
public int updates;
public int eigens_calculated;
public int norms_calculated;
public Matrix(int TYPE, int rows_num, int columns_num) {
rows = rows_num;
columns = columns_num;
symmetric = rows == columns ? 1 : 0;
shortest = rows < columns ? rows : columns;
updates = all_changed;
switch (TYPE) {
case (NONE):
case (ZERO):
make_zero();
break;
case (IDENTITY):
make_identity();
break;
case (COUNTERIDENTITY):
make_counterIdentity();
break;
case (ONES):
make_ones();
break;
}
eigenvector = new float[rows][columns];
eigenvalue = new float[rows];
}
public void show() {
int i = rows;
while(--i >= 0)
show_v(entry[i]);
System.out.println(rows + "," + columns);
}
public static void show_v (float[] v) {
int i = v.length;
while(--i >= 0)
System.out.print(v[i] + " ");
System.out.println();
}
public float[] minmax() {
if (minmax!=null && (updates & minmax_changed) == 0)
return minmax;
minmax = new float[2];
if (rows == 0 || columns == 0)
return minmax;
minmax[0] = minmax[1] = entry[0][0];
i = rows;
while (--i >= 0) {
j = columns;
while (--j >= 0) {
eij = entry[i][j];
if (eij > minmax[1])
minmax[1] = eij;
else if (eij < minmax[0])
minmax[0] = eij;
}
}
updates &= (all_changed ^ minmax_changed);
return minmax;
}
public float[] minmaxRow(int row) {
float[] minmaxRow = new float[2];
if (rows < row || columns == 0)
return minmaxRow;
minmaxRow[0] = minmaxRow[1] = entry[row][0];
j = columns;
while (--j >= 0) {
eij = entry[row][j];
if (eij > minmaxRow[1])
minmaxRow[1] = eij;
else if (eij < minmaxRow[0])
minmaxRow[0] = eij;
}
return minmaxRow;
}
public float trace() {
i = shortest;
trace = 0.0f;
while (--i >= 0)
trace += entry[i][i];
return trace;
}
public void make_zero() {
entry = new float[rows][columns];
updates &= (all_changed ^ entry_changed);
}
public void make_identity() {
entry = new float[rows][columns];
i = shortest;
while (--i >= 0)
entry[i][i] = IDENTITYF;
updates &= (all_changed ^ entry_changed);
}
public void make_counterIdentity() {
entry = new float[rows][columns];
i = shortest;
while (--i >= 0)
entry[i][shortest - i - 1] = IDENTITYF;
updates &= (all_changed ^ entry_changed);
}
public void make_ones() {
entry = new float[rows][columns];
i = rows;
while (--i >= 0) {
Arrays.fill(entry[i], IDENTITYF);
}
}
public static void copy(float[][] source, float[][] dest) {
int si = dest.length;
int sj = dest[0].length;
while (--si >= 0) {
System.arraycopy(source[si], 0, dest[si], 0, sj);
}
}
public Matrix(float[][] entries) {
rows = entries.length;
if (rows != 0)
columns = entries[0].length;
else
columns = 0;
symmetric = rows == columns ? 1 : 0;
shortest = rows < columns ? rows : columns;
entry = new float[rows][columns];
Matrix.copy(entries,entry);
eigenvector = new float[rows][columns];
eigenvalue = new float[rows];
updates = all_changed;
}
public Matrix(Matrix expired) {
rows = expired.rows;
columns = expired.columns;
entry = new float[rows][columns];
eigenvector = new float[rows][columns];
eigenvalue = new float[rows];
Matrix.copy(expired.entry, entry);
Matrix.copy(expired.eigenvector, eigenvector);
System.arraycopy(expired.eigenvalue, 0, eigenvalue, 0,
eigenvalue.length);
shortest = expired.shortest;
}
public Matrix transpose() {
int j = columns;
int i = rows;
Matrix transpose = new Matrix(Matrix.NONE, j, i);
while (--j >= 0) {
while (--i >= 0) {
transpose.entry[j][i] = entry[i][j];
}
i = rows;
}
return transpose;
}
}
import java.util.ArrayList;
import processing.core.PVector;
public class Visionary {
public final static int VERTICESONSCREEN = 60;
public final static int NOMOD = 0;
public final static int MOD = 1;
public int[] gridsz;
public int mc = 0;
public Matrix lrf;
public Matrix gridv;
public int etype = 0;
public int offset = 0;
public final AspektWorld aspektWorld;
public Graph g1;
public Adventurer bg;
public Visionary(AspektWorld aw) {
aspektWorld = aw;
gridsz = new int[] { 70,140,210,280,350,420,490,560,630,700 };
lrf = new Matrix(Matrix.IDENTITY,VERTICESONSCREEN, VERTICESONSCREEN);
}
public Graph randomGraph() {
Graph g = new Graph(aspektWorld);
ArrayList<Graph.Vertex> knownVertices = new ArrayList<Graph.Vertex>();
int i = VERTICESONSCREEN;
while(--i >= 0) {
Graph.Vertex v = g.new Vertex();
g.addVertex(v);
knownVertices.add(v);
int k,j;
k = VERTICESONSCREEN-i;
j = (int) aspektWorld.random(k);
while(--j >= 0) {
Graph.Vertex randomNeighbour = knownVertices.get((int)(aspektWorld.random(k)));
Graph.Edge newEdge = g.new Edge(v, randomNeighbour);
g.addEdge(newEdge);
}
}
g.crystallizeGraph();
g1 = g;
bg = new Adventurer(g1);
g1 = bg.g;
return g;
}
public int vertexToGrid(Graph.Vertex v) {
int vn = g1.numbering.get(v);
if(gridv == null) {
float maxGrid = gridsz.length;
Matrix nd = new Matrix(g1.matrix[Graph.MatrixTypeIndex.DEGREE]);
Arithmetician.scaleToRange(nd, 0.0f, maxGrid-1 );
gridv = nd;
}
return (int)gridv.entry[vn][vn];
}
public void boxit() {
int i = g1.v.length;
while(--i >= 0) {
Graph.Vertex v = g1.v[i];
int grid = vertexToGrid(v);
v.pos.set(boxCoords(nextBox(v.pos, grid), grid));
}
}
public int[] nextBox( PVector start, int grid ) {
int sz = gridsz[grid];
int x = (int)(start.x/sz); int y = (int)(start.y/sz); int z = (int)(start.z/sz);
return new int[] { x,y,z };
}
public PVector boxCoords( int[] boxp, int grid ) {
int sz = gridsz[grid];
PVector j = new PVector(boxp[0]*sz,boxp[1]*sz,boxp[2]*sz);
return j;
}
public Graph randomizeLayoutColorSize( ) {
int i = g1.v.length;
while(--i >= 0) {
Graph.Vertex v = g1.v[i];
v.color = aspektWorld.color(aspektWorld.random(360),200,200,200);
v.radius = 3 + aspektWorld.random(40);
v.pos.set(aspektWorld.random(aspektWorld.width)-aspektWorld.width/2, -aspektWorld.random(aspektWorld.height), aspektWorld.random(aspektWorld.height)-aspektWorld.height/2);
}
i = g1.e.length;
while(--i >= 0) {
Graph.Edge e = g1.e[i];
}
return g1;
}
public int[] randomi( int sz, int max ) {
int[] ri = new int[sz];
while(--sz >= 0)
ri[sz] = (int)aspektWorld.random(max);
return ri;
}
public int min(int a, int b) {
return a < b ? a : b;
}
public void embedPlain(Matrix f) {
Matrix ef = new Matrix(f);
Arithmetician.scaleToRangeRow(ef, offset+0, -aspektWorld.height*2, aspektWorld.height*2);
Arithmetician.scaleToRangeRow(ef, offset+1, -aspektWorld.height*2, aspektWorld.height*2);
Arithmetician.vectorScalarAdd(ef.entry[offset+1], -aspektWorld.height*2);
Arithmetician.scaleToRangeRow(ef, offset+2, -aspektWorld.height, aspektWorld.height*2);
Arithmetician.scaleToRangeRow(ef, offset+3, 0, 360);
Arithmetician.scaleToRangeRow(ef, offset+4, 10, 70);
int count = min(ef.shortest,g1.v.length);
while(--count >= 0 ) {
Graph.Vertex v = g1.v[count];
v.pos.x = ef.entry[offset+0][count];
v.pos.y = ef.entry[offset+1][count];
v.pos.z = ef.entry[offset+2][count];
v.color = aspektWorld.color(ef.entry[offset+3][count],200,200,200);
v.radius = ef.entry[offset+4][count];
}
}
public void embedProjected(Matrix f) {
Matrix ef;
ef = Algebraicist.projectedMatrix(f, 0.5f);
//ef = Algebraicist.eigenvectors(ef);
Arithmetician.scaleToRangeRow(ef, offset+0, -aspektWorld.height*2, aspektWorld.height*2);
Arithmetician.scaleToRangeRow(ef, offset+1, -aspektWorld.height*2, aspektWorld.height*2);
Arithmetician.vectorScalarAdd(ef.entry[offset+1], -aspektWorld.height*2);
Arithmetician.scaleToRangeRow(ef, offset+2, -aspektWorld.height, aspektWorld.height*2);
Arithmetician.scaleToRangeRow(ef, offset+3, 0, 360);
Arithmetician.scaleToRangeRow(ef, offset+4, 10, 70);
int count = min(ef.shortest,g1.v.length);
while(--count >= 0 ) {
Graph.Vertex v = g1.v[count];
v.pos.x = ef.entry[offset+0][count];
v.pos.y = ef.entry[offset+1][count];
v.pos.z = ef.entry[offset+2][count];
v.color = aspektWorld.color(ef.entry[offset+3][count],200,200,200);
v.radius = ef.entry[offset+4][count];
}
}
public void embedProjectedEigeneered(Matrix f) {
Matrix ef;
ef = Algebraicist.projectedMatrix(f, 0.5f);
Arithmetician.PowerIterationDeflate(ef, 5+offset, 0.00000001, 0);
ef = new Matrix(ef.eigenvector);
Arithmetician.scaleToRangeRow(ef, offset+0, -aspektWorld.height*2, aspektWorld.height*2);
Arithmetician.scaleToRangeRow(ef, offset+1, -aspektWorld.height*2, aspektWorld.height*2);
Arithmetician.vectorScalarAdd(ef.entry[offset+1], -aspektWorld.height*2);
Arithmetician.scaleToRangeRow(ef, offset+2, -aspektWorld.height, aspektWorld.height*2);
Arithmetician.scaleToRangeRow(ef, offset+3, 0, 360);
Arithmetician.scaleToRangeRow(ef, offset+4, 10, 70);
int count = min(ef.shortest,g1.v.length);
while(--count >= 0 ) {
Graph.Vertex v = g1.v[count];
v.pos.x = ef.entry[offset+0][count];
v.pos.y = ef.entry[offset+1][count];
v.pos.z = ef.entry[offset+2][count];
v.color = aspektWorld.color(ef.entry[offset+3][count],200,200,200);
v.radius = ef.entry[offset+4][count];
}
}
public static void show_v (float[] v) {
int i = v.length;
while(--i >= 0)
System.out.print(v[i] + " ");
System.out.println();
}
public Graph randomFilterEmbed() {
offset = 0;
if(bg == null)
bg = new Adventurer(g1);
if(g1.matrix[0] == null)
bg.make_all_basic_matrices();
// Better random filter code
Matrix rf = bg.make_random_filter((int)aspektWorld.random(Graph.MatrixTypeIndex.MATRIX_FIELD_COUNT),
(int)aspektWorld.random(Graph.MatrixTypeIndex.MATRIX_FIELD_COUNT),
(int)aspektWorld.random(13),
(int)aspektWorld.random(Arithmetician.MatrixOperation.MatrixBinary.BINARY_FIELD_COUNT));
// Older rf code
/**
* Matrix rf = bg.make_random_Matrix_filter(NOMOD,
randomi(5, Graph.MatrixTypeIndex.MATRIX_FIELD_COUNT),
randomi(5, Arithmetician.MatrixOperation.MatrixUnary.UNARY_FIELD_COUNT),
randomi(4, Arithmetician.MatrixOperation.MatrixBinary.BINARY_FIELD_COUNT),
new int[] { 0, 0 }, new float[] { aspektWorld.random(10), 10+aspektWorld.random(20), 20+aspektWorld.random(30) });
**/
etype = 4;
lrf = rf;
embedProjectedEigeneered(rf);
return g1;
}
public Graph basicMatrixEmbed() {
offset = 0;
if(bg == null)
bg = new Adventurer(g1);
if(g1.matrix[0] == null)
bg.make_all_basic_matrices();
//System.out.println(mc);
Matrix rf = g1.matrix[mc];
mc ++;
if(mc >= Graph.MatrixTypeIndex.MATRIX_FIELD_COUNT)
mc = 0;
lrf = rf;
etype = 1;
embedPlain(rf);
return g1;
}
public Graph basicMatrixProjectedEmbed() {
offset = 0;
if(bg == null)
bg = new Adventurer(g1);
if(g1.matrix[0] == null)
bg.make_all_basic_matrices();
//System.out.println(mc);
Matrix rf = g1.matrix[mc];
mc ++;
if(mc >= Graph.MatrixTypeIndex.MATRIX_FIELD_COUNT)
mc = 0;
lrf = rf;
etype = 2;
embedProjected(rf);
return g1;
}
public Graph eigeneeringEmbed() {
offset = 0;
if(bg == null)
bg = new Adventurer(g1);
if(g1.matrix[0] == null)
bg.make_all_basic_matrices();
//System.out.println(mc);
Matrix rf = g1.matrix[mc];
mc ++;
if(mc >= Graph.MatrixTypeIndex.MATRIX_FIELD_COUNT)
mc = 0;
lrf = rf;
etype = 3;
embedProjectedEigeneered(rf);
return g1;
}
public void reEmbedWithSameFilter() {
// TODO Auto-generated method stub
switch(etype) {
case(1):
embedPlain(lrf);
break;
case(2):
embedProjected(lrf);
break;
case(3):case(4):default:
embedProjectedEigeneered(lrf);
}
}
}
Every city starts with a plan, right? Not really, but in this case we're starting with a flat one. 1,2,3,4 cycles through 4 classes of layout. FPS controls. c is straight down. Holding b/B cycles through through different filters.