Hashtron inference: Difference between revisions

From Rosetta Code
Content added Content deleted
m (→‎Description: clarify finite functions)
(non draft)
Line 1: Line 1:
{{draft task}}
{{task}}
= Hashtron classifier inference =
= Hashtron classifier inference =



Revision as of 10:43, 24 May 2024

Task
Hashtron inference
You are encouraged to solve this task according to the task description, using any language you may know.

Hashtron classifier inference

Description

This task involves implementing a Hashtron classifier inference function. Hashtron classifier program can be machine learned to calculate arbitrary finite computable functions or sets (Given enough CPU time and RAM). The Hashtron classifier takes a command and a number of bits to infer, using a provided program configuration. The inference function for the test will generate a pseudo-random n-bits output. The inference function for the square root demo will generate a square root of a command in range: 0 <= command < 256.

Examples

Test

Given the following program configuration and input command:

Program configuration:

Input command:

42

Number of bits:

64

Program:

[[0,2]]

The inference function should process the input and generate the following 64-bit output:

14106184687260844995

Square root demo

Given the following program configuration and input command:

Program configuration:

Input command: A byte (integer) to take square root of.

Number of bits:

4

Program:

[[8776,79884], [12638,1259], [9953,1242], [4658,1228], [5197,1210], [12043,1201],
[6892,1183], [7096,1168], [10924,1149], [5551,1136], [5580,1123], [3735,1107],
[3652,1091], [12191,1076], [14214,1062], [13056,1045], [14816,1031], [15205,1017],
[10736,1001], [9804,989], [13081,974], [6706,960], [13698,944], [14369,928],
[16806,917], [9599,906], [9395,897], [4885,883], [10237,870], [10676,858],
[18518,845], [2619,833], [13715,822], [11065,810], [9590,799], [5747,785],
[2627,776], [8962,764], [5575,750], [3448,738], [5731,725], [9434,714],
[3163,703], [3307,690], [3248,678], [3259,667], [3425,657], [3506,648],
[3270,639], [3634,627], [3077,617], [3511,606], [27159,597], [27770,589],
[28496,580], [28481,571], [29358,562], [31027,552], [30240,543], [30643,534],
[31351,527], [31993,519], [32853,510], [33078,502], [33688,495], [29732,487],
[29898,480], [29878,474], [26046,468], [26549,461], [28792,453], [26101,446],
[32971,439], [29704,432], [23193,426], [29509,421], [27079,415], [32453,409],
[24737,404], [25725,400], [23755,395], [52538,393], [53242,386], [19609,380],
[26492,377], [24566,358], [31163,368], [57174,363], [26639,364], [31365,357],
[60918,350], [21235,338], [28072,322], [28811,314], [27571,320], [17635,309],
[51968,169], [54367,323], [60541,254], [26732,270], [52457,157], [27181,276],
[19874,227], [22797,320], [59346,271], [25496,260], [54265,231], [22281,250],
[42977,318], [26008,240], [87604,142], [94647,314], [52292,157], [20999,216],
[89253,316], [22746,29], [68338,312], [22557,317], [110904,104], [70975,285],
[51835,277], [51871,313], [132221,228], [18522,290], [68512,285], [118816,302],
[150865,268], [68871,273], [68139,290], [84984,285], [150693,266], [396047,272],
[84923,269], [215562,258], [68015,248], [247689,235], [214471,229], [264395,221],
[263287,212], [280193,201], [108065,194], [263616,187], [148609,176], [263143,173],
[378205,162], [312547,154], [50400,147], [328927,140], [279217,132], [181111,127],
[672098,118], [657196,113], [459383,111], [833281,105], [520281,102], [755397,95],
[787994,91], [492444,82], [1016592,77], [656147,71], [819893,66], [165531,61],
[886503,57], [1016551,54], [3547827,49], [14398170,43], [395900,41], [4950628,37],
[11481175,33], [100014881,30], [8955328,31], [11313984,27], [13640855,23],
[528553762,21], [63483027,17], [952477,8], [950580,4], [918378,2], [918471,1]]

The inference function should process the input and generate the square root of the input byte.

Example Code

Python

