Reptorian G'MIC Filters

Not much progress, but did a few on improving Mitchell Concatenation. And renamed one command (I don’t remember the original name), and made one more command for now.

C:\Windows\System32>gmic echo ${rep_decimal2alt_base_digits\ 12301245,153616098709870114235}
[gmic]./ Start G'MIC interpreter (v.3.3.6).
1015169,7116789,4682705
[gmic]./ End G'MIC interpreter.

C:\Windows\System32>gmic echo ${rep_alt_base_digits2decimal\ 12301245,1015169,7116789,4682705}
[gmic]./ Start G'MIC interpreter (v.3.3.6).
153616098709870114235
[gmic]./ End G'MIC interpreter.

C:\Windows\System32>gmic echo ${rep_decimal2alt_base_digits\ 16777216,153616098709870114235}
[gmic]./ Start G'MIC interpreter (v.3.3.6).
545754,254519,2520507
[gmic]./ End G'MIC interpreter.

C:\Windows\System32>gmic echo ${rep_alt_base_digits2decimal\ 16777216,545754,254519,2520507}
[gmic]./ Start G'MIC interpreter (v.3.3.6).
153616098709870114235
[gmic]./ End G'MIC interpreter.

C:\Windows\System32>gmic echo ${rep_decimal2alt_base_digits\ 6,1244151515151421414}
[gmic]./ Start G'MIC interpreter (v.3.3.6).
1,3,2,4,1,4,2,2,5,2,3,1,3,5,2,0,5,4,5,2,1,3,5,4
[gmic]./ End G'MIC interpreter.

C:\Windows\System32>gmic echo ${rep_alt_base_digits2decimal\ 6,1,3,2,4,1,4,2,2,5,2,3,1,3,5,2,0,5,4,5,2,1,3,5,4}
[gmic]./ Start G'MIC interpreter (v.3.3.6).
1244151515151421414
[gmic]./ End G'MIC interpreter.

This is useful in application where you need alternative bases. That’s all I have for now.

Let’s see how am I doing.

  1. My SSD broke down. It’s probably recoverable. Hopefully, I can extract the user.gmic file I had some day. So, I have to set up everything on the new SSD, at least my HHD still works which only has the necessary documents, so I can at least keep the more important files.
  2. I got sick of what I was doing for now, so I took a small break and went straight into coding.
$ +pal {v(320)} +rep_square_chair [-1],8

#@cli rep_square_chair: [image], _iteration_level>1
#@cli : Generate Square Chair Images.
#@cli : Default values: '_iteration_level=5'
+rep_square_chair:
skip ${2=5}
check isint($2,2)

# Step 1. Import and valid.

