Jama package, 4x4 linear equation solver - java

I'm trying to solve a 4x4 linear equation system (4 variables, 4 equations) using Jama. I have tried the following code, but it doesn't work. I would appreciate if someone can help me, using Jama or any other method.
import Jama.Matrix;
public class OvaWork {
public OvaWork()
{
//Creating Arrays Representing Equations
double[][] lhsArray = {{-3, 1, -1}, {5, -2, 1}, {-1, 1, 3}, {2, 5, 7}};
double[] rhsArray = {-4, 6, 0, 8};
//Creating Matrix Objects with arrays
Matrix lhs = new Matrix(lhsArray);
Matrix rhs = new Matrix(rhsArray, 4);
//Calculate Solved Matrix
Matrix ans = lhs.solve(rhs);
//Printing Answers
System.out.println("w = " + Math.round(ans.get(0, 0)));
System.out.println("x = " + Math.round(ans.get(1, 0)));
System.out.println("y = " + Math.round(ans.get(2, 0)));
System.out.println("z = " + Math.round(ans.get(3, 0)));
}
public static void main(String[] args)
{
OvaWork o = new OvaWork();
}
}

You have to try with easier examples like this 2x2 equation
double[][] lhsArray = {{1,1},{2, 0}};
double[] rhsArray = {10,2};
Matrix lhs = new Matrix(lhsArray);
Matrix rhs = new Matrix(rhsArray, 2);
Matrix ans = lhs.solve(rhs);
It works and the output is a matrix {1,9}
The problem with your code is that your matrix is not square it is 3x4
double[][] lhsArray = {{-3, 1, -1}, {5, -2, 1}, {-1, 1, 3}, {2, 5, 7}};
Change your matrix to a square one.
Test this trivial equation:
double[][] lhsArray = {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}};
double[] rhsArray = {1, 2, 3, 4};
Matrix lhs = new Matrix(lhsArray);
Matrix rhs = new Matrix(rhsArray, 4);
Matrix ans = lhs.solve(rhs);
The ans is {1,2,3,4} as expected.

Related

Determining if a knight can pass through all cells in a 2d array - if so print board

