java - Google Foobar Challenge Level 3: doomsday-fuel [closed] - java

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed last month.
Improve this question
I have been working on this java code for the doomsday-fuel problem which deals with the absorbing markov chains. It has passed every test except for test four. Is there any particular type of input I may have missed while testing my code? I have only about 12 hours left. I have tested four one dimensional arrays and am curious as to if this test failure is somehow a precision error or something else.
Context:
Making fuel for the LAMBCHOP's reactor core is a tricky process because of the exotic matter involved. It starts as raw ore, then during processing, begins randomly changing between forms, eventually reaching a stable form. There may be multiple stable forms that a sample could ultimately reach, not all of which are useful as fuel.
Commander Lambda has tasked you to help the scientists increase fuel creation efficiency by predicting the end state of a given ore sample. You have carefully studied the different structures that the ore can take and which transitions it undergoes. It appears that, while random, the probability of each structure transforming is fixed. That is, each time the ore is in 1 state, it has the same probabilities of entering the next state (which might be the same state). You have recorded the observed transitions in a matrix. The others in the lab have hypothesized more exotic forms that the ore can become, but you haven't seen all of them.
Write a function solution(m) that takes an array of array of nonnegative ints representing how many times that state has gone to the next state and return an array of ints for each terminal state giving the exact probabilities of each terminal state, represented as the numerator for each state, then the denominator for all of them at the end and in simplest form. The matrix is at most 10 by 10. It is guaranteed that no matter which state the ore is in, there is a path from that state to a terminal state. That is, the processing will always eventually end in a stable state. The ore starts in state 0. The denominator will fit within a signed 32-bit integer during the calculation, as long as the fraction is simplified regularly.
public static int[] returnFractionPair(double x) {
double tolerance = 1.0E-14;//Handles the extent of precision used
double numerator=1;//Kept as one because initially the decimal may be greater than zero
double numeratorStorage=0;
double denominator=0;
double denominatorStorage=1;//prevents division by zero
double decimal = x;
double comparison = 0;
do {
double flooredDecimal = (double)(int)decimal;//Floors decimal
double aux = numerator;//Sets auxilary to be the numerator
numerator =(flooredDecimal*numerator)+numeratorStorage;
numeratorStorage = aux;
aux = denominator;
denominator = (flooredDecimal*denominator)+denominatorStorage;
denominatorStorage = aux;
decimal = 1/(decimal-flooredDecimal);
comparison = x-(numerator/denominator);
} while( returnAbs(comparison) > (x*tolerance) );//Tests if the difference between the initial decimal and this new numerator/denominator is greater than that of x multiplied by the level of tolerance it has
int[] res = new int[]{(int)numerator, (int)denominator};
return res;
}
public static double returnAbs(double value){
if(value < 0){
value *= -1;
}
return value;
}
public static int getLCD(int[][] fractions){
int num = 0;
int den = 1;
int lcd = 1;
for(int i = 0; i < fractions.length; i++){
lcd *= fractions[i][den];
}
for(int i = 2; i < lcd; i++){
boolean foundLeastCommon = true;
for(int j = 0; j < fractions.length; j++){
if( (double)( i%fractions[j][den] ) != 0){
foundLeastCommon = false;
}
}
if(foundLeastCommon == true){
lcd = i;
return lcd;
}
}
return lcd;
}
public static double[] returnRowSums(int[][] matrix){
//Assume all values in matrix are positive
double[] sumsOfEachRow = new double[matrix.length];
for(int i = 0; i < matrix.length; i++){
for(int j = 0; j < matrix.length; j++){
sumsOfEachRow[i] += matrix[i][j];
}
}
return sumsOfEachRow;
}
public static double returnMatrixCellSum(double[] row, double[] column){//Assume row size == column size.
if(row.length != column.length){
return 0;
}
double sum = 0;
for(int i = 0; i < row.length; i++){
sum += (column[i] * row[i]);
}
return sum;
}
public static int[] returnRearrangedIndices(double[] sumsOfEachRow){
int[] indicesOfRearrangedMatrix = new int[sumsOfEachRow.length];
int indicesIndex = 0;
for(int i = 0; i < sumsOfEachRow.length; i++){
if(sumsOfEachRow[i] <= 1){
indicesOfRearrangedMatrix[indicesIndex] = i;
indicesIndex++;
}//TerminalStates first
}
for(int i = 0; i < sumsOfEachRow.length; i++){
if(sumsOfEachRow[i] > 1){
indicesOfRearrangedMatrix[indicesIndex] = i;
indicesIndex++;
}
}
return indicesOfRearrangedMatrix;
}
public static double[][] subtractMatrix(double[][] matrix1, double[][] matrix2){//assumes matrices are of same dimensions
double[][] matrix3 = new double[matrix1.length][matrix1.length];
for(int i = 0; i < matrix1.length;i++){
for(int j = 0; j < matrix1[i].length; j++){
matrix3[i][j] = matrix1[i][j] - matrix2[i][j];
}
}
return matrix3;
}
public static double[][] rotateMatrix(double[][] matrix){
double[][] rotatedMatrix = new double[matrix[0].length][matrix.length];
for(int i = 0; i < rotatedMatrix.length;i++){
for(int j = 0; j < rotatedMatrix[0].length; j++){
rotatedMatrix[i][j] = matrix[j][i];
}
}
return rotatedMatrix;
}
public static double[][] getRemainingValues(double[][] matrix, int rowIgnored, int columnIgnored){
double[][] newMatrix = new double[matrix.length-1][matrix.length-1];
int iC = 0;
int iR = 0;
for(int k = 0; k < matrix.length; k++){
if(k != rowIgnored){
iR = 0;
for(int j = 0; j < matrix[k].length;j++){
if(j != columnIgnored){
newMatrix[iC][iR] = matrix[k][j];
iR++;
}
}
iC++;
}
}
return newMatrix;
}
public static double getDeterminant(double[][] matrix){
//uses top rows only
double determinant = 0;
if(matrix.length == 1 && matrix[0].length == 1){
return matrix[0][0];
}
boolean negative = false;
double[][] newMatrix = new double[matrix.length-1][matrix.length-1];
for(int i = 0; i < matrix.length; i++){
newMatrix = getRemainingValues(matrix, 0, i);
if(negative == false){
determinant += matrix[0][i]*getDeterminant(newMatrix);
negative = true;
}else{
determinant -= matrix[0][i]*getDeterminant(newMatrix);
negative = false;
}
//System.out.println(determinant);
}
return determinant;
}
public static double[][] getMinorMatrix(double[][] matrix){
double[][] newMatrix = new double[matrix.length][matrix.length];
double[][] remainderMatrix;
if(matrix.length-1 != 0){
remainderMatrix = new double[matrix.length-1][matrix.length-1];
}else{
remainderMatrix = new double[matrix.length][matrix.length];
}
for(int i = 0; i < newMatrix.length;i++){
for(int j = 0; j < newMatrix.length;j++){
remainderMatrix = getRemainingValues(matrix, i, j);
newMatrix[i][j] = getDeterminant(remainderMatrix) + 0.0;//Prevent -0.0 float values
}
}
return newMatrix;
}
public static double[][] divideMatrixByScalar(double[][] matrix, double scalar){
double[][] newMatrix = new double[matrix.length][matrix[0].length];
newMatrix = matrix;
for(int i = 0; i < matrix.length; i++){
for(int j = 0; j < matrix[i].length;j++){
newMatrix[i][j] /= scalar;
}
}
return newMatrix;
}
public static double[][] invertMatrix(double[][] matrix){
double[][] minorMatrix = new double[matrix.length][matrix.length];
if(minorMatrix.length == 2){
minorMatrix = matrix;
double temp = minorMatrix[0][0];
minorMatrix[0][0] = minorMatrix[1][1];
minorMatrix[1][1] = temp;
minorMatrix[0][1] *= -1;
minorMatrix[0][1] += 0;
minorMatrix[1][0] *= -1;
minorMatrix[1][0] += 0;
for(int i = 0; i < minorMatrix.length; i++){
for(int j = 0; j < minorMatrix[i].length; j++){
System.out.print(minorMatrix[i][j] + " ");
}
System.out.print("\n");
}
}else{
minorMatrix = getMinorMatrix(matrix);
System.out.println("Getting minorMatrix");
for(int i = 0; i < minorMatrix.length; i++){
for(int j = 0; j < minorMatrix[i].length; j++){
System.out.print(minorMatrix[i][j] + " ");
}
System.out.print("\n");
}
boolean isNegative = false;
System.out.println("Getting adjoint of minorMatrix");//Not doing things correctly
for(int i = 0; i < minorMatrix.length;i++){
for(int j = 0; j < minorMatrix[i].length;j++){
if(isNegative == true){
minorMatrix[i][j] *= -1;
minorMatrix[i][j] += 0;
isNegative = false;
}else{
isNegative = true;
}
System.out.print(minorMatrix[i][j] + " ");
}
if(minorMatrix[i].length % 2 == 0){
if(isNegative == true){
isNegative = false;
}else{
isNegative = true;
}
}
System.out.print("\n");
}
minorMatrix = rotateMatrix(minorMatrix);//rotates the minorMatrix
}
double determinant = getDeterminant(matrix);
System.out.println(determinant);
if(determinant != 0){
minorMatrix = divideMatrixByScalar(minorMatrix, determinant);
System.out.println("Result");
for(int i = 0; i < minorMatrix.length; i++){
for(int j = 0; j < minorMatrix[i].length; j++){
System.out.print(minorMatrix[i][j] + " ");
}
System.out.print("\n");
}
return minorMatrix;//Inverse is good
}else{
return matrix;
}
}
public static double[][] returnUnabsorbedToUnabsorbed(double[][] matrix, int terminalStates){//Assumes matrix layers go from absorbed to unabsorbed
double[][] unabsorbedToUnabsorbed = new double[matrix.length-terminalStates][matrix.length-terminalStates];
int uIndex = 0;
int uuIndex = 0;
for(int i = terminalStates; i < matrix.length;i++){
uuIndex = 0;
for(int j = terminalStates; j < matrix.length;j++){
unabsorbedToUnabsorbed[uIndex][uuIndex] = matrix[i][j];
uuIndex++;
}
uIndex++;
}
return unabsorbedToUnabsorbed;
}
public static double[][] returnUnabsorbedToAbsorbed(double[][] matrix, int terminalStates){//Assumes matrix layers go from absorbed to unabsorbed
double[][] unabsorbedToAbsorbed = new double[matrix.length-terminalStates][terminalStates];
int uIndex = 0;
int uuIndex = 0;
for(int i = terminalStates; i < matrix.length;i++){
uuIndex = 0;
for(int j = 0; j < terminalStates;j++){
unabsorbedToAbsorbed[uIndex][uuIndex] = matrix[i][j];
uuIndex++;
}
uIndex++;
}
return unabsorbedToAbsorbed;
}
public static double[][] getFundamental(double[][] matrix){
double[][] modifiedMatrix = new double[matrix.length][matrix[0].length];
modifiedMatrix = matrix;
double[][] identity = new double[matrix.length][matrix.length];
for(int i = 0; i < identity.length; i++){
for(int j = 0;j < identity[i].length;j++){
if(i == j){
identity[i][j] = 1;
}else{
identity[i][j] = 0;
}
}
}
modifiedMatrix = subtractMatrix(identity, modifiedMatrix);//Modified matrix is returning properly
/*System.out.println("Getting matrix to be inverted");
for(int i = 0; i < modifiedMatrix.length; i++){
for(int j = 0; j < modifiedMatrix[i].length; j++){
System.out.print(modifiedMatrix[i][j] + " ");
}
System.out.print("\n");
}*/
modifiedMatrix = invertMatrix(modifiedMatrix);//Problem here(?)
return modifiedMatrix;
}
public static double[][] multiplyMatrix(double[][] matrix1, double[][] matrix2){//Assume all rows are equal.
double[][] result = new double[matrix1.length][matrix2[0].length];
double[][] rotatedM2 = new double[matrix2[0].length][matrix2.length];
rotatedM2 = rotateMatrix(matrix2);
for(int i = 0; i < result.length;i++){
for(int j = 0; j < result[i].length; j++){
result[i][j] = returnMatrixCellSum(matrix1[i], rotatedM2[j]);
//RotateMatrix does not increase matrix sums by how it should be
}
}
return result;
}
public static int[] algorithm(int[][] matrix, int startingPoint){
if(matrix.length == 0){
return new int[]{0, 1};
}
if(matrix.length == 1){
int[] ans = new int[matrix.length+1];
for(int i = 0; i < ans.length;i++){
ans[i] = 1;
}
for(int i = 0; i < ans.length; i++){
System.out.println(ans[i]);
}
return ans;
}
double[] sumsOfEachRow = new double[matrix.length];
sumsOfEachRow = returnRowSums(matrix);
double[][] probMatrix = new double[matrix.length][matrix.length];
int terminalStates = 0;//Number of terminal states
for(int i = 0; i < probMatrix.length; i++){
for(int j = 0; j < probMatrix[i].length; j++){
if(sumsOfEachRow[i] != 0){
probMatrix[i][j] = (double)matrix[i][j];
probMatrix[i][j] /= sumsOfEachRow[i];
}else{
probMatrix[i][j] = 0;
}
}
}
boolean startingIsTerminal = false;
for(int i = 0; i < probMatrix.length;i++){
boolean foundOne = false;
for(int j = 0; j < probMatrix[i].length;j++){
if(probMatrix[i][j] == 1 && i == j){
terminalStates++;
foundOne = true;
if(i == startingPoint){
startingIsTerminal = true;
}
}
}
if(foundOne == false){
if(sumsOfEachRow[i] == 0){
terminalStates++;
}
}
}
if( (sumsOfEachRow[startingPoint] == 0) || startingIsTerminal == true){
int[] ans = new int[terminalStates+1];
for(int i = 0; i < terminalStates;i++){
if(i != startingPoint){
ans[i] = 0;
}else{
ans[i] = 1;
}
}
ans[terminalStates] = 1;
for(int i = 0; i < ans.length; i++){
System.out.println(ans[i]);
}
return ans;
}
int[] indicesOfRearrangedMatrix = new int[probMatrix.length];
indicesOfRearrangedMatrix = returnRearrangedIndices(sumsOfEachRow);
double[][] rearranged = new double[probMatrix.length][probMatrix[0].length];
for(int i = 0; i < matrix.length; i++){
for(int j = 0; j < matrix[i].length; j++){
rearranged[i][j] = probMatrix[indicesOfRearrangedMatrix[i]][indicesOfRearrangedMatrix[j]];
System.out.print(rearranged[i][j] + " ");
}
System.out.print("\n");
}//Get rearranged matrix divided
System.out.println("Matrix rearranged");
double[][] unabsorbedToUnabsorbed = new double[probMatrix.length-terminalStates][probMatrix.length-terminalStates];
unabsorbedToUnabsorbed = returnUnabsorbedToUnabsorbed(rearranged, terminalStates);//Get Unabsorbed Matrix
for(int i = 0; i < unabsorbedToUnabsorbed.length; i++){
for(int j = 0; j < unabsorbedToUnabsorbed[i].length; j++){
System.out.print(unabsorbedToUnabsorbed[i][j] + " ");
}
System.out.print("\n");
}
System.out.println("unabsorbedToUnabsorbed");
double[][] unabsorbedToAbsorbed = new double[probMatrix.length-terminalStates][terminalStates];
unabsorbedToAbsorbed = returnUnabsorbedToAbsorbed(rearranged, terminalStates);
for(int i = 0; i < unabsorbedToAbsorbed.length; i++){
for(int j = 0; j < unabsorbedToAbsorbed[i].length; j++){
System.out.print(unabsorbedToAbsorbed[i][j] + " ");
}
System.out.print("\n");
}
System.out.println("unabsorbedToAbsorbed");
double[][] fundamental = new double[unabsorbedToUnabsorbed.length][unabsorbedToUnabsorbed.length];
fundamental = getFundamental(unabsorbedToUnabsorbed);//Gets fundamental
double[][] probResult = multiplyMatrix(fundamental, unabsorbedToAbsorbed);
System.out.println("ProbResult got");
for(int i = 0; i < probResult.length; i++){
for(int j = 0; j < probResult[i].length; j++){
System.out.print(probResult[i][j] + " ");
}
System.out.print("\n");
}
int[][] fractionPairs = new int[terminalStates][2];
for(int i = 0; i < probResult[startingPoint].length; i++){
fractionPairs[i] = returnFractionPair(probResult[startingPoint][i]);
}
int lcd = getLCD(fractionPairs);
int[] ans = new int[terminalStates+1];
int num = 0;
int den = 1;
for(int i = 0; i < fractionPairs.length;++i){
int newNumerator = (lcd/fractionPairs[i][den]) * fractionPairs[i][num];
ans[i] = newNumerator;
}
ans[ans.length-1] = lcd;
for(int i = 0; i < ans.length; i++){
System.out.println(ans[i]);
}
return ans;
}
public static int[] solution(int[][] m) {
return algorithm(m, 0);
}
}