pass$1 0
if !inrange(whd#-1,0,21564,0,1) error exec_image_size fi
size_of_palette:=w#-1

# Step 2. Create a palette from imported image.
colormap. 0
gcd_shuffle.

# Step 3. Generate random colors to apply per pixels
number_of_possible_color_combination:=perm(4,$size_of_palette,0)-1
number_of_possible_color_combination_index:=$number_of_possible_color_combination-1

repeat 4 {
 index:=v($number_of_possible_color_combination_index)
 start,end:=v(4)+[0,3]

 1,1,1,4,"
 const n_items=$size_of_palette;
 const choices=4;
 const index=$index;
 tiles=[0,1,2,3,0,1,2,0,1,0,0,2,0,1,1,0,1,0,1,0];

 comb=vector(#choices,0);
 V=1;
 R=perm(choices-1,n_items-V,0);
 K=R;

 while(K<=index,
  ++V;
  R=perm(choices-1,n_items-V,0);
  K+=R;
 );
 K-=R;
 comb[0]=V-1;

 for(p=2,p<choices,++p,
  ++V;
  R=perm(choices-p,n_items-V,0);
  K+=R;
  while(K<=index,
   ++V;
   R=perm(choices-p,n_items-V,0);
   K+=R;
  );
  K-=R;
  comb[p-1]=V-1;
 );

 comb[choices-1]=V+index-K;

 map((tiles)[v(4)*4,4],comb);"

}

# Step 4. Merge the pixels
append[-4--1] x

# Step 5. Generate the square chair reference image
5,1,1,4,>"begin(
  possible_permutations=
  [0,1,2,3
  ,0,1,3,2
  ,0,2,1,3
  ,0,2,3,1
  ,0,3,1,2
  ,0,3,2,1
  ,1,0,2,3
  ,1,0,3,2
  ,1,2,0,3
  ,1,2,3,0
  ,1,3,0,2
  ,1,3,2,0
  ,2,0,1,3
  ,2,0,3,1
  ,2,1,0,3
  ,2,1,3,0
  ,2,3,0,1
  ,2,3,1,0
  ,3,0,1,2
  ,3,0,2,1
  ,3,1,0,2
  ,3,1,2,0
  ,3,2,0,1
  ,3,2,1,0
  ];
  possible_arrangements=
  [0,1,2,3,
   0,1,2,0,
   1,0,0,2,
   0,1,1,0,
   1,0,1,0
  ];
 );
 map(
  (possible_arrangements)[x<<2,4],
  (possible_permutations)[v(23)<<2,4]
 );
 "

(${rep_ncr_combination_index2list\ 5,4,{v(3)}}) map. .. rm..
2,2,1,1,>begin(v=I[#-1,0];m=0;);v[m++]; gcd_shuffle..

repeat $2-1 {
  {vector2(w#-1<<1)},1,1
  eval.. draw(#-1,I[#-3,i],x<<1,y<<1,0,0,2,2,1,1)
  rm..
 }

rm..

# Step 6. Finally map the random colors onto square chair image
{vector2(w#-1<<1)},1,1
eval.. draw(#-1,I[#-3,i],x<<1,y<<1,0,0,2,2,1,1)
rm[-3,-2] map. .. rm[-3,-2]

Based on this - Tilings Encyclopedia | Square Chair

Please take some time to setup a backup!

Yes, I know. I have a HHD here as a external drive, and I kept the most important documents and files I need there, more so than G’MIC things. It’s a HHD so recovery of documents is feasible. So eventually, I’ll extract the user.gmic file from my old SSD. This time, I will set up a symlink so that I can smoothly transition more.

a backup is a multiple, point-in-time copies. A different drive is not a backup! Time you spend on things makes those things valuable!!

Okay, I seem to understood the most voted reply in this thread - combinatorics - What is the formula for combinations with identical elements? - Mathematics Stack Exchange

EDIT:
I deleted parts of earlier comment as I realized my assumptions is wrong. The code works as expected, it is just that my assumption is wrong. So, bad news for rep_string_combination.

Ok, I made at least rde class of combinatorics tool for permutations at least. I will rewrite rep_string_permutation* commands using rep_rde_permutation series of code. Or maybe work with a way to convert different encoding to utf-8 code point and back. I already have utf-8 processing code.

Still no luck with the size allocation for rde_combination. I even have a thread about that there. No one can solve it. And yet, the generation of combination sequence is correct.

Looks like I solved the size allocation problem for rde_combinations. Now, new problem is finding combinations at Nth index. All this image gives me a hint:

I had a vision that can be used to aid into development of Square Chair filter. A new combinatorics class rep_inc_combination. This is what it generates:

0,0,0,0,0
0,0,0,0,1
0,0,0,1,1
0,0,0,1,2
0,0,1,1,1
0,0,1,1,2
0,0,1,2,2
0,0,1,2,3
0,1,1,1,1
0,1,1,1,2
0,1,1,2,2
0,1,1,2,3
0,1,2,2,2
0,1,2,2,3
0,1,2,3,3
0,1,2,3,4

Pay attention to the numbers, they’re all equal to or greater than previous number by 1.

They also have index2list, and list2index too:

D:\>gmic echo ${rep_inc_combination_index2list\ 8,100}
[gmic]./ Start G'MIC interpreter (v.3.4.1).
0,1,2,2,2,3,3,3
[gmic]./ End G'MIC interpreter.

D:\>gmic echo ${rep_inc_combination_list2index\ 0,1,2,2,2,3,3,3}
[gmic]./ Start G'MIC interpreter (v.3.4.1).
100
[gmic]./ End G'MIC interpreter.

FYI, your recent post images disappeared. media.discordapp.net: This content is no longer available.

1 Like

Yeah, well, I won’t fix them. The important part is the code anyway, and letting people know what I’m doing.

Anyway, I used my combinatorics tools to generate square chair image:


#@cli rep_square_chair: [image],number_of_tiles>4,_iteration_level>1,number_of_color_choice
#@cli : Generate Square Chair Images.
#@cli : Default values: '_iteration_level=5'
+rep_square_chair:
skip ${3=4},${4=4}
check isint($2,4)&&isint($3,1)

m cmd_ext_inc_comb_img:"
 s x
 foreach {
  rep_extract_unique_values_and_count
  +rep_rde_permutations {crop(#-1,0,0,0,1,whd#-1,1,1,1)}
  rm..
 }
 a x
 "

pass$1 0
possible_combinations={perm($2,whd#-1,0)}
if $possible_combinations>(1<<53) error exec_combine_dim_pal_+_inp fi

dec_counts_of_tiles={$2-1}

+rep_inc_combinations 4,x crop. 1,100%
cmd_ext_inc_comb_img[-1]
um cmd_ext_inc_comb_img

shuffle. crop. 0,$dec_counts_of_tiles
+rep_ncr_combinations {w#-1},4,x shuffle. crop. 0,$dec_counts_of_tiles
fill.. map(I,I[#-1,x]) rm.

r_choice:=int(u(0,$possible_combinations-eps))
(${rep_ncr_combination_index2list\ {whd#-2},$2,$r_choice}) shuffle. map. ... rm...

rv[-2,-1]

r_choice:=v(0,w#-1-1)
({I[#-1,$r_choice]})
r. 2,2,1,1,-1

repeat $3-1 {
    200%,200%,1,1
    eval[-2] draw(#-1,I[#-3,i],x<<1,y<<1,0,0,2,2,1,1)
    rm[-2]
}

map[-1] [-3] rm[-3,-2]

EDIT: Amazing result is possible too!

2 Likes

I’m currently in the process of making my code easier to read, and I am replacing spaces with tabs because it is adjustable, and more accessible too. I hope I don’t screw things up, but I will download the older reptorian.gmic file onto my tablet so I can see how it went.

Feel free to let me know my code is more readable.

New command! - rep_val_ord_id

I do not think it’s the fastest solution there is. I think David could certainly make a better solution than I can on this.

Anyway, here is what it does.

If the first value starting from 0,0,0,0 is 85, then 85 becomes 0
If the second different value is 55, then 55 becomes 1.

And so forth.

C:\Windows\System32>gmic sp cat tic rep_val_ord_id toc
[gmic]./ Start G'MIC interpreter (v.3.4.2).
[gmic]./ Input sample image 'cat' (1 image 600x550x1x3).
[gmic]./ Initialize timer.
[gmic]./ Elapsed time: 0.639 s.
[gmic]./ Display image [0] = '[unnamed]'.
[0] = '[unnamed]':
  size = (600,550,1,3) [3867.2 Kio of float32].
  data = (0,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,4,4,4, ... ,126,129,176,176,41,201,209,210,162,176,16,17,176,209,148,209,209,149,150,191,41,196,16,129,121,129,16,175,25,193,209,201,210,162,196,41,209,41,210,17,129,129,176,175,41,200,16,16,129,129,41,41,176,178,178,176,209,41,129,64,99,16,175,153).
  min = 0, max = 224, mean = 102.929, std = 66.5345, coords_min = (0,0,0,0), coords_max = (223,153,0,2).
[gmic]./ End G'MIC interpreter.

0.639 seems slow for such a task. But, I wanted to have any values to converted to their order of appearance.

I also strongly suspect this command and rep_extract_unique_values_and_count can be combined too. I’m just not sure how to do that yet.

With math parser and its limitation, I been able to get it down to 0.395 s.

EDIT: I got it down to .200 s for sp cat. Still slow, but it will do. In addition, I made a new command which replace rep_extract_unique_values_and_count and rep_val_ord_id. Its name is rep_val2order and it can do both at the same time.

Made a generic version of rep_mode_type_int. It uses some of the code found in @David_Tschumperle 's colormap code. So, this is a generic command.

I will try to find a generic solution to rep_blend_mode_type_int too. Maybe even retire the non-generic ones too. Definitely for rep_blend_mode_type_int , but not necessarily for rep_mode_type_int as execution time is faster than the new command which uses some parts of colormap code.

EDIT: I made rep_val2order so much faster with the use of dictionary. And I actually coded my own dictionary solution instead of borrowing it which I did with rep_mode. But, I did learned from reading colormap code and figuring it all out with the use of visual debugging.

Looks like I can retire both rep_mode_type_int and rep_blend_mode_type_int as I made generic versions that are faster than both, and they don’t rely on 0-255 integer range. I will update the Mode GUI filter.

The algorithm I did for rep_mode_blend is between O(n) and O(n^2), and the closest to O(n) you can get without hash-table. Better space complexity too as it works in-place. Best of all, it no longer requires a parameter like the type_int version as it is a comparative algorithm.

See for yourself to see what I mean:

	for(p=S,p<s#-1,p+=S,
		current_color=(v)[p,S];
		found_duplicate=0;
		for(q=[0,0],q[1]<counts_limit,q+=[1,S],
			if(same((v)[q[1],S],current_color),
				++counts[q[0]];
				found_duplicate=1;
				break();
			);
		);
		found_duplicate?(
			found_at_least_one_duplicate=1;
		):(
			copy(v[counts_limit],current_color);
			counts_limit+=S;
			++counts[q[0]-1];
			++uniques_color_count;
		);
	);

Best case - All same color: O(n)
Worse case - All unique colors: O(n^2)

After making rep_square_chair, I will go back to hiatus.

I’m just going to save AI-generated code here to test for later, I know this one works:

def generate_arrays(N, max_int_sum):
    def backtrack(remaining, current):
        if len(current) == N:
            # If the current length is N, just add the current array
            result.append(current[:])
            return
        
        # Iterate from 0 to remaining (inclusive) for the next element
        for i in range(remaining + 1):
            current.append(i)
            backtrack(remaining - i, current)
            current.pop()

    result = []
    backtrack(max_int_sum, [])
    return result

# Example usage
N = 3
max_int_sum = 16
arrays = generate_arrays(N, max_int_sum)
for array in arrays:
    print(array)
print("Total arrays generated:", len(arrays))

Not sure for these:

from math import comb

def count_valid_arrays(N, max_int_sum, prefix):
    total = 0
    current_sum = 0
    
    for i in range(N):
        for x in range(prefix[i]):  # Count arrays starting with numbers less than prefix[i]
            remaining_sum = max_int_sum - current_sum - x
            if remaining_sum >= 0:
                # Calculate how many arrays can be formed with the remaining sum
                total += comb(remaining_sum + N - i - 1, N - i - 1)
        
        current_sum += prefix[i]
    
    return total

def lexicographic_rank(N, max_int_sum, array):
    rank = 1  # Start rank from 1 (1-based indexing)
    
    # Count the valid arrays before the given array
    rank += count_valid_arrays(N, max_int_sum, array)
    
    return rank

# Example usage
N = 3
max_int_sum = 4
array = [1, 2, 1]
rank = lexicographic_rank(N, max_int_sum, array)
print("Lexicographic Rank:", rank)
To find the lexicographic rank of a specific array of non-negative integers that sum to a value less than or equal to max_int_sum, you can directly calculate how many valid arrays would precede the given array in lexicographic order.

Here’s how you can do that:

    Iterate Through Each Element: For each element in the array, count how many combinations can be formed by fixing previous elements and varying the current element to be less than the given one.

    Use Combinatorial Counting: For each choice made, compute how many ways you can fill the remaining positions.

Here's the complete code to achieve this:

python

from math import comb

def count_valid_arrays(N, max_int_sum, prefix):
    total = 0
    current_sum = 0

    for i in range(N):
        for x in range(prefix[i]):  # Count arrays starting with numbers less than prefix[i]
            remaining_sum = max_int_sum - current_sum - x
            if remaining_sum >= 0:
                # Calculate how many arrays can be formed with the remaining sum
                total += comb(remaining_sum + N - i - 1, N - i - 1)
        
        current_sum += prefix[i]

    return total

def lexicographic_rank(N, max_int_sum, array):
    rank = 1  # Start rank from 1 (1-based indexing)
    
    # Count the valid arrays before the given array
    rank += count_valid_arrays(N, max_int_sum, array)
    
    return rank

# Example usage
N = 3
max_int_sum = 4
array = [1, 2, 1]
rank = lexicographic_rank(N, max_int_sum, array)
print("Lexicographic Rank:", rank)

There’s the pressing question of converting them into G’MIC, but I"ll figure that out when I feel like it.

Ok, I have 4 new commands. 4 of which has application to Lyapunov Fractal. Particularly strings like “AAABBBCCC”. The number of characters per chars.

rep_sum_permutation* is used to generate all possible list of integer numbers whose sum is less than or equal to a integer value, and rep_freq_sortvals sorts scalar values, and then return the frequency only.