ベクトルクラスの作成
Javaの標準ライブラリには,
MultiVectorクラスは,
リスト1 MultiVector.
public class MultiVector {
private double[] data;
// 指定された次元数でゼロベクトルを作成
public MultiVector(int dimension) {
data = new double[dimension];
}
// 次元数チェック
private void checkDimension(MultiVector v) {
if (dimension() != v.dimension()) {
throw new IllegalArgumentException("Dimension mismatch.");
}
}
// 指定されたベクトルを加算
public void add(MultiVector v) {
checkDimension(v);
for (int i = 0; i < dimension(); i++) {
data[i] += v.data[i];
}
}
...
}
MultiVectorには,
- void add(MultiVector v)
- ベクトルにvを加算します。
- void subtract(MultiVector v)
- ベクトルからvを減算します。
- void multiply(double d)
- ベクトル成分をd倍します。
- void divide(double d)
- ベクトル成分をdで除算します。
- double norm()
- ベクトルのノルム
(長さ) を計算します。 - void normalize()
- ベクトルを正規化します
(ノルムが1になるように調整します)。 - double distanceSq(MultiVector v)
- このベクトルとvの距離の二乗を計算します。
ノードクラスの作成
次に,
まず,
リスト2 Node.
public interface Node {
List<MultiVector> getVectors();
}
次に,
リスト3 Item.
public class Item implements Node {
private String name; // 結果出力用のプロパティ
private MultiVector vector;
public Item(String name, MultiVector vector) {
this.name = name;
this.vector = vector;
}
public String getName() { return name; }
public MultiVector getVector() { return vector; }
public List<MultiVector> getVectors() {
// ベクトル自身をリスト化して返す
return Collections.singletonList(vector);
}
}
同様に,
リスト4 Cluster.
public class Cluster implements Node {
private Node left;
private Node right;
private List<MultiVector> cachedVectors;
public Cluster(Node left, Node right) {
this.left = left;
this.right = right;
}
public Node getLeft() { return left; }
public Node getRight() { return right; }
public List<MultiVector> getVectors() {
// 高速化のため結果をキャッシュする
if (cachedVectors == null) {
cachedVectors = new ArrayList<MultiVector>();
// leftノードとrightノードのベクトル集合を連結
cachedVectors.addAll(left.getVectors());
cachedVectors.addAll(right.getVectors());
}
return cachedVectors;
}
}