Initialize the Columns of an Array in Java - java

I have three arrays of equal lengths that I combine (as I will sort them on column c later):
double abc[][] = {
Arrays.copyOf(a, a.length),
Arrays.copyOf(b, a.length),
Arrays.copyOf(c, a.length)
};
When I call
System.out.println(Arrays.deepToString(abc));
I receieve:
[[4.0, 2.0, 1.3333333333333333, 5.0, 2.5, 1.6666666666666667 ....
However, I would prefer something like:
[[1.0, 1.0, 4.0], [2.0, 2.0, 5.0], [3.0, 3.0, 7.0]]
This is possible using double singlets
double test[][] = {{1,1,4},{2,2,5},{3,3,7}};
How can I populate/initialize three columns using three double[ ]?
EDIT:
Solution based on vojta's answer:
double abcT[][] = new double[abc[0].length][abc.length];
for (int i = 0; i < abc.length; i++) {
for (int j = 0; j < abc[0].length; j++) {
abcT[j][i] = abc[i][j];
}
}
System.out.println(Arrays.deepToString(abcT));

I think there is no one-line solution of your problem, unfortunately. You will have to use some homemade code:
static <T> T[][] createMatrix(T[]... columns) {
if (columns== null || columns.length == 0)
return new T[0][0];
int wid = columns.length;
int ht = columns[0].length;
T[][] result = new T[ht][wid];
for (int x = 0; x < wid; x++) {
for (int y = 0; y < ht; y++) {
result[y][x] = columns[x][y];
}
}
return result;
}
I hope it was useful.

I finally reached this more elegant solution:
for (int i = 0; i < a.length; i++){
abc[0][i] = a[i];
abc[1][i] = b[i];
abc[2][i] = c[i];
}
Although it is not a general solution for n[], this avoids the need to make intermediate copies of the original arrays. And then I just swap the for-loops for row and column:
for (int j = 0; j < abc[0].length; j++) {
for (int i = 0; i < abc.length; i++) {
System.out.print(abc[i][j] + " ");
}
System.out.print("\n");
}
Note: This solution does not store in the intended R:C format, but retrieves in C:R.

Related

How can i keep the same function with different argument type

Mr
I have developed this function to disply matrices.
I don't want to write the function again, perhaps i have many matrices with different arguments type.
private void displyMatrix(int matrix[][]) {
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
System.out.print(matrix[i][j] + " ");
}
System.out.println();
}
}
What happens if i have another matrix with double argument?
Do i have to write the function again, or there is another method.
Thanks
You can create method like this with help of generics.
public <T> void print(T[][] matrix) {
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
System.out.print(matrix[i][j] + " ");
}
System.out.println();
}
}
The only limitation would be, you need to use wrapper class Integer instead of primitive int.
Integer[][] integers = new Integer[][]{ new Integer[] {1, 2}};
Double[][] doubles = new Double[][]{ new Double[] {1.0, 2.0}};
print(integers);
print(doubles);

Java Array List is overriding the data added and put the last items added only