def hash(n, s, max_val):
    # Mixing stage, mix input with salt using subtraction
    m = (n - s) & 0xFFFFFFFF
    # Hashing stage, use xor shift with prime coefficients
    m ^= (m << 2) & 0xFFFFFFFF
    m ^= (m << 3) & 0xFFFFFFFF
    m ^= (m >> 5) & 0xFFFFFFFF
    m ^= (m >> 7) & 0xFFFFFFFF
    m ^= (m << 11) & 0xFFFFFFFF
    m ^= (m << 13) & 0xFFFFFFFF
    m ^= (m >> 17) & 0xFFFFFFFF
    m ^= (m << 19) & 0xFFFFFFFF
    # Mixing stage 2, mix input with salt using addition
    m += s
    m &= 0xFFFFFFFF
    # Modular stage using Lemire's fast alternative to modulo reduction
    return ((m * max_val) >> 32) & 0xFFFFFFFF


def inference(command, bits, program):
    out = 0
    # Check if the program is empty
    if len(program) == 0:
        return out
    # Iterate over the bits
    for j in range(bits):
        input_val = command | (j << 16)
        ss, maxx = program[0]
        input_val = hash(input_val, ss, maxx)
        for i in range(1, len(program)):
            s, max_val = program[i]
            maxx -= max_val
            input_val = hash(input_val, s, maxx)
        input_val &= 1
        if input_val != 0:
            out |= 1 << j
    return out

print(inference(42,64,[[0,2]]))

Go

package main

func Inference(command uint32, bits byte, program [][2]uint32) (out uint64) {
	// Check if the program is empty
	if len(program) == 0 {
		return
	}

	// Iterate over the bits
	for j := byte(0); j < bits; j++ {
		var input = command | (uint32(j) << 16)
		var ss, maxx = program[0][0], program[0][1]
		input = Hash(input, ss, maxx)
		for i := 1; i < len(program); i++ {
			var s, max = program[i][0], program[i][1]
			maxx -= max
			input = Hash(input, s, maxx)
		}
		input &= 1
		if input != 0 {
			out |= 1 << j
		}
	}
	return
}

func Hash(n uint32, s uint32, max uint32) uint32 {
	// Mixing stage, mix input with salt using subtraction
	var m = n - s

	// Hashing stage, use xor shift with prime coefficients
	m ^= m << 2
	m ^= m << 3
	m ^= m >> 5
	m ^= m >> 7
	m ^= m << 11
	m ^= m << 13
	m ^= m >> 17
	m ^= m << 19

	// Mixing stage 2, mix input with salt using addition
	m += s

	// Modular stage using Lemire's fast alternative to modulo reduction
	return uint32((uint64(m) * uint64(max)) >> 32)
}

func main() {
	println(Inference(42, 64, [][2]uint32{{0, 2}}))
}

https://go.dev/play/p/AsmOzKWx7jB

PHP

// define hashtron hash
$hash = function($n, $s, $max) {
    // Ensure the inputs are treated as unsigned 32-bit integers
    $n = $n & 0xFFFFFFFF;
    $s = $s & 0xFFFFFFFF;
    $max = $max & 0xFFFFFFFF;

    // Mixing stage, mix input with salt using subtraction
    $m = ($n - $s) & 0xFFFFFFFF;

    // Hashing stage, use xor shift with prime coefficients
    $m ^= ($m << 2) & 0xFFFFFFFF;
    $m ^= ($m << 3) & 0xFFFFFFFF;
    $m ^= ($m >> 5) & 0xFFFFFFFF;
    $m ^= ($m >> 7) & 0xFFFFFFFF;
    $m ^= ($m << 11) & 0xFFFFFFFF;
    $m ^= ($m << 13) & 0xFFFFFFFF;
    $m ^= ($m >> 17) & 0xFFFFFFFF;
    $m ^= ($m << 19) & 0xFFFFFFFF;

    // Mixing stage 2, mix input with salt using addition
    $m = ($m + $s) & 0xFFFFFFFF;

    // Modular stage using multiply-shift trick
    // Cast to 64-bit integer for multiplication
    $result = ((($m & 0xFFFFFFFF) * ($max & 0xFFFFFFFF)) >> 32) & 0xFFFFFFFF;

    return $result;
};