Related

Finding the mode of an array Java

I've got to find the mode of an array. I am a bit embarrassed to admit that I've been stuck on this for a day. I think I've overthought it a bit - my method just gets longer and longer. The real issue that I keep running into is that when there isn't one mode (two numbers appear with the same frequency) I need to return Double.NaN.
Here's what I've tried:
private double[] data = {1, 1, 2, 2, 2, 3, 4, 5, 5, 5, 5, 5, 6, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9};
if(data.length != 0){
double maxValue = -1;
int maxCount = 0;
for(int i = 0; i < data.length; i++) {
int count = 0;
for(int j = 0; j < data.length; j++) {
if(data[j] == data[i]) {
count++;
}
}
if(count > maxCount) {
maxValue = (int) data[i];
maxCount = count;
}
}
return maxValue;
}else{
return Double.NaN;
}
This actually returns the mode, but it can't deal with two modes. Here's my most recent attempt, but it's only half complete:
private double[] data = {1, 1, 2, 2, 2, 3, 4, 5, 5, 5, 5, 5, 6, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9};
public void mode(){
int[] frequency = new int[data.length];
double[] vals = new double[data.length];
for(int i = 0; i < data.length; i++){
frequency[i] = occursNumberOfTimes(data[i]);
}
boolean uniform = false;
for(int g = 0; g < frequency.length && !uniform; g++){
if(frequency[0] != frequency[g]){
uniform = false;
}
int[] arr = new int[frequency.length-1];
for(int j = 1; j < frequency.length; j++){
if(frequency[j] > frequency[j-1]){
int mod = 0;
for(int k = 0; k < arr.length; k++){
if(k == j){
mod += 1;
arr[k] = frequency[k + mod];
}else{
arr[k] = frequency[k + mod];
}
}
}
}
frequency = arr;
}
}
private int occursNumberOfTimes(double value){
int count = 0;
for(int i = 0; i < data.length; i++){
if(data[i] == value){
count++;
}
}
return count;
}
I sorta got lost in the second try, I just can't sort out how to deal with multiple modes. I've written out my thoughts, but I just don't know how. I can't use anything from the Arrays class, which is why I'm lost.
Does it have to be efficient? If not:
double maxValue = -1.0d;
int maxCount = 0;
for (int i = 0; i < data.length; ++i) {
double currentValue = data[i];
int currentCount = 1;
for (int j = i + 1; j < data.length; ++j) {
if (Math.abs(data[j] - currentValue) < epsilon) {
++currentCount;
}
}
if (currentCount > maxCount) {
maxCount = currentCount;
maxValue = currentValue;
} else if (currentCount == maxCount) {
maxValue = Double.NaN;
}
}
System.out.println("mode: " + maxValue);
You could track the two most common elements as was suggested in the comments, but another approach is to keep a boolean flag that indicates if the current most common element is unique. Then:
For each array element e, obtain its count as you're currently doing.
If that count is greater than the current max, set the the most common element (seen so far) to e and set the "unique" flag to true.
Otherwise, if that count is equal to the current max, set the "unique" flag to false.
At the end, just return the mode if "unique" is true, otherwise return NaN.
Here's my long, dumb solution. It works! It's a very roundabout way of getting the mode, but I'm really happy it works. I used the advice I got from some comments and looked at it differently. It was a frustrating few hours, but here it is:
public double mode2(){
if(data.length != 0){
int[] counts = new int[data.length];
double[] vals = new double[data.length];
for(int l = 0; l < data.length; l++){
counts[l] = 1;
}
for(int i = 0; i < data.length; i++){
for(int j = 0; j < data.length; j++){
if((data[i] == data[j]) && (i != j)){
vals[i] = data[i];
counts[i] += 1;
}
}
}
for(int i = 0; i < data.length; i++){
for(int j = 0; j < data.length; j++){
if((vals[i] == vals[j]) && (i != j)){
vals[i] = 0;
counts[i] = 0;
}
}
}
int counter = 0;
for(int k = 0; k < data.length; k++){
if(counts[k] != 0){
counts[counter] = counts[k];
vals[counter] = vals[k];
counter++;
}
}
int[] compactCounts = new int[counter];
double[] compactVals = new double[counter];
for(int k = 0; k < counter; k++){
if(counts[k] != 0){
compactCounts[k] = counts[k];
compactVals[k] = vals[k];
}else{
break;
}
}
for(int g = 1; g < compactVals.length; g++){
if(compactCounts[g] > compactCounts[g-1]){
compactCounts[g-1] = 0;
compactVals[g-1] = 0;
}
}
for(int g = 0; g < compactVals.length-1; g++){
if(compactCounts[g] > compactCounts[g+1]){
compactCounts[g+1] = 0;
compactVals[g+1] = 0;
}
}
int counterTwo = 0;
for(int k = 0; k < compactCounts.length; k++){
if(compactCounts[k] != 0){
compactCounts[counterTwo] = compactCounts[k];
compactVals[counterTwo] = vals[k];
counterTwo++;
}
}
int[] compactCountsTwo = new int[counterTwo];
double[] compactValsTwo = new double[counterTwo];
for(int k = 0; k < counterTwo; k++){
if(counts[k] != 0){
compactCountsTwo[k] = compactCounts[k];
compactValsTwo[k] = compactVals[k];
}else{
break;
}
}
//now populated compactTwos
//We're now setting some lesser values to 0
for(int g = 1; g < compactValsTwo.length; g++){
if(compactCountsTwo[g] > compactCountsTwo[g-1]){
compactCountsTwo[g-1] = 0;
compactValsTwo[g-1] = 0;
}
}
//now setting other lesser values to 0
for(int g = 0; g < compactValsTwo.length-1; g++){
if(compactCountsTwo[g] > compactCountsTwo[g+1]){
compactCountsTwo[g+1] = 0;
compactValsTwo[g+1] = 0;
}
}
//calling methods to shorten our arrays by dropping indexes populated by zeroes
compactValsTwo = doubleTruncator(compactValsTwo);
compactCountsTwo = intTruncator(compactCountsTwo);
//now setting some lesser values to 0
for(int g = 1; g < compactValsTwo.length; g++){
if(compactCountsTwo[g] > compactCountsTwo[g-1]){
compactCountsTwo[g-1] = 0;
compactValsTwo[g-1] = 0;
}
}
//now setting other lesser values to 0
for(int g = 0; g < compactValsTwo.length-1; g++){
if(compactCountsTwo[g] > compactCountsTwo[g+1]){
compactCountsTwo[g+1] = 0;
compactValsTwo[g+1] = 0;
}
}
//calling methods to shorten our arrays by dropping indexes populated by zeroes
compactValsTwo = doubleTruncator(compactValsTwo);
compactCountsTwo = intTruncator(compactCountsTwo);
if(compactValsTwo.length > 1){
return Double.NaN;
}else{
return compactValsTwo[0];
}
}else{
System.out.println("ISSUE");
return Double.NaN;
}
}
public double[] doubleTruncator(double[] a){
int counter = 0;
for(int k = 0; k < a.length; k++){
if(a[k] != 0){
a[counter] = a[k];
counter++;
}
}
double[] b = new double[counter];
for(int i= 0; i < counter; i++){
if(a[i] != 0){
b[i] = a[i];
}else{
break;
}
}
return b;
}
public int[] intTruncator(int[] a){
int counter = 0;
for(int k = 0; k < a.length; k++){
if(a[k] != 0){
a[counter] = a[k];
counter++;
}
}
int[] b = new int[counter];
for(int i= 0; i < counter; i++){
if(a[i] != 0){
b[i] = a[i];
}else{
break;
}
}
return b;
}
Big thanks to everybody who helped. I know it's not great (certainly not as good as the answer from #Perdi Estaquel), but I'm happy that I managed to do it.