Java Array List is overriding the data added and put the last items added only.
The output expected is 1.0, 1.0, -1.0,-1.0, -1.0, 1.0,-1.0, -1.0, -1.0,-1.0, -1.0, -1.0
But, the output I get is -1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0 .
The code override the list by last array elements which is a=[-1,-1,-1,-1]. That is why all 12 elements of the list value is overridden to -1.
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args){
double sum=0; int n=0,y=0,count=0,x=1;
double []a=new double []{1,0,1};
double []b=new double [a.length];
List<double[] >mylist= new ArrayList<>();
double [][]c=new double[][]{{0,0.66,0.66},{0.66,0,0.66},{0,0.66,0}};
mylist.add(0,a);
while(n>=0 && n<4){
for (int i = 0 ; i < 3 ; i++)
for (int j = 0 ; j < a.length; j++)
{
sum=sum+(c[i][j]*a[j]);
if(j==a.length-1)
{
if(sum>0)
sum=1;
else
sum=-1;
b[y]=sum;
y++;
count++;
sum=0;
}
if(count==a.length){
mylist.add(x,b);
x++;
y=0;
count=0;
for(int k=0;k<a.length;k++){
a[k]=b[k];
}
}
}n++;
}
for (int i = 0 ; i < mylist.size(); i++)
for (int j = 0 ; j < a.length ; j++)
{
System.out.print(mylist.get(i)[j]+",");
}
}
}
Arrays in Java are passed by reference to methods, you can check this link for detailed explanation "pass by referece and pass by value" for more about Java parameter passing.
In you code, you just have multiple references of array a and array b. So that is why when their values change all initial values also change. you can use a debugger and you will see it starts changing from the second insertion of b to the ArrayList.
To fix this create a copy of array a at the beginning (whose content will not change). for each new insertion, create a temporary array to hold the values and insert them to your ArrayList.
Below is a fix
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
double sum = 0;
int n = 0, y = 0, count = 0, x = 1;
double[] a = { 1, 0, 1 };
// Create a copy of a to insert at the beginning
double[] acpy = new double[] { 1, 0, 1 };
double[] b = new double[a.length];
List<double[]> mylist = new ArrayList<>();
double[][] c = new double[][] { { 0, 0.66, 0.66 }, { 0.66, 0, 0.66 }, { 0, 0.66, 0 } };
mylist.add(0, acpy);
double[] temp ;
while (n >= 0 && n < 4) {
// this will create a new reference whenever you are about to insert a new element
temp = new double[a.length];
for (int i = 0; i < 3; i++)
for (int j = 0; j < a.length; j++) {
sum = sum + (c[i][j] * a[j]);
if (j == a.length - 1) {
if (sum > 0)
sum = 1;
else
sum = -1;
b[y] = sum;
// copy values of b for insertion to ArrayList
temp[y] = sum;
y++;
count++;
sum = 0;
}
if (count == a.length) {
mylist.add(x, temp);
x++;
y = 0;
count = 0;
for (int k = 0; k < a.length; k++) {
a[k] = b[k];
}
}
}
n++;
}
for (int i = 0; i < mylist.size(); i++)
for (int j = 0; j < a.length; j++) {
System.out.print(mylist.get(i)[j] + ",");
}
}
}

CpxObjective for general expressions: Exception Cplex with solve quadratic model