I need an advice regarding this problem called "Knight Path".
Given an n*n board whose cells are initialized to 0, I need to determine, given an arbitrary Knight's position, if the knight can pass through every cell on the board exactly once, where every cell the Knight had visited will be marked as counter, counting from: 1 - n^2.
If a path is possible, I need to print the board. I need to print all the valid boards.
The knight, for those who do not know the rules for chess, can move either up or down one square vertically and over two squares horizontally OR up or down two squares vertically and over one square horizontally.
For example given a 5*5 board, starting at (0,0) the method should print:
{{1,16,11,6,21},
{10,5,20,15,12},
{17,2,13,22,7},
{4,9,24,19,14},
{25,18,3,8,23}};
The above out put would be one of few, as there could be different other ways considering different initial positions.
I've written the below code but it doesn't print anything. I need to spot the logic flaws here so I can make it work.
public class KnightDemo {
static int counter = 1;
public static void KnightPath(int[][] b, int i, int j) {
b[i][j] = counter;
if (counter == b.length * b[0].length) {
printMatrix(b);
return;
} else {
counter++;
if (isValid(b, i - 1, j + 2) && b[i - 1][j + 2] == 0) {
KnightPath(b, i - 1, j + 2);
} else {
return;
}
if (isValid(b, i - 2, j + 1) && b[i - 1][j + 1] == 0) {
KnightPath(b, i - 2, j + 1);
} else {
return;
}
if (isValid(b, i - 1, j - 2) && b[i - 1][j - 2] == 0) {
KnightPath(b, i - 1, j - 2);
} else {
return;
}
if (isValid(b, i - 2, j - 1) && b[i - 2][j - 1] == 0) {
KnightPath(b, i - 2, j - 1);
} else {
return;
}
if (isValid(b, i + 2, j - 1) && b[i + 2][j - 1] == 0) {
KnightPath(b, i + 2, j - 1);
} else {
return;
}
if (isValid(b, i + 1, j - 2) && b[i + 1][j - 2] == 0) {
KnightPath(b, i + 1, j - 2);
} else {
return;
}
if (isValid(b, i + 1, j + 2) && b[i + 1][j + 2] == 0) {
KnightPath(b, i + 1, j + 2);
} else {
return;
}
if (isValid(b, i + 2, j + 1) && b[i + 2][j + 1] == 0) {
KnightPath(b, i + 2, j + 1);
} else {
return;
}
}
}
public static boolean isValid(int[][] a, int i, int j) {
if (i > a.length - 1 || i < 0 || j > a[0].length - 1 || j < 0) {
return false;
}
return true;
}
public static void main(String[] args) {
int[][] b = new int[5][5];
for (int i = 0; i < b.length; i++) {
for (int j = 0; j < b[0].length; j++) {
KnightPath(b, i, j);
}
}
}
public static void printMatrix(int[][] matrix) {
for (int[] rows: matrix) {
StringBuilder buff = new StringBuilder();
buff.append("[");
for (int i = 0; i < rows.length; i++) {
int value = rows[i];
buff.append(value);
if (i < rows.length - 1) {
buff.append(", ");
}
}
buff.append("]");
System.out.println(buff.toString());
}
}
}
The output is
[1, 2, 3, 4, 5]
[6, 7, 8, 9, 10]
[11, 12, 13, 14, 15]
[16, 17, 18, 19, 20]
[21, 22, 23, 24, 25]
Based on the OP's explanation in the comments section, the goal is to map out all possible paths a knight can take from a location on the board. Basically, given the knight's location b[i][j], calculate all legal paths.
If a knight is at {0, 0}, the knight has only two legal paths that end in {1, 2} and {2, 1}. The idea here is to capture that in a map. Then, move on to the next location on the board (i.e. {1, 0}) and repeat the process. Since each board location can be identified as an integer (counter), we can use it to map the paths...
0=[{1, 2}, {2, 1}]
1=[{2, 2}, {1, 3}, {2, 0}]
...
n=[{n^-2 - 3, n^-2 - 2}, {n^-2 - 2, n^-2 - 3}] // last location is always a corner
To make it simple, I decided to create a Java record of coordinates to store the {x, y} coordinates of the end location of a given path, making my map <Integer, Set<Coordinates>>
The logic here is quite simple. First, seed the map with empty lists for each one corresponding location in the matrix. Then, iterate through the matrix (2D array) and calculate all the legal paths a knight can take from this location. For each legal path, add the Coordinates of the end location of the path. I used a Set to eliminate duplicate coordinates.
My solution (perhaps not optimal) is as follows (used OP code as baseline) - Need Java 15 or later to run. For Java 14 or earlier, replace Coordinates with an Integer[] of length 2, and store the coordinates in it.
public class KnightDemo {
static int counter = 0;
static Map<Integer, Set<Coordinates>> map = new HashMap<>();
public static void KnightPath(int[][] b, int i, int j) {
Set<Coordinates> paths = map.get(counter);
if (isValid(b, i - 1, j + 2)) {
paths.add(new Coordinates(i - 1, j + 2));
map.put(counter, paths);
}
if (isValid(b, i - 2, j + 1)) {
paths.add(new Coordinates(i - 2, j + 1));
map.put(counter, paths);
}
if (isValid(b, i - 1, j - 2)) {
paths.add(new Coordinates(i - 1, j - 2));
map.put(counter, paths);
}
if (isValid(b, i - 2, j - 1)) {
paths.add(new Coordinates(i - 2, j - 1));
map.put(counter, paths);
}
if (isValid(b, i + 2, j - 1)) {
paths.add(new Coordinates(i + 2, j - 1));
map.put(counter, paths);
}
if (isValid(b, i + 1, j - 2)) {
paths.add(new Coordinates(i + 1, j - 2));
map.put(counter, paths);
}
if (isValid(b, i + 1, j + 2)) {
paths.add(new Coordinates(i + 1, j + 2));
map.put(counter, paths);
}
if (isValid(b, i + 2, j + 1)) {
paths.add(new Coordinates(i + 2, j + 1));
map.put(counter, paths);
}
counter++;
}
public static boolean isValid(int[][] a, int i, int j) {
return i >= 0 && i < a.length && j >= 0 && j < a[0].length;
}
public static void main(String[] args) {
int[][] b = new int[5][5];
for (int i = 0; i < b.length; i++) {
for (int j = 0; j < b[0].length; j++) {
map.put(counter, new HashSet<>()); // add a new set before calculating paths
KnightPath(b, i, j);
}
}
map.entrySet().stream().forEach(System.out::println);
}
private static record Coordinates(int row, int col) {
#Override
public String toString() {
return "{" + row + ", " + col + "}";
}
}
}
The program outputs:
0=[{1, 2}, {2, 1}]
1=[{2, 2}, {1, 3}, {2, 0}]
2=[{2, 3}, {1, 4}, {2, 1}, {1, 0}]
3=[{2, 2}, {1, 1}, {2, 4}]
4=[{2, 3}, {1, 2}]
5=[{2, 2}, {0, 2}, {3, 1}]
6=[{2, 3}, {0, 3}, {3, 0}, {3, 2}]
7=[{0, 0}, {3, 3}, {2, 4}, {0, 4}, {3, 1}, {2, 0}]
8=[{0, 1}, {3, 4}, {3, 2}, {2, 1}]
9=[{3, 3}, {2, 2}, {0, 2}]
10=[{1, 2}, {0, 1}, {4, 1}, {3, 2}]
11=[{0, 0}, {3, 3}, {1, 3}, {0, 2}, {4, 0}, {4, 2}]
12=[{0, 1}, {3, 4}, {1, 4}, {0, 3}, {4, 1}, {3, 0}, {1, 0}, {4, 3}]
13=[{1, 1}, {4, 4}, {0, 2}, {0, 4}, {4, 2}, {3, 1}]
14=[{1, 2}, {0, 3}, {4, 3}, {3, 2}]
15=[{2, 2}, {1, 1}, {4, 2}]
16=[{2, 3}, {1, 2}, {1, 0}, {4, 3}]
17=[{1, 1}, {4, 4}, {2, 4}, {1, 3}, {4, 0}, {2, 0}]
18=[{1, 2}, {1, 4}, {4, 1}, {2, 1}]
19=[{2, 2}, {1, 3}, {4, 2}]
20=[{3, 2}, {2, 1}]
21=[{3, 3}, {2, 2}, {2, 0}]
22=[{3, 4}, {2, 3}, {3, 0}, {2, 1}]
23=[{2, 2}, {2, 4}, {3, 1}]
24=[{2, 3}, {3, 2}]
UPDATE: Can you use this in a real game of chess?
Yes, you can! Suppose you seed the matrix with black and white. You could enhance the logic so that, if the end location corresponds to your color, you don't add as a valid path since it is blocked by one of your pieces.
SECOND UPDATE: Same code but using Coordinate object as key
public class KnightDemo {
static int counter = 0;
static Map<Coordinates, Set<Coordinates>> map = new HashMap<>();
public static void KnightPath(int[][] b, Coordinates coordinates) {
Set<Coordinates> paths = map.get(coordinates);
if (isValid(b, coordinates.row() - 1, coordinates.col() + 2)) {
paths.add(new Coordinates(coordinates.row() - 1, coordinates.col() + 2));
map.put(coordinates, paths);
}
if (isValid(b, coordinates.row() - 2, coordinates.col() + 1)) {
paths.add(new Coordinates(coordinates.row() - 2, coordinates.col() + 1));
map.put(coordinates, paths);
}
if (isValid(b, coordinates.row() - 1, coordinates.col() - 2)) {
paths.add(new Coordinates(coordinates.row() - 1, coordinates.col() - 2));
map.put(coordinates, paths);
}
if (isValid(b, coordinates.row() - 2, coordinates.col() - 1)) {
paths.add(new Coordinates(coordinates.row() - 2, coordinates.col() - 1));
map.put(coordinates, paths);
}
if (isValid(b, coordinates.row() + 2, coordinates.col() - 1)) {
paths.add(new Coordinates(coordinates.row() + 2, coordinates.col() - 1));
map.put(coordinates, paths);
}
if (isValid(b, coordinates.row() + 1, coordinates.col() - 2)) {
paths.add(new Coordinates(coordinates.row() + 1, coordinates.col() - 2));
map.put(coordinates, paths);
}
if (isValid(b, coordinates.row() + 1, coordinates.col() + 2)) {
paths.add(new Coordinates(coordinates.row() + 1, coordinates.col() + 2));
map.put(coordinates, paths);
}
if (isValid(b, coordinates.row() + 2, coordinates.col() + 1)) {
paths.add(new Coordinates(coordinates.row() + 2, coordinates.col() + 1));
map.put(coordinates, paths);
}
}
public static boolean isValid(int[][] a, int i, int j) {
return i >= 0 && i < a.length && j >= 0 && j < a[0].length;
}
public static void main(String[] args) {
int[][] b = new int[5][5];
for (int i = 0; i < b.length; i++) {
for (int j = 0; j < b[0].length; j++) {
Coordinates coordinates = new Coordinates(i, j);
map.put(coordinates, new HashSet<>());
KnightPath(b, coordinates);
counter++;
}
}
map.entrySet().stream().forEach(System.out::println);
}
private static record Coordinates(int row, int col) {
#Override
public String toString() {
return "{" + row + ", " + col + "}";
}
}
}
Outputs:
{0, 0}=[{1, 2}, {2, 1}]
{2, 2}=[{0, 1}, {3, 4}, {1, 4}, {0, 3}, {4, 1}, {3, 0}, {1, 0}, {4, 3}]
{4, 4}=[{2, 3}, {3, 2}]
{0, 1}=[{2, 2}, {1, 3}, {2, 0}]
{2, 3}=[{1, 1}, {4, 4}, {0, 2}, {0, 4}, {4, 2}, {3, 1}]
{0, 2}=[{2, 3}, {1, 4}, {2, 1}, {1, 0}]
{2, 4}=[{1, 2}, {0, 3}, {4, 3}, {3, 2}]
{0, 3}=[{2, 2}, {1, 1}, {2, 4}]
{0, 4}=[{2, 3}, {1, 2}]
{3, 0}=[{2, 2}, {1, 1}, {4, 2}]
{3, 1}=[{2, 3}, {1, 2}, {1, 0}, {4, 3}]
{1, 0}=[{2, 2}, {0, 2}, {3, 1}]
{3, 2}=[{1, 1}, {4, 4}, {2, 4}, {1, 3}, {4, 0}, {2, 0}]
{1, 1}=[{2, 3}, {0, 3}, {3, 0}, {3, 2}]
{3, 3}=[{1, 2}, {1, 4}, {4, 1}, {2, 1}]
{1, 2}=[{0, 0}, {3, 3}, {2, 4}, {0, 4}, {3, 1}, {2, 0}]
{3, 4}=[{2, 2}, {1, 3}, {4, 2}]
{1, 3}=[{0, 1}, {3, 4}, {3, 2}, {2, 1}]
{1, 4}=[{3, 3}, {2, 2}, {0, 2}]
{4, 0}=[{3, 2}, {2, 1}]
{4, 1}=[{3, 3}, {2, 2}, {2, 0}]
{2, 0}=[{1, 2}, {0, 1}, {4, 1}, {3, 2}]
{4, 2}=[{3, 4}, {2, 3}, {3, 0}, {2, 1}]
{2, 1}=[{0, 0}, {3, 3}, {1, 3}, {0, 2}, {4, 0}, {4, 2}]
{4, 3}=[{2, 2}, {2, 4}, {3, 1}]
They don't print in the same order, but you can tell that coordinates {2, 2} is the same set as counter==12 in the previous example. Cell {2, 2} is the 13th cell from the top-left.
To solve for all paths, you need to reset the placed values of paths you've exhausted so that newer paths can access them. Additionally, your counter should reflect how deep you've gone, so that if you back out to try another path, your counter should roll back, too. I would recommend passing a counter as a parameter rather than using a static counter. Also, if you want to try all valid possibilities, then you need to avoid those return statements whenever one possibility is deemed invalid.
public static void KnightPath(int[][] b, int i, int j, int counter) {
...
if (isValid(b, i - 1, j + 2) && b[i - 1][j + 2] == 0) {
KnightPath(b, i - 1, j + 2, counter+1);
}
...
b[i][j] = 0;
}
public static void main(String[] args) {
...
KnightPath(b, i, j, 1);
...
}