// define hashtron inference
$infer = function($command, $bits, $program) {
    global $hash;
    $out = 0;
   
    $programLength = count($program);
    if ($programLength == 0) {
        return $out;
    }

    for ($j = 0; $j < $bits; $j++) {
        $input = ($command & 0xFFFFFFFF) | (($j & 0xFF) << 16);

        $ss = $program[0][0];
        $maxx = $program[0][1];

        $input = $hash($input, $ss, $maxx);

        for ($i = 1; $i < $programLength; $i++) {
            $s = $program[$i][0];
            $max = $program[$i][1];
            $maxx -= $max;

            $input = $hash($input, $s, $maxx);
        }

        $input &= 1;
        if ($input != 0) {
            $out |= 1 << $j;
        }
    }

    return $out;
};

Java

public class Main {
    public static long inference(long command, long bits, long[][] program) {
        long out = 0;

        // Check if the program is empty
        if (program.length == 0) {
            return out;
        }

        // Iterate over the bits
        for (long j = 0; j < bits; j++) {
            long input = (command & 0xFFFFFFFF) | (((long)j & 0xFF) << (long)16);
            long ss = program[0][0];
            long maxx = program[0][1];
            input = hash(input, ss, maxx);
            for (long i = 1; i < program.length; i++) {
                long s = program[(int)i][0];
                long max = program[(int)i][1];
                maxx -= max;
                input = hash(input, s, maxx);
            }
            input &= 1;
            if (input != 0) {
		out |= (long)1 << (long) j;
            }
        }
        return out;
    }
    public static long hash(long n, long s, long max_val) {
        // Mixing stage, mix input with salt using subtraction
        long m = (n - s) & 0xFFFFFFFFL;
        
        // Hashing stage, use xor shift with prime coefficients
        m ^= (m << 2) & 0xFFFFFFFFL;
        m ^= (m << 3) & 0xFFFFFFFFL;
        m ^= (m >> 5) & 0xFFFFFFFFL;
        m ^= (m >> 7) & 0xFFFFFFFFL;
        m ^= (m << 11) & 0xFFFFFFFFL;
        m ^= (m << 13) & 0xFFFFFFFFL;
        m ^= (m >> 17) & 0xFFFFFFFFL;
        m ^= (m << 19) & 0xFFFFFFFFL;
        
        // Mixing stage 2, mix input with salt using addition
        m += s;
        m &= 0xFFFFFFFFL;
        
        // Modular stage using Lemire's fast alternative to modulo reduction
        return ((m * max_val) >>> 32) & 0xFFFFFFFFL;
    }

    public static void main(String[] args) {

        long command = 42;
        long[][] program = {{0,2}}; // Example program
	    long bits = 64;
        long result = inference(command, bits, program);
        System.out.println(Long.toUnsignedString(result));

    }
}

Wren

Translation of: Python
Library: Wren-long
Library: Wren-fmt
import "./long" for ULong
import "./fmt" for Fmt

var hash = Fn.new { |n, s, max|
    // 32 bit mask
    var k = 0xFFFFFFFF

	// Mixing stage, mix input with salt using subtraction
    var m = (n - s) & k

	// Hashing stage, use xor shift with prime coefficients
	m = m ^ ((m << 2)  & k)
	m = m ^ ((m << 3)  & k)
    m = m ^ ((m >> 5)  & k)
	m = m ^ ((m >> 7)  & k)
	m = m ^ ((m << 11) & k)
	m = m ^ ((m << 13) & k)
	m = m ^ ((m >> 17) & k)
	m = m ^ ((m << 19) & k)

    // Mixing stage 2, mix input with salt using addition
	m = (m + s) & k

	// Modular stage using Lemire's fast alternative to modulo reduction
	return ((ULong.new(m) * ULong.new(max)) >> 32).toSmall & k
}

var inference = Fn.new { |command, bits, program|
    var out = ULong.zero

    // Check if the program is empty
    if (program.count == 0) return out

    // Iterate over the bits
    for (j in 0...bits) {
        var input = command | (j << 16)
        var ss = program[0][0]
        var maxx = program [0][1]
        input = hash.call(input, ss, maxx)
        for (i in 1...program.count) {
            var s = program[i][0]
            var max = program[i][1]
            maxx = maxx - max
            input = hash.call(input, s, maxx)
        }
        input = input & 1
        if (input != 0) out = out | (ULong.one << j)
    }
    return out
}