I am trying to minimize the function a quadratic function sum(sum (w*a)-v)^2
being "a" square array and "w" and "v" two vectors. "a" and "v" are known, "w" is unknown. I am using CPLEX in Java
double [][] input = {{1,2},{3,4}};
double[] result = {3,2};
//define new model
IloCplex cplex = new IloCplex();
// variables
IloNumVar[] w = new IloNumVar[input[0].length];
for (int i = 0; i < w.length; i++) {
w[i] = cplex.numVar(0.0, 1.0, IloNumVarType.Float);
}
IloNumExpr value = cplex.numExpr();
IloNumExpr objective = cplex.numExpr();
for (int i = 0; i < result.length; i++) {
for (int j = 0; j < result.length; j++) {
value = cplex.sum(value, cplex.prod(input[i][j], w[i]));
}
value = cplex.diff(value, result[i]);
value = cplex.square(value);
objective = cplex.sum(objective, value);
}
but I got this exception which I do not understand:
Exception in thread "main" java.lang.UnsupportedOperationException: CpxObjective for general expressions
at ilog.cplex.CpxObjective.setExpr(CpxObjective.java:102)
at ilog.cplex.CpxObjective.<init>(CpxObjective.java:357)
at ilog.cplex.IloCplexModeler.objective(IloCplexModeler.java:796)
at ilog.cplex.IloCplexModeler.minimize(IloCplexModeler.java:714)
at ilog.cplex.IloCplexModeler.minimize(IloCplexModeler.java:810)
at Tont.main(Tont.java:55)
Thanks for helping.
As far as I can tell, your first iteration of the outer loop creates terms like w[i]^2. The second iteration of the outer loops then takes this expression and squares it. Thus creating terms like w[i]^2. This is not supported. Only exponents of 1 and 2 are supported (linear and quadratic objectives).
From what you wrote, I think you are not creating your objective right. It should look something like this (note the initialization of value moved into the loop):
for (int i = 0; i < result.length; i++) {
IloNumExpr value = cplex.numExpr();
for (int j = 0; j < result.length; j++) {
value = cplex.sum(value, cplex.prod(input[i][j], w[i]));
}
value = cplex.diff(value, result[i]);
value = cplex.square(value);
objective = cplex.sum(objective, value);
}
This is the complete code, but it is infeasible. is it because Cplex cannot solve this kind of problems?
double [][] input = {{1,2},{3,4}};
double[] result = {3,2};
// define new model
IloCplex cplex = new IloCplex();
//cplex.setParam(IloCplex.Param.RootAlgorithm, IloCplex.Algorithm.Auto);
// variables
IloNumVar[] w = cplex.numVarArray(input[0].length, 0, Float.MAX_VALUE);// new IloNumVar[input[0].length];
for (int i = 0; i < w.length; i++) {
w[i] = cplex.numVar(0.0, 1.0, IloNumVarType.Float);
}
//IloNumExpr value = cplex.numExpr();
IloNumExpr objective = cplex.numExpr();
for (int i = 0; i < result.length; i++) {
IloNumExpr value = cplex.numExpr();
for (int j = 0; j < result.length; j++) {
value = cplex.sum(value, cplex.prod(input[i][j], w[i]));
}
value = cplex.diff(value, result[i]);
value = cplex.square(value);
objective = cplex.sum(objective, value);
}
cplex.minimize(objective);
//constraints
IloLinearNumExpr weightsAdded = cplex.linearNumExpr();
for (int j = 0; j < w.length; j++) {
weightsAdded.addTerm(1, w[j]);
}
cplex.addEq(weightsAdded, 1);
for (int i = 0; i < w.length; i++) {
cplex.addGe(0, w[i]);
}
// solve model
if (cplex.solve()) {
System.out.println("obj = "+cplex.getObjValue());
}
else {
System.out.println("problem not solved");
Thank you

Cloning two-dimensional Arrays in Java [duplicate]

This question already has answers here:
copy a 2d array in java
(5 answers)
Closed 4 years ago.
I know that similar questions have been asked, but after reading their answers, I keep being unable to solbe my problem: I need to implement the Java method clone, which copies all the double entries in a given two-dimensional array a to a newly created two-dimensional array of the same type and size. This method takes the array a as input and returns the new array with the copied values.
IMPORTANT: I am not not allowed to use a library method to clone the array.
Here's what I've done so far: Maybe I didn't understand the requirements but it didn't work:
class Solution {
static double[][] clone(double[][] a) {
double[][] b = new double[a.length][a.length];
for (int i = 0; i < a.length; i++) {
b[i][i] = a[i][i];
}
return b;
}
}
This is the error message I get:
Status: Done
cloneLonger(weblab.UTest) failed: 'java.lang.AssertionError: expected:<3> but was:<2>'
Test score: 2/3
Something like this should work (with library method):
public class Util{
// clone two dimensional array
public static boolean[][] twoDimensionalArrayClone(boolean[][] a) {
boolean[][] b = new boolean[a.length][];
for (int i = 0; i < a.length; i++) {
b[i] = a[i].clone();
}
return b;
}
}
In this, your code has few mistakes. These corrections were done below. The two-dimension array has 2 lengths. In this case, you didn't consider inside array length.
class Solution {
static double[][] clone(double[][] a) {
double[][] b = new double[a[0].length][a.length];
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
b[i][j] = a[i][j];
}
}
return b;
}
}
you should iterate this array with two loops. This will helps you:
static double[][] clone(double[][] a) {
double[][] b = new double[a.length][];
for (int i = 0; i < a.length; i++) {
b[i]= new double[a[i].length];
for (int j = 0; j < a[i].length; j++)
b[i][j] = a[i][j];
}
return b;
}
You have some logical mistakes:
1. Matrix could be sized M x N where M is the number of rows and N is the number of columns. In your solution you are taking for granted that M is always equal to N.
2. You are iterating trough all the rows and there you do set only one column per row like target[K][K] = source[K][K] -> this will go copy the diagonal only and not the whole matrix.
Copy to a temp single row array and then assign it to the out array
static double[][] clone(double[][] a) {
double[][] b = new double[a.length][];
for (int i = 0; i < a.length; i++) {
double[] temp = new double[a[i].length];
for (int j = 0; j < temp.length; j++) {
temp[j] = a[i][j];
}
b[i] = temp;
}
return b;
}
Ever more "advanced" alternatives are:
static double[][] clone(double[][] a) {
double[][] b = new double[a.length][];
for (int i = 0; i < a.length; i++) {
b[i] = new double[a[i].length];
//for (int j = 0; j < a[i].length; ++j) {
// b[i][j] = a[i][
//}
System.arraycopy(a[i], 0, b[i], a[i].length);
}
return b;
}
Now there is a utility class Arrays worth knowing:
static double[][] clone(double[][] a) {
double[][] b = new double[a.length][];
for (int i = 0; i < a.length; i++) {
b[i] = Arrays.copyOf(a[i], 0, [a[i].length]);
}
return b;
}
And for primitive arrays the clone method still may be used. Cloning is not very pure, bypassing constructors, and might be dropped from java in some future.
static double[][] clone(double[][] a) {
double[][] b = new double[a.length][];
for (int i = 0; i < a.length; i++) {
b[i] = a[i].clone();
}
return b;
}
You can't create new array like that. If you are sure that length and width of array is same than only this will work.
class Solution {
static double[][] clone(double[][] a) {
boolean[][] b = new boolean[a.length][];
for (int i = 0; i < a.length; i++) {
b[i] = new double[a[i].length];
for (int j = 0; i < a[i].length; j++) {
b[i][j] = a[i][j];
}
}
return b;
}
}

