| Parameter | Description | Range |
|---|---|---|
| width | Number of output image pixel width. | Limited to at least 50 and at most 2000. |
| height | Number of output image pixel height. | Limited to at least 50 and at most 2000. |
| mod | For calculation types product and sum fixed modulus for new composite number.For calculation type jacobi the parameter mod is the fixed number in jacobi-symbol For calculation type congruence mod defines and only creates a fractal image for composite numbers. |
Limited to at least 1 in all calculation types and at most 1000 in congruence, at most 10000 in jacobi and roots and at most 1000000 in all other calculation types. |
| mapping | Mapping of input pixel | Does not create a fractal image for in calculation types product, sum, roots and congruence. |
productpublic Color[][] product(final BiFunction<Long, Long, Long> fun, final long mod) {
final long[][] colors = new long[pixelWidth][pixelHeight];
java.util.stream.IntStream.range(1, pixelWidth + 1).parallel().forEach(i -> {
for(int j = 1; j <= pixelHeight; j++) {
final List<Long> primeFactors = new ArrayList<>();
final List<Integer> expFactors = new ArrayList<>(), preSortExpFactors = new ArrayList<>();
final Set<Long> visited = new HashSet<>();
Map<Long, Integer> factors;
long oldMapping = fun.apply((long)i, (long)j), happy = 0;
while (true) {
final long oldMappingMod = Math.floorMod(oldMapping, mod);
if(memoMap.containsKey(oldMappingMod)) {
happy = memoMap.get(oldMappingMod);
break;
}
if (visited.contains(oldMappingMod)) {
happy = -1; // BLACK
addAllVisitedToMemoMap(visited, happy);
break;
}
long mapping = 1, mappingNoMod;
boolean modHit = false;
factors = factors(oldMappingMod);
primeFactors.addAll(factors.keySet());
expFactors.addAll(factors.values());
preSortExpFactors.addAll(factors.values());
visited.add(oldMappingMod);
Collections.sort(primeFactors);
Collections.sort(expFactors);
for (int k = 0; k < primeFactors.size(); k++) {
final long pow = pow(primeFactors.get(k), expFactors.get(k));
mappingNoMod = mapping * pow;
mapping = (mapping * pow) % mod;
if (mapping < mappingNoMod) {
modHit = true;
}
}
if (mapping == 0) {
happy = -3; // GRAY
addAllVisitedToMemoMap(visited, happy);
break;
}
if (isPrime(mapping)) {
happy = mapping;
addAllVisitedToMemoMap(visited, happy);
break;
}
if (preSortExpFactors.equals(expFactors)) {
happy = -2; // WHITE
addAllVisitedToMemoMap(visited, happy);
break;
}
if (!modHit) { // mod did not hit -> cheat to get new prime factors
oldMapping = mapping + 1;
primeFactors.clear();
expFactors.clear();
preSortExpFactors.clear();
continue;
}
oldMapping = mapping;
primeFactors.clear();
expFactors.clear();
preSortExpFactors.clear();
}
colors[i - 1][j - 1] = happy;
}
});
memoMap.clear();
System.out.println(factors(mod));
return getSmoothColors(colors);
}
sumpublic Color[][] sum(final BiFunction<Long, Long, Long> fun, final long mod) {
final long[][] colors = new long[pixelWidth][pixelHeight];
final DoubleAdder progress = new DoubleAdder();
java.util.stream.IntStream.range(1, pixelWidth + 1).parallel().forEach(i -> {
for(int j = 1; j <= pixelHeight; j++) {
final List<Long> primeFactors = new ArrayList<>();
final List<Integer> expFactors = new ArrayList<>(), preSortExpFactors = new ArrayList<>();
final Set<Long> visited = new HashSet<>();
Map<Long, Integer> factors;
long oldMapping = fun.apply((long)i, (long)j), happy = 0;
while (true) {
final long oldMappingMod = Math.floorMod(oldMapping, mod);
if(memoMap.containsKey(oldMappingMod)) {
happy = memoMap.get(oldMappingMod);
break;
}
if (visited.contains(oldMappingMod)) {
happy = -1; // BLACK
addAllVisitedToMemoMap(visited, happy);
break;
}
long mapping = 0;
factors = factors(oldMappingMod);
primeFactors.addAll(factors.keySet());
expFactors.addAll(factors.values());
preSortExpFactors.addAll(factors.values());
visited.add(oldMappingMod);
Collections.sort(primeFactors);
Collections.sort(expFactors);
for (int k = 0; k < primeFactors.size(); k++) {
mapping = (mapping + pow(primeFactors.get(k), expFactors.get(k))) % mod;
}
if (mapping == 0) {
happy = -3; // GRAY
addAllVisitedToMemoMap(visited, happy);
break;
}
if (isPrime(mapping)) {
happy = mapping;
addAllVisitedToMemoMap(visited, happy);
break;
}
oldMapping = mapping;
primeFactors.clear();
expFactors.clear();
preSortExpFactors.clear();
}
colors[i - 1][j - 1] = happy;
}
});
memoMap.clear();
System.out.println(factors(mod));
return getSmoothColors(colors);
}
jacobiThis mode calculates the jacobi-symbol for each pixel and fixed (odd) modulus
https://en.wikipedia.org/wiki/Jacobi_symbol
rootsThis mode calculates the roots of the quadratic congruence where for each pixel .
The roots are connected by the bitwise and operator to before plotting the color.
congruenceThis mode calculates the number of solutions of the congruence where for each pixel .
The number of solutions of this equation is given by the formula: