Currently I have a dependency to commons-math 2.1 but I want to upgrade it to commons-math 3.6. Unfortunately there are some testcases that are not working any longer. I know what is causing my problem, but I don't know how to change the testcase accordingly to test the correct behavior as before.
I have following test code:
#Test
public void testIdentityMatrix() {
double[][] x = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 0, 1 }, { 0, 0, 0, 1 } };
double[] y = { 1, 2, 3, 4 };
OLSMultipleLinearRegression regression = new OLSMultipleLinearRegression();
regression.setNoIntercept(true);
regression.newSampleData(y, x);
double[] b = regression.estimateRegressionParameters();
for (int i = 0; i < y.length; i++)
{
assertEquals(b[i], y[i], 0.001);
}
}
After the upgrade to commons-math 3.6 the OLSMultipleLinearRegression checks the given matrix x and vector y for valid contents. And this validation fails with the message:
not enough data (4 rows) for this many predictors (4 predictors)
What do I need to change to correct that test case?
This is a bug in Commons Math 3.x. When there is no intercept in the model, as long as the design matrix is not singular, the number of observations equal to the number of regressors should be OK. In your example, I think you mean for the third x row to be {0,0,1,0} (otherwise the design matrix is singular). With this change to your data and the code patch applied in the Hipparchus fix your test succeeds. This bug is being tracked as MATH-1392 in Commons Math.
The number of samples has to be bigger than the number of variables. Apparently your test case it not correct. You would have to add at least one more sample.
If you change
double[][] x = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 0, 1 }, { 0, 0, 0, 1 } };
to
double[][] x = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 0, 1 }, { 0, 0, 0, 1 }, {1,0,0,0} };
it should work. (although I didn't test it).
I guess the 3rd row of x should be 0010 instead of 0001?
However, if you change x to
double[][] x = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 ), { 0,
0, 0, 1 }, {1,1,1,1} };
and change y to
double[] y = { 1, 2, 3, 4, 10 };
that the last element is the sum of other elements, then it works.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I tried to put java list into a 2D array and Retrieve it from the JSP. But It wasn't success.I really need this done.. Support me if you can..I have put my codes below if you able to solve this I'm really appreciate that.
Update:
1st List is getting inserted to first row(I want it insert to first column). likewise other three lists inserted to other 3 rows instead of three columns.
Screenshot
Requirement :
Ex:-
Servlet Code.
Scanner scanner = new Scanner(Result);
List<String> cdLine = new ArrayList<String>();
List<Integer> wtc = new ArrayList<Integer>();
List<Integer> ncc = new ArrayList<Integer>();
List<Integer> ccpps = new ArrayList<Integer>();
ControlData controlData = new ControlData();
while(scanner.hasNextLine())
{
token1 = scanner.nextLine();
Wtcs = controlData.CtrlWeight(token1);
NC = controlData.NofConditions(token1);
Ccspps = controlData.previousComplex(token1);
cdLine.add(token1);
wtc.add(Ccspps);
ncc.add(NC);
ccpps.add(Wtcs);
#SuppressWarnings("rawtypes")
List arr[][]={{cdLine},{wtc},{ncc},{ccpps}};
}
#SuppressWarnings("rawtypes")
List arr[][]={{cdLine},{wtc},{ncc},{ccpps}};
scanner.close(); //close the scanner
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/views/Control_structures.jsp");
request.setAttribute("Code_string", arr);
dispatcher.forward(request, response);
JSP code(using JSTL)
<c:forEach items="${Code_string}" var="post" varStatus="theCount">
<tbody>
<c:forEach items="${post}" var="value" varStatus="cell">
<tr>
<td scope="row">${theCount.count}</td>
<td>${value[0]}</td>
<td>${value[1]}</td>
<td>${value[2]}</td>
<td>${value[3]}</td>
<td>-</td>
</tr>
</c:forEach>
</tbody>
</c:forEach>
Update 2:
The 2D array that parsing to the JSP is like this. Hope this also need to be changed.
[[[public class Prime {, if, public static void main(String[]
args) {, , int low = 20, high = 50;, , while (low <
high) {, if(checkPrimeNumber(low)),
System.out.print(low + " ");, , ++low;, }, },
, public static boolean checkPrimeNumber(int num) {,
boolean flag = true;, , for(int i = 2; i <= num/2; ++i) {, ,
if(num % i == 0) {, flag = false;,
break;, }, }, , return flag;, }, }]],
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0]], [[0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], [[0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]]]
Output that I'm getting:
Thank you for your contribution.
There are two problems in your code:
A. With the following statement, you have created a 3-D structure which is an array of arrays of lists (Note that the List is an implementation of a dynamic 1-D array).
List arr[][]={{cdLine},{wtc},{ncc},{ccpps}};
You need an array of lists as given below:
List arr[]={cdLine,wtc,ncc,ccpps};
B. Do not place the above line inside the while loop. Do it just once after the while loop.
Apart from the points mentioned above, I would recommend you create a custom type instead of using raw type for the List array. Your custom type should be something like:
class MyType {
private List<String> cdLine = new ArrayList<String>();
private List<Integer> wtc = new ArrayList<Integer>();
private List<Integer> ncc = new ArrayList<Integer>();
private List<Integer> ccpps = new ArrayList<Integer>();
// ..constructors and getters and setters
}
Feel free to comment in case of any doubt/issue.
I'm building (or learning how to) a sports REST API using Spring Boot, Java, and MySQL. I'm building a method that currently takes each match from a collection of matches and returns an ArrayList of TeamStandings for the full list of matches.
Here is the method:
public List<TeamStanding> createStandingsTable(Match[] matches){
List<TeamStanding> teamStandings = new ArrayList<TeamStanding>();
for(int i = 0;i < matches.length; i++) {
TeamStanding firstTeam = new TeamStanding();
TeamStanding secondTeam = new TeamStanding();
//set team ids
firstTeam.setIdTeam(matches[i].getWcmHome());
secondTeam.setIdTeam(matches[i].getWcmAway());
//first team stats
firstTeam.setTeamPlayed((long) 1);
firstTeam.setTeamGoalsFavor(matches[i].getWcmHomeGoals());
firstTeam.setTeamGoalsAgainst(matches[i].getWcmAwayGoals());
firstTeam.setTeamGoalDif(firstTeam.getTeamGoalsFavor() - firstTeam.getTeamGoalsAgainst());
//second team stats
secondTeam.setTeamPlayed((long) 1);
secondTeam.setTeamGoalsFavor(matches[i].getWcmAwayGoals());
secondTeam.setTeamGoalsAgainst(matches[i].getWcmHomeGoals());
secondTeam.setTeamGoalDif(secondTeam.getTeamGoalsFavor() - secondTeam.getTeamGoalsAgainst());
//combined team stats
if(firstTeam.getTeamGoalsFavor() > secondTeam.getTeamGoalsFavor()) {
firstTeam.setTeamWins((long) 1);
firstTeam.setTeamLoses((long) 0);
firstTeam.setTeamDraws((long) 0);
firstTeam.setTeamPoints((long) 3);
secondTeam.setTeamWins((long) 0);
secondTeam.setTeamLoses((long) 1);
secondTeam.setTeamDraws((long) 0);
secondTeam.setTeamPoints((long) 0);
} else if (firstTeam.getTeamGoalsFavor() == secondTeam.getTeamGoalsFavor()) {
firstTeam.setTeamWins((long) 0);
firstTeam.setTeamLoses((long) 0);
firstTeam.setTeamDraws((long) 1);
firstTeam.setTeamPoints((long) 1);
secondTeam.setTeamWins((long) 0);
secondTeam.setTeamLoses((long) 0);
secondTeam.setTeamDraws((long) 1);
secondTeam.setTeamPoints((long) 1);
} else {
firstTeam.setTeamWins((long) 0);
firstTeam.setTeamLoses((long) 1);
firstTeam.setTeamDraws((long) 0);
firstTeam.setTeamPoints((long) 0);
secondTeam.setTeamWins((long) 1);
secondTeam.setTeamLoses((long) 0);
secondTeam.setTeamDraws((long) 0);
secondTeam.setTeamPoints((long) 3);
}
teamStandings.add(firstTeam);
teamStandings.add(secondTeam);
}
return teamStandings;
}
And the result is something like this:
[
{
"idTeam": 7,
"teamPoints": 3,
"teamPlayed": 1,
"teamWins": 1,
"teamDraws": 0,
"teamLoses": 0,
"teamGoalsFavor": 4,
"teamGoalsAgainst": 1,
"teamGoalDif": 3
},
{
"idTeam": 13,
"teamPoints": 0,
"teamPlayed": 1,
"teamWins": 0,
"teamDraws": 0,
"teamLoses": 1,
"teamGoalsFavor": 1,
"teamGoalsAgainst": 4,
"teamGoalDif": -3
},
{
"idTeam": 4,
"teamPoints": 3,
"teamPlayed": 1,
"teamWins": 1,
"teamDraws": 0,
"teamLoses": 0,
"teamGoalsFavor": 1,
"teamGoalsAgainst": 0,
"teamGoalDif": 1
},
{
"idTeam": 7,
"teamPoints": 0,
"teamPlayed": 1,
"teamWins": 0,
"teamDraws": 0,
"teamLoses": 1,
"teamGoalsFavor": 0,
"teamGoalsAgainst": 1,
"teamGoalDif": -1
}
]
My question is how can I merge these objects based on the idTeam? The result I'm trying to achieve would be to have all the rest of the properties added up while the idTeam remains the same. In the given example the expected one would be:
[
{
"idTeam": 7,
"teamPoints": 3,
"teamPlayed": 2,
"teamWins": 1,
"teamDraws": 0,
"teamLoses": 1,
"teamGoalsFavor": 4,
"teamGoalsAgainst": 2,
"teamGoalDif": 2
},
{
"idTeam": 13,
"teamPoints": 0,
"teamPlayed": 1,
"teamWins": 0,
"teamDraws": 0,
"teamLoses": 1,
"teamGoalsFavor": 1,
"teamGoalsAgainst": 4,
"teamGoalDif": -3
},
{
"idTeam": 4,
"teamPoints": 3,
"teamPlayed": 1,
"teamWins": 1,
"teamDraws": 0,
"teamLoses": 0,
"teamGoalsFavor": 1,
"teamGoalsAgainst": 0,
"teamGoalDif": 1
}
]
Also just a detail, I built the ArrayList of TeamStandings first and now I'm trying to merge them but perhaps I should be stacking them as a loop through the array of Matches, within the same method above but I'm not sure.
Iterate through the list of TeamStanding, mind the team ID and perform the additions. You might want to use the Map to save the pair of team ID as a key and the team itself as a value for easier manipulation. Here is the snipped (I haven't tested it, so you might need to amend it a bit).
List<TeamStanding> list = createStandingsTable(matches);
Map<Integer, TeamStanding> map = new HashMap<>();
for (TeamStanding team: list) {
int id = team.getIdTeam();
if (map.containsKey(id)) {
TeamStanding other = map.get(id);
other.setTeamPoints(team.getTeamPoints());
other.setTeamPlayed(team.getTeamPlayed());
// and so on...
} else {
map.put(id, team);
}
}
List<TeamStanding> merged = new ArrayList<>(map.values());
If you want to create the merged List<TeamStanding> directly from Match[], then you have to use the same idea, however, this might be a bit complicated to combine both of the iterations together. Then I recommend you to stick with these two separate iterations. Brevity, readability and maintainability over performance - moreover, the performance is not really an issue here.
You can use HashMap. Use "idTeam" as key and the object TeamStanding as value. Now you can iterate on the result list and if you find the object in the map, just update its fields and if you don't find then insert the object. After iteration finishes, you can call map.values() and it will give you a collection of objects(TeamStanding) and then you can create a new ArrayList with this collection.
The code will go like as follows:
public List<TeamStanding> mergeTeamStandingList(List<TeamStanding> teamStandingList) {
final Map<Integer, TeamStanding> idTeamVsTeamStandingMap = new HashMap<Integer, TeamStanding>();
teamStandingList.forEach(teamStanding -> {
if(idTeamVsTeamStandingMap.containsKey(teamStanding.getIdTeam())) {
TeamStanding teamStanding1 = idTeamVsTeamStandingMap.get(teamStanding.getIdTeam());
teamStanding1.setTeamDraws(teamStanding1.getTeamDraws() + teamStanding.getTeamDraws());
//so on
} else {
idTeamVsTeamStandingMap.put(teamStanding.getIdTeam(), teamStanding);
}
});
return new ArrayList<>(idTeamVsTeamStandingMap.values());
}
Create a merge method on your Teamstanding object.
public TeamStanding merge(TeamStanding other) {
this.teamPoints += other.getTeamPoints();
this.teamPlayed += other.getTeamPlayed();
this.teamWins += other.getTeamWins();
this.teamDraws += other.getTeamDraws();
this.teamGoalsFavor += other.getTeamGoalsFavor();
this.teamLoses += other.getTeamLoses();
this.teamGoalDif += other.getTeamGoalDif();
return this;
}
Then use Streams to group by teamId and reduce the common items using the merge method.
Map<Integer, Optional<TeamStanding>> mapReduced = teamStandings
.stream()
.collect(groupingBy(TeamStanding::getIdTeam, Collectors.reducing(TeamStanding::merge)));
Quick question about Java 2D arrays; For my tile-based, top-down, 2D game (using swing) I use
a 2D array to create a map, like this
public int[][] createMap(){
return new int[][]{
{0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}};
}
I then use this in my gameComponents class where I draw the individual tiles unto the map, like this
protected void paintComponent(Graphics g){
super.paintComponent(g);
for (int row = 0; row < game.getMap().getWidth(); row++) {
for (int col = 0; col < game.getMap().getHeight(); col++) {
g.drawImage(tile.getTileImage().get(values()[game.getMap().getMapArray()[col][row]]), row * SIZE,
col * SIZE, this);
}
} }
(where size is the size of a tile)
This works, and it correctly draws each tile to the map as expected, however
this also causes a problem for collision detection. As you may have noted, while I do define the size between the tiles in draw method, it is not defined in the array at all. Which, as you'd imagine, raises issues when checking for collision as the drawn tile is not where the tile is in the 2D array (due to size offset).
This is the code I use for checking collision (of course, not working due to ArrayIndexOutofbounds).
public boolean collisionDetected(int xDirection, int yDirection, Game game, Player player){
for (int row = 0; row < game.getMap().getHeight() * 16; row ++){
for (int col = 0; col < game.getMap().getWidth() * 16; col++) {
System.out.println(col + xDirection + player.getPositionX());
if(game.getMap().getTile(col + xDirection + player.getPositionX() ,
row + yDirection + player.getPositionY()) == Tiles.GRASS ){
System.out.println("COLLISION DETECTED");
return true;
}
}
}
return false;
}
This method uses a method within the map class that returns the tile on that
specific coordinate, like this
public Tiles getTile(int col,int row){
return Tiles.values()[mapArray[col][row]];
}
And, of course, as the 2D array doesn't know of the size offset, it just throws
an arrayindexoutofbound.
My question is, is it possible to define a 2D map array with the size of a tile in-mind? I appreciate any help & input I can get, after-all I am here to learn!
Extra clarification: All the tiles are in an enum class (i.e AIR, GRASS, STONE...). Also worth noting that the player position is not bound by an array, I merely move it the amount of pixels I want it to move.
Thanks in advance!
This method uses a method within the map class that returns the tile on that specific coordinate, like this
public Tiles getTile(int col,int row){
return Tiles.values()[mapArray[col][row]];
}
So if you have a "coordinate", why do you call the parameters col/row?
If you have a 10x10 grid and each tile is 20 pixels then the grid size is 200x200 so you could have x/y values in the range 0-199
So if you have a coordinate of 25x35 you would simply calculate the row/col values as:
int row = 35 / 20;
int column = 25 / 20;
So your method would be something like :
public Tiles getTile(int x, int y)
{
int row = y / 20;
int column = x / 20;
return Tiles.values()[mapArray[row][column]];
}
I would like to paste a given little array into another bigger array at a specified position (or interval) in Java:
int[] bigger_array = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int[] smaller_array = { 1, 2, 3 };
Does exist a simple Java method (with matlab it's simple) that helps me pasting "smaller_array" for example at position 2 (of the bigger) so that "bigger_array" variable becomes:
{ 0, 0, 1, 2, 3, 0, 0, 0, 0 };
Please don't paste methods with a simple "for". I want to know if an optimized method exists.
You can use System.arraycopy:
public static void arraycopy(
Object src, int srcPos, Object dest, int destPos, int length)
Copies an array from the specified source array, beginning at the
specified position, to the specified position of the destination
array. A subsequence of array components are copied from the source
array referenced by src to the destination array referenced by dest.
The number of components copied is equal to the length argument. The
components at positions srcPos through srcPos+length-1 in the source
array are copied into positions destPos through destPos+length-1,
respectively, of the destination array.
Note that the documentation on the System class says (emphasis added):
Among the facilities provided by the System class are standard input,
standard output, and error output streams; access to externally
defined properties and environment variables; a means of loading files
and libraries; and a utility method for quickly copying a portion of
an array.
Here's an exaple and its output:
import java.util.Arrays;
public class ArrayCopyDemo {
public static void main(String[] args) {
int[] bigger_array = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int[] smaller_array = { 1, 2, 3 };
// start copying from position 1 in source, and into
// position 3 of the destination, and copy 2 elements.
int srcPos = 1, destPos = 3, length = 2;
System.arraycopy(smaller_array, srcPos, bigger_array, destPos, length );
System.out.println( Arrays.toString( bigger_array ));
}
}
[0, 0, 0, 2, 3, 0, 0, 0, 0]
To copy the entire array, just use 0 as srcPos, and src.length as length (where src is the source array; in this case, you'd use smaller_array.length).
You can use System.arraycopy(...). Reusing your example:
int[] bigger_array = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int[] smaller_array = { 1, 2, 3 };
You could do:
System.arraycopy(smaller_array, 0, bigger_array, 2, 3 );
And you'll end up with your bigger_array modified and now containing the { 0, 0, 1, 2, 3, 0, 0, 0, 0 } you're after.
Use it
public static void arraycopy(Object src,
int srcPos,
Object dest,
int destPos,
int length)
System.arraycopy(smaller_array, from_position, bigger_array, to_position, smaller_array.length);
I would go for System.arraycopy
int[] bigger_array = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int[] smaller_array = { 1, 2, 3 };
System.arraycopy(smaller_array, 0, bigger_array, 2, 3 );
System.out.println(Arrays.toString(bigger_array));
I have been at this little project and i spend like 20 hours solving (without any luck or results) a major problem in the code. Now i am at the point that i found out that the real problem is that the copy() function does not properly work.
What am i doing wrong?
This is the example i made of the specific problem:
package cloneobject;
import java.util.Arrays;
public class CloneObject {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
clone(new int[3][3]);
}
public static void clone(int[][] x) {
int[][] y = (int[][]) x.clone();
System.out.println("x=");
PrintFieldImage(x);
System.out.println("y=");
PrintFieldImage(y);
x[1][1] = 3;
System.out.println("x=");
PrintFieldImage(x);
System.out.println("y=");
PrintFieldImage(y);
y[2][2] = 4;
System.out.println("x=");
PrintFieldImage(x);
System.out.println("y=");
PrintFieldImage(y);
}
public static void PrintFieldImage(int[][] field) {
if (field != null) {
int x;
for (x = 0; x < field.length; x++) {
System.out.println(Arrays.toString(field[x]));
}
} else {
System.out.println("no field!");
}
}
}
and this is the result:
run:
x=
[0, 0, 0]
[0, 0, 0]
[0, 0, 0]
y=
[0, 0, 0]
[0, 0, 0]
[0, 0, 0]
x=
[0, 0, 0]
[0, 3, 0]
[0, 0, 0]
y=
[0, 0, 0]
[0, 3, 0]
[0, 0, 0]
x=
[0, 0, 0]
[0, 3, 0]
[0, 0, 4]
y=
[0, 0, 0]
[0, 3, 0]
[0, 0, 4]
BUILD SUCCESSFUL (total time: 0 seconds)
Now i wish let x contain 3, and y contain 4.
Plz help!
clone() only will do a shallow clone. You are cloning a 2D array; an array of arrays. Only the top level array will be cloned. If you want to do a deep clone, you'll have to use ol' fashioned for loop(s).
int[][] y = new int[x.length][];
for(int i=0; i<x.length; i++) {
y[i] = x[i].clone();
}
See also copy a 2d array in java