This is a hill cipher im getting an error

This is for a hill cipher program that I am coding for my class. I am getting an error message that tell me that state .class is excpeted. The error occurs on line 51. If you can help that would be great and explain why I am getting this error in the first place.
inv_temp[i][j] = determinant(temp,order-1)/float(res);
import java.io.*;
import java.util.*;
class main{
public static int n = 3;
double determinant(double[][] array,int order){
if (order == 1)
return array[0][0];
if (order == 2)
return (array[0][0]*array[1][1] - array[0][1]*array[1][0]);
double answer = 0;
double[][] temp = new double[n][n];
for (int i = 0; i < order; i++){
for (int j = 1; j < order; j++){
int t = 0;
for (int k = 0; k < order; k++){
if (k == i){
t++;
continue;
}
else{
temp[j-1][k-t] = array[j][k];
}
}
}
if (i % 2 == 0)
answer += array[0][i]*determinant(temp,order-1);
else
answer -= array[0][i]*determinant(temp,order-1);
}
return answer;
}
public static double[][] inverse(double[][] inv,double[][] array,int order){
double res = determinant(array,order);
double[][] inv_temp = new double[n][n];
if (res != 0){
double[][] temp = new double[n][n];
for (int i = 0; i < order; i++){
for (int j = 0; j < order; j++){
int t = 0;
for (int k = 0; k < order; k++){
if (k == i){
t++;
continue;
}
int tt = 0;
for (int l = 0; l < order; l++){
if (l == j){
tt++;
continue;
}
temp[k-t][l-tt] = array[k][l];
}
}
if (i % 2 == 0){
if (j % 2 == 0){
inv_temp[i][j] = determinant(temp,order-1)/float(res);
}
else{
inv_temp[i][j] = -1*(determinant(temp,order-1))/res;
}
}
else{
if (j % 2 == 0){
inv_temp[i][j] = -1*(determinant(temp,order-1))/res;
}
else{
inv_temp[i][j] = (determinant(temp,order-1))/res;
}
}
}
}
for (int i = 0; i < order; i++){
for (int j = 0; j < order; j++){
inv[j][i] = inv_temp[i][j] % 26;
}
}
return inv;
}
}
public static void main(String[] args){
}
}