creating non symmetrical patterns of asterisks [closed]

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 2 years ago.
Improve this question
I'm new to Java and programming in general and embarking on an interesting problem. its a question has ive been tasked with to make my initials with asterisks. as mine is "CH" I've decided to start by trying to simplify by thinking of it as three columns and three rows.
so far I've created a two-dimensional array; to use as a blank grid. it's 5 by 10 (arbitrarily).
Breaking the task down I think there are three columns top to bottom, occupying the 0, 6, and 9th indexes of the y array. Also three rows: top and bottom first thirds; and the central last third. further to this I've decided on two spaces between the characters.
So my next thought has been it's probably best to consider the spaces? I believe I can probably effectively do this by slicing the arrays rather than doing iterating through or similar. to keep the code as tight as possible. i'm thinking I want to split x index and tell it to place a space in the mid-value..at some point (x/2) is it possible to give this index a name to do this and how do I do this in java?
What i'm trying to achieve is:
XXXX x x
x x x
x xxxx
x x x
xxxx x x
// so far i have just the base:
public class MyClass {
public static void main (string args[]){
int[x][y] myArray = new int[5][10];
brief summary of what i'd like to achieve so far:
*'s on Y "columns" 0,6,9
*'s on X 0-4 y 0;
6-9 y 2;
0-4 y 4
apologies if this seems stupidly simple but I'm unsure how to do this programmatically, and I'm on my own!
apologies for any errors any suggestions or pointers appreciated!
I would make each letter as array of bytes like:
byte[][] c = {{1, 1, 1, 1}, {1, 0, 0, 0}, {1, 0, 0, 0}, {1, 0, 0, 0}, {1, 1, 1, 1}};
byte[][] h = {{1, 0, 0, 1}, {1, 0, 0, 1}, {1, 1, 1, 1}, {1, 0, 0, 1}, {1, 0, 0, 1}};
so, 1 marks the X, and 0 marks the zero, ie. a "raster alphabet".
Then you can do a row by row iteration of the arrays and print it out?
public class Test
{
public static void main(String[] args)
{
byte[][] c = {{1, 1, 1, 1}, {1, 0, 0, 0}, {1, 0, 0, 0}, {1, 0, 0, 0}, {1, 1, 1, 1}};
byte[][] h = {{1, 0, 0, 1}, {1, 0, 0, 1}, {1, 1, 1, 1}, {1, 0, 0, 1}, {1, 0, 0, 1}};
for (int i = 0; i < 5; i++)
{
for (int j=0; j < 4; j++)
{
byte l = c[i][j];
System.out.print(l == 1 ? "x":" ");
}
System.out.print(" ");
for (int j=0; j < 4; j++)
{
byte l = h[i][j];
System.out.print(l == 1 ? "x":" ");
}
System.out.println("");
}
}
}

Equivalent of for x, y in z in java

In python, you can use the structure for x in [a, b, c, d] for loops. This can be replicated using a foreach loop in java.
What about if I wanted to replicate a for x, y in z loop, such as the one below, in java?
for x_off, y_off in ( (1, 2), (-1, 2), (1, -2), (-1, -2), (2, 1), (-2, 1), (2, -1), (-2, -1) ):
#do something
I ended up just using variables for each index. But this won't be useful for 2d arrays with large counts for each inner array.
int[][] offsets = new int[][] { {0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1} };
for(int[] offset: offsets) {
int x = offset[0], y = offset[1];
// do something with x and y
You should create a class for storing the three values:
final class Point3D {
private final int x, y, z;
// constructor, getters, and equals/hashCode/toString here
}
Then you can use an array initializer with an enhanced for loop:
for (Point3D point : new Point3D[] { new Point3D(1, 1, 1), new Point3D(-1, 1, 1),
new Point3D(-1, -1, 1), new Point3D(1, -1, 1) }) {
// code here
}
It reads better if you create the array separately, especially if there are many points:
Point3D[] points = {
new Point3D( 1, 1, 1), new Point3D(-1, 1, 1),
new Point3D(-1, -1, 1), new Point3D( 1, -1, 1),
new Point3D( 1, 1, -1), new Point3D(-1, 1, -1),
new Point3D(-1, -1, -1), new Point3D( 1, -1, -1)
};
for (Point3D point : points) {
// code here
}

Setting a specific element in a 2d array to a random value

I am looking to set a random value to a certain element in a 2d array.
In my assignment I have to assign a random number 1-5 for the first element in the 2d array and then go the the next row and do the same thing. This is what I have so far but it does not look right.
double CURRENT_BOARD [5][5] = {{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0}};
public double shuffleBoard (double currentBoard) {
Random rand = new Random();
shuffledBoard [][] = new double [5][5];
for (i=0 ;i<5 ;i++) {
j = rand.nextInt(5) + 1;
shuffledBoard = shuffledBoard [j][0];
}
return shuffleBoard;
}//shuffleBoard
My end goal is that the elements of the array will look something like
{5, 0, 0, 0, 0}
{3, 0, 0, 0, 0}
{4, 0, 0, 0, 0} and so on as long as the first element of the array is selected at random. Can anyone offer any help to make this happen?
Your declaration of a 2D double array is not correct.
Take a look at this StackOverflow answer
Declaration should be like
double[][] CURRENT_BOARD = new double[][]{{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0}};
For random number part, you can try this
public double[][] shuffleBoard(double[][] currentBoard) {
double[][] shuffledBoard = currentBoard;
Random rand = new Random();
double rangeMin = 1, rangeMax = 5;
for (int i = 0; i < 5; i++) {
double j = rangeMin + (rangeMax - rangeMin) * rand.nextDouble();
shuffledBoard[i][0] = j;
}
return shuffledBoard;
}

How to multiply 2 matrices in java and then use the result as transformation matrix for Imgproc.warpPerspective function

I want to create 3 matrices:
A of 3x4 and B of 4x4 and C of 4x3 . Then I want to multiply them D = A * (B * C) to receive a 3x3 matrix
And then call warpPerspective with D.
All of the above is needed to be done with Java. In c++ it is 'extremely' easy opposed to Java, I could not find any real example for Java implementation.
package test;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
public class MatrixMul {
static {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
public static void main(String[] args) {
Mat A = new Mat(3, 4, CvType.CV_32FC1);
Mat B = new Mat(4, 4, CvType.CV_32FC1);
Mat C = new Mat(4, 3, CvType.CV_32FC1);
Mat tmp = new Mat();
Mat D = new Mat();
A.put(0, 0, new float[] { 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3 });
B.put(0, 0, new float[] { 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4 });
C.put(0, 0, new float[] { 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3 });
Core.gemm(B, C, 1, new Mat(), 0, tmp);
Core.gemm(A, tmp, 1, new Mat(), 0, D);
// Mat src = ...
// Mat dst = new Mat();
// Imgproc.warpPerspective(src, dst, D, new Size(3,3));
System.out.println("A =\n" + A.dump());
System.out.println("B =\n" + B.dump());
System.out.println("C =\n" + C.dump());
System.out.println("B * C =\n" + tmp.dump());
System.out.println("D = A * (B * C) =\n" + D.dump());
}
}

Categories