syntax = "proto3";

package cirq.api.google.v1;

option java_package = "com.google.cirq.api.google.v1";
option java_outer_classname = "ParamsProto";
option java_multiple_files = true;

// Specifies how to repeatedly sample a circuit, with or without sweeping over
// varying parameter-dicts.
message ParameterSweep {
  // How many times to sample, for each parameter-dict that is swept over.
  // This must be set to a value strictly greater than zero.
  int32 repetitions = 1;

  // Which parameters, that control gates in the circuit, to try.
  //
  // The keys of the parameters generated by this sweep must be a superset
  // of the keys in the program's operations.  When this is not specified,
  // no parameterization is assumed (and the program must have no
  // ParameterizedFloat's with keys.
  ProductSweep sweep = 2;
}

// A cartesian product of parameter sweeps.
message ProductSweep {
  // A list of parameter sweeps to combine into a cartesian sweep.
  //
  // Example: if one of the factors assigns
  // "a": 0.0
  // "a": 1.0
  // and another assigns
  // "b": 2.0
  // "b": 3.0
  // then the product of these assigns
  // "a": 0.0, "b": 2.0
  // "a": 0.0, "b": 3.0
  // "a": 1.0, "b": 2.0
  // "a": 1.0, "b": 3.0
  repeated ZipSweep factors = 1;
}

// A pairwise-joining of parameter sweeps.
message ZipSweep {
  // Note: if one sweep is shorter, the others will be truncated.
  //
  // Example: if one of the factors assigns
  // "a": 0.0
  // "a": 1.0
  // and another assigns
  // "b": 2.0
  // "b": 3.0
  // then the product of these assigns
  // "a": 0.0, "b": 2.0
  // "a": 1.0, "b": 3.0
  repeated SingleSweep sweeps = 1;
}

// A set of values to try for a particular parameter.
message SingleSweep {
  // The parameter key being varied. This cannot be the empty string.
  string parameter_key = 1;

  // How to vary the parameter.
  oneof sweep {
    // An explicit list of points to try.
    Points points = 2;
    // Uniformly-spaced sampling over a range.
    Linspace linspace = 3;
  }
}

// A list of explicit values.
message Points {
  // The values.
  repeated float points = 1;
}

// A range of evenly-spaced values.
//
// Example: if the first_point is 1.0, the last_point is 2.0 ,
// and the num_points is 5, thi corresponds to the points
//   1.0, 1.25, 1.5, 1.75, 2.0
message Linspace {
  // The start of the range.
  float first_point = 1;
  // The end of the range.
  float last_point = 2;
  // The number of points in the range (including first and last). Must be
  // greater than zero. If it is 1, the first_point and last_point must be
  // the same.
  int64 num_points = 3;
}

// A point sampled during a parameter sweep.
message ParameterDict {
  // Maps parameter names to values.
  map<string, float> assignments = 1;
}