memoized matrix chain multiplication in Java

I feel like I'm really close with this implementation of a memoized matrix chain algorithm in Java, but I'm getting an array out of bounds error on line 45 and 53. These, for some reason, really seem to mess me up. Maybe there's something I'm continually messing up with, but I dunno, obviously. Can anyone help me out?
public class Lab2 {
//fields
static int p[];
static int m[][];
final static int INFINITY = 999999999;
public Lab2() {
//
}
public static void main(String[] args) {
Lab2 lab2 = new Lab2();
Lab2.m = new int[7][7];
Lab2.p = new int[7];
Lab2.p[0] = 20;
Lab2.p[1] = 8;
Lab2.p[2] = 4;
Lab2.p[3] = 25;
Lab2.p[4] = 30;
Lab2.p[5] = 5;
Lab2.p[6] = 10;
int n = Lab2.p.length-1;
//initialize m array to infinity
for (int i = 1; i <= n; i++){
for (int j = i; j <= n; j++){
Lab2.m[i][j]= INFINITY;
}
}
lab2.lookUpChain(m, p, 1, n);
for (int i = 0; i < 8; i++){
for (int j = 0; j < 8; j++){
System.out.println(m[i][j]);
}
}
}
//
public int lookUpChain(int m[][], int p[], int i, int j ){
if (m[i][j]<INFINITY){
return m[i][j];
}
if (i == j){
m[i][j] = 0;
}
else{
for (int k = i; k <= j; i++){
int q = (lookUpChain(m,p,i,k)) + (lookUpChain(m,p,k+1,j)) + (p[i]*p[k]*p[j]);
if (q < m[i][j]){
m[i][j] = q;
}
}
}
return m[i][j];
}
}
else{
for (int k = i; k <= j; i++)
Change to:
else{
for (int k = i; k <= j; k++) // change i to k

Inverse 2D FFT is outputting correct values in wrong order

My 2D FFT algorithm is outputting the correct values, but they are in the wrong order. For example, for input:
1050.0 1147.0 1061.0 1143.0
1046.0 1148.0 1118.0 1073.0
1072.0 1111.0 1154.0 1101.0
1078.0 1101.0 1106.0 1062.0
Taking the FFT, and then inverse FFT results in:
1050.0 1143.0 1061.0 1147.0
1078.0 1062.0 1106.0 1101.0
1072.0 1101.0 1154.0 1111.0
1046.0 1073.0 1118.0 1148.0
You can see that if you flip the last 3 columns horizontally, then the last 3 rows vertically, the data will be correct. As far as I can tell this is true for all input sizes so it's an easy (albeit hacky) fix. I am however worried about about computational time of the fix because I may have to perform this on 1024x1024 or even 2048x2048 images in the future.
I am fairly confident that my 1D FFT algorithm doFFT() is correct, and I am getting the expected values for the forward 2D FFT. It is just the inverse 2D FFT that is causing me trouble.
Does anyone see where my error is?
Code
private static double[] cose;
private static double[] sin;
public static void main(String[] args) {
float[][] img = new float[][]{
{ 1050.0f, 1147.0f, 1061.0f, 1143.0f},
{ 1046.0f, 1148.0f, 1118.0f, 1073.0f},
{ 1072.0f, 1111.0f, 1154.0f, 1101.0f},
{ 1078.0f, 1101.0f, 1106.0f, 1062.0f}
};
int size = img.length;
System.out.println("Image");
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
System.out.print(img[i][j] + "\t");
}
System.out.println();
}
Complex[][] fft = fft2D(toComplex(img), false);
Complex[][] inverse = fft2D(fft, true);
System.out.println("\nInverse");
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
System.out.print(inverse[i][j].getReal() + "\t");
}
System.out.println();
}
}
public static Complex[][] fft2D(Complex[][] pixels, boolean inverse){
int size = pixels.length;
computeCosSin(size);
Complex[][] data = transpose(pixels.clone());
Complex[] temp;
// FFT of rows
for (int i = 0; i < size; i++)
{
temp = doFFT(data[i], size);
data[i] = temp;
}
// FFT of columns
for (int i = 0; i < size; i++)
{
temp = new Complex[size];
for (int j = 0; j < size; j++)
{
temp[j] = data[j][i];
}
Complex[] temp2 = doFFT(temp, size);
for (int j = 0; j < size; j++)
{
data[j][i] = temp2[j];
}
}
if (!inverse)
{
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
data[i][j] = data[i][j].divide(size*size);
}
}
}
return data;
}
public static Complex[] doFFT(Complex[] data, int size){
Complex[] temp = new Complex[size];
int j = 0;
for (int i = 0; i < size; i++) {
temp[i] = data[j];
int k = size / 2;
while ((j >= k) && (k > 0)) {
j -= k;
k /= 2;
}
j += k;
}
Complex n,m,h,f;
for(int i=0; i<size;i+=4){
n = temp[i].add(temp[i+1]);
m = temp[i+2].add(temp[i+3]);
h = temp[i].subtract(temp[i+1]);
f = temp[i+2].subtract(temp[i+3]);
Complex mult = h.add(f.multiply(Complex.I));
Complex sub = h.subtract(f.multiply(Complex.I));
temp[i] = n.add(m);
temp[i+2] = n.subtract(m);
temp[i+1] = sub;
temp[i+3] = mult;
}
int u;
for(int i=4; i< size;i<<=1){
int v = size/(i <<1);
for(int c=0; c< size;c +=i<<1){
for(int x=0; x < i; x++){
u = v*x;
double calc = temp[i+c+x].getReal()*cose[u] - temp[i+c+x].getImaginary()*sin[u];
double calc2 = temp[i+c+x].getReal()*sin[u] + temp[i+c+x].getImaginary()*cose[u];
Complex fftArray = new Complex(calc,calc2);
temp[(i+c+x)] =temp[(c+x)].subtract(fftArray);
temp[(c+x)] = temp[(c+x)].add(fftArray);
}
}
}
return temp;
}
public static Complex[][] toComplex(float[][] arr)
{
Complex[][] newArr = new Complex[arr.length][arr.length];
for (int i = 0; i < arr.length; i++)
{
for (int j = 0; j < arr.length; j++)
{
newArr[i][j] = new Complex(arr[i][j], 0.0);
}
}
return newArr;
}
public static Complex[][] transpose(Complex[][] array)
{
for (int i = 0; i < array.length; i++)
{
for (int j = i+1; j < array[i].length; j++)
{
Complex temp = array[i][j];
array[i][j] = array[j][i];
array[j][i] = temp;
}
}
return array;
}
public static void computeCosSin(int size){
double num = (2.0*Math.PI)/size;
double cos = Math.cos(num);
double sine = Math.sin(num);
cose = new double[size];
sin = new double[size];
cose[0] =1.0;
for(int i=1; i<size;i++){
cose[i] = cos*cose[i-1] + sine*sin[i-1];
sin[i] = cos*sin[i-1] - sine*cose[i-1];
}
}
}
This doesn't solve the root problem, but it does change the data I'm getting to the data I expect so it will serve my purpose for now. I do worry it will be incredibly slow on large arrays.
This function swaps row i with row N-i and then swaps every column i with column N-i, for 0 < i < N, (Assuming a square, power of 2 input array)
public Complex[][] inverseFix(Complex[][] array)
{
int size = array.length;
// Swap rows
Complex[] temp;
for (int i = 1; i < size/2; i++)
{
temp = array[i];
array[i] = array[size-i];
array[size-i] = temp;
}
// Swap columns
Complex temp2;
for (int i = 0; i < size; i++)
{
for (int j = 1; j < size/2; j++)
{
temp2 = array[i][j];
array[i][j] = array[i][size-j];
array[i][size-j] = temp2;
}
}
return array;
}

