USER
Написать библиотеку для работы с линейной алгеброй. Результат следует
оформить в виде отдельного модуля (пакета). Назвать можно, например, Math.
Реализовать несколько классов для работы:
• Вектора размерности 2, 3, 4 (это отдельные классы). Для них должны
быть:
– Операции сложения и вычитания
– Умножения и деления на скаляр
57
– Вычисления длины
– Нормализации
– Скалярного произведения
– Векторного произведения (Для вектора размерности 3)
• Матрицы размерности 3х3, 4х4 (это отдельные классы). Для них должны
быть:
– Операции сложения и вычитания
– Умножения на соответствующий вектор 3 или 4. Здесь и дальше по
курсу работаем с векторами-столбцами
– Перемножения матриц
– Транспонирования
– Быстрого задания единичной и нулевой матрицы (через конструктор
или метод)
Особенно важно покрыть весь код тестами, чтобы нажатием пары кнопок
можно было доказать, что он рабочий. Стоит также добавить обработку ошибок (например, деление на ноль).
Желающие могут добавить (возможно, частично) для существующих классов
пункты из следующего списка - поощрается дополнительными баллами:
• Вычисление определителя матриц
• Вычисление обратной матрицы
• Решение систем методом Гаусса
используя принципы ооп. код пиши на java
ASSISTANT
Создание библиотеки для работы с линейной алгеброй в Java требует реализации нескольких классов. Мы создадим классы для векторов и матриц, каждый из которых будет иметь нужный набор методов. Основное внимание будет уделено правильной структуре классов и обработке ошибок. Включение тестов также критически важно, поэтому я покажу пример использования JUnit для тестирования. Начнем с представления классов для векторов различной размерности.
```java
// Vec2.java
package Math;
public class Vec2 {
public double x, y;
public Vec2(double x, double y) {
this.x = x;
this.y = y;
}
// Addition
public Vec2 add(Vec2 other) {
return new Vec2(this.x + other.x, this.y + other.y);
}
// Subtraction
public Vec2 subtract(Vec2 other) {
return new Vec2(this.x - other.x, this.y - other.y);
}
// Scalar multiplication
public Vec2 multiply(double scalar) {
return new Vec2(this.x * scalar, this.y * scalar);
}
// Scalar division
public Vec2 divide(double scalar) {
if (scalar == 0) {
throw new ArithmeticException("Division by zero");
}
return new Vec2(this.x / scalar, this.y / scalar);
}
// Length of the vector
public double length() {
return Math.sqrt(x * x + y * y);
}
// Normalization
public Vec2 normalize() {
double len = length();
if (len == 0) throw new ArithmeticException("Cannot normalize zero-length vector");
return this.divide(len);
}
// Dot product
public double dot(Vec2 other) {
return this.x * other.x + this.y * other.y;
}
}
```
```java
// Vec3.java
package Math;
public class Vec3 {
public double x, y, z;
public Vec3(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
// Addition
public Vec3 add(Vec3 other) {
return new Vec3(this.x + other.x, this.y + other.y, this.z + other.z);
}
// Subtraction
public Vec3 subtract(Vec3 other) {
return new Vec3(this.x - other.x, this.y - other.y, this.z - other.z);
}
// Scalar multiplication
public Vec3 multiply(double scalar) {
return new Vec3(this.x * scalar, this.y * scalar, this.z * scalar);
}
// Scalar division
public Vec3 divide(double scalar) {
if (scalar == 0) {
throw new ArithmeticException("Division by zero");
}
return new Vec3(this.x / scalar, this.y / scalar, this.z / scalar);
}
// Length of the vector
public double length() {
return Math.sqrt(x * x + y * y + z * z);
}
// Normalization
public Vec3 normalize() {
double len = length();
if (len == 0) throw new ArithmeticException("Cannot normalize zero-length vector");
return this.divide(len);
}
// Dot product
public double dot(Vec3 other) {
return this.x * other.x + this.y * other.y + this.z * other.z;
}
// Cross product
public Vec3 cross(Vec3 other) {
return new Vec3(
this.y * other.z - this.z * other.y,
this.z * other.x - this.x * other.z,
this.x * other.y - this.y * other.x
);
}
}
```
Для вектора размерности 4 класс будет аналогичен `Vec3`, но с добавлением четвёртой координаты `w`.
Теперь реализуем классы для матриц:
```java
// Matrix3x3.java
package Math;
public class Matrix3x3 {
private double[][] data;
public Matrix3x3(double[][] data) {
if (data.length != 3 || data[0].length != 3) {
throw new IllegalArgumentException("Matrix must be 3x3.");
}
this.data = data;
}
// Addition
public Matrix3x3 add(Matrix3x3 other) {
double[][] result = new double[3][3];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
result[i][j] = this.data[i][j] + other.data[i][j];
}
}
return new Matrix3x3(result);
}
// Subtraction, multiplication, etc. implemented similarly
// Multiplication by Vec3
public Vec3 multiply(Vec3 vector) {
double x = data[0][0] * vector.x + data[0][1] * vector.y + data[0][2] * vector.z;
double y = data[1][0] * vector.x + data[1][1] * vector.y + data[1][2] * vector.z;
double z = data[2][0] * vector.x + data[2][1] * vector.y + data[2][2] * vector.z;
return new Vec3(x, y, z);
}
// Transpose
public Matrix3x3 transpose() {
double[][] transposed = new double[3][3];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
transposed[i][j] = data[j][i];
}
}
return new Matrix3x3(transposed);
}
public static Matrix3x3 identity() {
double[][] identity = {
{1, 0, 0},
{0, 1, 0},
{0, 0, 1}
};
return new Matrix3x3(identity);
}
public static Matrix3x3 zero() {
return new Matrix3x3(new double[3][3]);
}
}
```
Класс для матрицы 4х4 будет аналогичен классу `Matrix3x3`, с учетом увеличенного размера массива.
### Тестирование с использованием JUnit
Для тестирования этих классов мы используем фреймворк JUnit.
Пример теста для `Vec3` с использованием JUnit:
```java
// Vec3Test.java
import Math.Vec3;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class Vec3Test {
@Test
public void testAddition() {
Vec3 v1 = new Vec3(1, 2, 3);
Vec3 v2 = new Vec3(4, 5, 6);
Vec3 result = v1.add(v2);
assertEquals(5, result.x);
assertEquals(7, result.y);
assertEquals(9, result.z);
}
@Test
public void testDotProduct() {
Vec3 v1 = new Vec3(1, 2, 3);
Vec3 v2 = new Vec3(4, -5, 6);
double result = v1.dot(v2);
assertEquals(12, result);
}
@Test
public void testCrossProduct() {
Vec3 v1 = new Vec3(1, 0, 0);
Vec3 v2 = new Vec3(0, 1, 0);
Vec3 result = v1.cross(v2);
assertEquals(0, result.x);
assertEquals(0, result.y);
assertEquals(1, result.z);
}
}
```
Для каждой функции в ваших классах следует написать отдельный тест, чтобы убедиться в правильности их работы.
### Обработка ошибок
Для простоты, обработка ошибок включает в себя выброс исключений в случае недопустимых операций, таких как деление на ноль или попытка нормализации нулевого вектора.
### Дополнительные возможности
Если вы хотите расширить функциональность, вы можете добавить вычисление определителя, обратной матрицы и решение систем уравнений методом Гаусса в соответствующих классах матриц.
Эти исходные файлы и тесты позволят вам создать базовую библиотеку для работы с линейной алгеброй в Java.