Arithemetic Circuit (RUST)
Arithemetic Circuit implementated in the RUST programming langauge...
Last updated
Arithemetic Circuit implementated in the RUST programming langauge...
Last updated
Arithmetic circuits come to us from a field of research called "computational complexity theory" (CCT), and are used as the standard model for computing polynomials. An arithmetic circuit is an abstract concept, but it operates similar to a logic circuit: it takes variables and numbers as inputs, which go through arithmetic gates such as "add" or "multiply", like on the image below. Red boxes are input variables, grey octagon is a constant, green circles are operation gates, and a blue box on the right is the output. 1
The design approach we would be taking is very similar to the implementations in this book.
Design the structural interface and Data structures
Comment out the step needed for implementing this interface
Implement the complete interface
Write Unit test. :)
you can find the complete code implementation here
Interface and Data Structure
This circuit need just one method, this method would be responsible for evaluating the circuit on some given input.\
Data Structure
Circuit
: Represents the entire arithmetic circuit. It contains multiple layers of gates.
CircuitLayer
: Represents a single layer within the circuit. Each layer contains multiple gates. This struct helps in organizing gates into different layers, which can be useful for implementing and understanding the flow of computations.
Gate
: Represents an individual gate within a layer. Each gate has a type and inputs. The Gate struct represents an individual gate with a specific type and inputs. g_type indicates the type of operation the gate performs (Add
or Mul
). inputs is an array of two usize values representing the indices of the input gates. These indices refer to the outputs of gates from previous layers or input values.
GateType
: Enum defining the types of operations that a gate can perform (addition or multiplication).
An example on how this gate would be constructed is given by;
In this section, we will discuss the implementation of the CircuitInterface
trait for the Circuit
struct. This implementation provides a method to evaluate the circuit given some input values. The evaluation involves computing the outputs of each gate in the circuit layer by layer, starting from the inputs.
The evaluate method takes a reference to a slice of inputs and returns a CircuitEvaluation<F>
, where F
is a generic type that supports addition and multiplication.
The CircuitEvaluation
struct holds the results of the circuit evaluation. It contains a vector of layers, where each layer is a vector of values representing the outputs of the gates in that layer.
The evaluate method processes the circuit in a reverse manner, starting from the input layer and working backwards through the layers of gates.
Explanation
Initialization:
The method starts by initializing an empty vector layers to hold the results of each layer.
current_input is set to the initial input provided to the evaluate method. • The initial input is added to the layers vector.
Layer Processing: • The method iterates over the circuit layers in reverse order using self.layers.iter().rev()
. • For each layer, it processes each gate by iterating over layer.layer
. • Depending on the gate type (GateType::Add
or GateType::Mu
l), it evaluates the gate using the current inputs. • The results of the gates in the current layer are collected into temp_layer
. • temp_layer
is added to the layer's vector. • current_input
is updated to refer to the outputs of the current layer.
Finalization: • After processing all layers, the layers vector is reversed to get the correct order of layers from input to output. • A CircuitEvaluation struct is created with the layer's vector and returned.
Here is a sample code for building and executing a Circuit
given some input
.