System.print("Test demo:")
var program = [[0, 2]]
System.print(inference.call(42, 64, program))

program = [
    [8776,79884], [12638,1259], [9953,1242], [4658,1228], [5197,1210], [12043,1201],
    [6892,1183], [7096,1168], [10924,1149], [5551,1136], [5580,1123], [3735,1107],
    [3652,1091], [12191,1076], [14214,1062], [13056,1045], [14816,1031], [15205,1017],
    [10736,1001], [9804,989], [13081,974], [6706,960], [13698,944], [14369,928],
    [16806,917], [9599,906], [9395,897], [4885,883], [10237,870], [10676,858],
    [18518,845], [2619,833], [13715,822], [11065,810], [9590,799], [5747,785],
    [2627,776], [8962,764], [5575,750], [3448,738], [5731,725], [9434,714],
    [3163,703], [3307,690], [3248,678], [3259,667], [3425,657], [3506,648],
    [3270,639], [3634,627], [3077,617], [3511,606], [27159,597], [27770,589],
    [28496,580], [28481,571], [29358,562], [31027,552], [30240,543], [30643,534],
    [31351,527], [31993,519], [32853,510], [33078,502], [33688,495], [29732,487],
    [29898,480], [29878,474], [26046,468], [26549,461], [28792,453], [26101,446],
    [32971,439], [29704,432], [23193,426], [29509,421], [27079,415], [32453,409],
    [24737,404], [25725,400], [23755,395], [52538,393], [53242,386], [19609,380],
    [26492,377], [24566,358], [31163,368], [57174,363], [26639,364], [31365,357],
    [60918,350], [21235,338], [28072,322], [28811,314], [27571,320], [17635,309],
    [51968,169], [54367,323], [60541,254], [26732,270], [52457,157], [27181,276],
    [19874,227], [22797,320], [59346,271], [25496,260], [54265,231], [22281,250],
    [42977,318], [26008,240], [87604,142], [94647,314], [52292,157], [20999,216],
    [89253,316], [22746,29], [68338,312], [22557,317], [110904,104], [70975,285],
    [51835,277], [51871,313], [132221,228], [18522,290], [68512,285], [118816,302],
    [150865,268], [68871,273], [68139,290], [84984,285], [150693,266], [396047,272],
    [84923,269], [215562,258], [68015,248], [247689,235], [214471,229], [264395,221],
    [263287,212], [280193,201], [108065,194], [263616,187], [148609,176], [263143,173],
    [378205,162], [312547,154], [50400,147], [328927,140], [279217,132], [181111,127],
    [672098,118], [657196,113], [459383,111], [833281,105], [520281,102], [755397,95],
    [787994,91], [492444,82], [1016592,77], [656147,71], [819893,66], [165531,61],
    [886503,57], [1016551,54], [3547827,49], [14398170,43], [395900,41], [4950628,37],
    [11481175,33], [100014881,30], [8955328,31], [11313984,27], [13640855,23],
    [528553762,21], [63483027,17], [952477,8], [950580,4], [918378,2], [918471,1]
]
System.print("\nSquare root demo for commands in [0, 255]:")
Fmt.tprint("$2i", (0..255).map { |i| inference.call(i, 4, program) }, 16)
Output:
Test demo:
14106184687260844995

Square root demo for commands in [0, 255]:
 0  1  1  1  2  2  2  2  2  3  3  3  3  3  3  3
 4  4  4  4  4  4  4  4  4  5  5  5  5  5  5  5
 5  5  5  5  6  6  6  6  6  6  6  6  6  6  6  6
 6  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7
 8  8  8  8  8  8  8  8  8  8  8  8  8  8  8  8
 8  9  9  9  9  9  9  9  9  9  9  9  9  9  9  9
 9  9  9  9 10 10 10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 11 11 11 11 11 11 11
11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11
12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12
12 12 12 12 12 12 12 12 12 13 13 13 13 13 13 13
13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13
13 13 13 13 14 14 14 14 14 14 14 14 14 14 14 14
14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14
14 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15
15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15