Finding the mode of a 2D array

I'm trying to return the mode of a 2D array using a frequency array. I have an array, score, which is of length 10, and has 3 columns. Each column contains an int that is between 0 and 100.
I'm trying to find a way that will iterate through the array and return the modal value. What I have so far is:
int value = 0;
int[] freq = new int[100];
for (int row = 0; row < score.length; row++) {
for (int col = 0; col < score[row].length; col++) {
score[row][col] = value;
freq[value]++;
}
}
int largest = 0;
int mode = -1;
for (int i = 0; i < 100; i++) {
if (freq[i] > largest)
{
largest = freq[i];
mode = i;
}
}
System.out.println("modal score is: " +mode);
Problem is that this is just returning the modal score as 0, which it isn't.
You have a problem on generating the freq array. If I understand correctly, on the first double-for block you are trying to put the frequencies of the numbers inside the freq array.
But all you do is:
int value = 0;
.....
score[row][col] = value;
freq[value]++;`
firstly you are changing the score array,( which is a problem for you I guess...) and the you go to freq[0] and do ++. Obviously modal is 0, that number appears in all of the array.
SOLUTION: in the first double for block you should do:
value = score[row][col];
freq[value]++;
so I think you mixed up the order of the line, it should be the other way around.
private static void printMode(double[][] doubles) {
HashMap<Double , Double> map = new HashMap();
for (int i = 0; i < doubles.length; i++) {
for (int j = 0; j < doubles[i].length; j++) {
double temp = doubles[i][j];
if(map.get(temp)==null){
map.put(doubles[i][j],1.0);
}else {
double temp2 = (double) map.get(temp);
map.put(doubles[i][j],++temp2);
}
}
}
Object[] objects = map.values().stream().sorted().toArray();
Stream stream = map.entrySet().stream().filter(val-> val.getValue().equals(objects[objects.length-1]));
stream.forEach(System.out::println);
}
I think using Stream for finding mode is the best way.
use int instead of double doesn't cause any problems.
int value = 0;
int [] freq = new int [arr.length];
for (int i = 0; i < arr.length; i++){
for (int j = 0; j < arr[i].length; j++){
value = arr[i][j];
freq[value]++;
}
}
int largest = 0;
int mode = 0;
for (int i = 0; i < freq.length; i++) {
if (freq[i] > largest)
{
largest = freq[i];
mode = i;
}
}
System.out.println("modal score is: " +mode);

Categories

Resources