public static InvertibleCodec<double[], DoubleGene>
	ofVector(final DoubleRange... domains) {
		if (domains.length == 0) {
			throw new IllegalArgumentException("Domains must not be empty.");
		}

		final ISeq<DoubleChromosome> chromosomes = Stream.of(domains)
			.peek(Objects::requireNonNull)
			.map(DoubleGene::of)
			.map(DoubleChromosome::of)
			.collect(ISeq.toISeq());

		return InvertibleCodec.of(
			Genotype.of(chromosomes),
			gt -> {
				final double[] args = new double[gt.length()];
				for (int i = gt.length(); --i >= 0;) {
					args[i] = gt.get(i).gene().doubleValue();
				}
				return args;
			},
			val -> Genotype.of(
				IntStream.range(0, val.length)
					.mapToObj(i ->
						DoubleChromosome.of(DoubleGene.of(val[i], domains[i])))
					.collect(ISeq.toISeq())
			)
		);
	}
Create a vector {@link InvertibleCodec} for the given ranges. Each vector
element might have a different domain. The vector length is equal to the
number of domains.

@param domains the domain ranges
@return a new vector {@code Codec}
@throws NullPointerException if one of the arguments is {@code null}
@throws IllegalArgumentException if the {@code domains} array is empty
jenetics/src/main/java/io/jenetics/engine/Codecs.java