Multiplying 2d arrays(matrices) in java

My goal is to print out the Matrix when the two arrays are multiplied together. What am I doing wrong with this code? How do I get it so that it prints out the matrix? (Sorry I do not know what other details i should provide and I cannot submit this post unless I add more detail).
public class Matrices {
static int mRows = 0;
static int mCol = 0;
static int nRows = 0;
static int nCol = 0;
public static int[][] multiplyMatrices(int[][] m, int[][] n){
mRows = m.length;
mCol = m[0].length;
nRows = n.length;
nCol = n[0].length;
if(canBeMultiplied(m,n) == false){
throw new IllegalArgumentException("Cannot multiply arrays");
}
int[][] answer = new int[mRows][nCol];
for(int i = 0; i < mRows; i++){
for(int j = 0; j < nCol; j++){
for(int k = 0; k < mCol; k++){
answer[i][j] += m[i][k] * n[k][j];
}
}
}
return answer;
}
public static boolean canBeMultiplied(int[][] m, int[][]n){
mRows = m.length;
mCol = m[0].length;
nRows = n.length;
nCol = n[0].length;
if(nRows == mCol){
return true;
}
return false;
}
public static void main(String[] args) {
int[][] temp1 = {{1,2,3},{4,5,6}};
int[][] temp2 ={{1},{2},{3}};
for(int i = 0; i < mRows; i++){
for(int j = 0; j < nCol; j++){
System.out.print(multiplyMatrices(temp1,temp2)[i][j]);
}
System.out.print("\n");
}
}
}
Thanks for your help.
This could will loop through the the 2D array and print each element.
static final int ROWS = 2;
static final int COLS = 4;
int[][] a2 = new int[ROWS][COLS];
//... Print array in rectangular form
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
System.out.print(" " + a2[i][j]);
}
System.out.println("");
}

Categories

Resources