Skip to content

Commit 990270c

Browse files
committed
Add stab function for parameter symnols
1 parent f640e58 commit 990270c

2 files changed

Lines changed: 58 additions & 53 deletions

File tree

src/circuit/qasm3_exporter.hpp

Lines changed: 5 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -39,59 +39,11 @@ inline std::string to_qasm3(circuit::QuantumCircuit &circ)
3939
auto name_map = get_standard_gate_name_mapping();
4040

4141
// Input parameter declarations
42-
uint_t num_params = circ.num_parameters();
43-
if (num_params > 0)
44-
{
45-
std::set<std::string> symbol_names;
46-
uint_t param_insts = qk_circuit_num_instructions(rust_circ.get());
47-
48-
for (uint_t i = 0; i < param_insts; i++)
49-
{
50-
QkCircuitInstruction inst;
51-
qk_circuit_get_instruction(rust_circ.get(), i, &inst);
52-
53-
for (uint_t j = 0; j < inst.num_params; j++)
54-
{
55-
char *param_str = qk_param_str(inst.params[j]);
56-
std::string s(param_str);
57-
qk_str_free(param_str);
58-
59-
// Extract all identifier tokens from the param string.
60-
static const std::set<std::string> reserved = {
61-
"sin", "cos", "tan", "asin", "acos", "atan", "exp", "log",
62-
"abs", "sign", "conjugate", "pi", "sqrt", "ceil", "floor"};
63-
64-
size_t pos = 0;
65-
while (pos < s.size())
66-
{
67-
const char c = s[pos];
68-
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_')
69-
{
70-
const size_t start = pos++;
71-
while (pos < s.size() &&
72-
((s[pos] >= 'a' && s[pos] <= 'z') ||
73-
(s[pos] >= 'A' && s[pos] <= 'Z') ||
74-
(s[pos] >= '0' && s[pos] <= '9') || s[pos] == '_'))
75-
{
76-
pos++;
77-
}
78-
const std::string token = s.substr(start, pos - start);
79-
if (reserved.find(token) == reserved.end())
80-
{
81-
symbol_names.insert(token);
82-
}
83-
continue;
84-
}
85-
pos++;
86-
}
87-
}
88-
qk_circuit_instruction_clear(&inst);
89-
}
90-
91-
for (const auto &sym : symbol_names)
92-
{
93-
qasm3 << "input float[64] " << sym << ";" << std::endl;
94-
}
42+
auto param_syms = circ.parameter_symbols();
43+
if (!param_syms.empty()) {
44+
for (const auto &sym : param_syms) {
45+
qasm3 << "input float[64] " << sym << ";" << std::endl;
46+
}
9547
}
9648

9749
// add header for non-standard gates

src/circuit/quantumcircuit_def.hpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,6 +1240,59 @@ class QuantumCircuit
12401240
return qk_circuit_num_param_symbols(rust_circuit_.get());
12411241
}
12421242

1243+
/// @brief Return a list of parameter symbol names used in the circuit.
1244+
/// @details It will be replaced by a C-API call when the API becomes available.
1245+
/// This is a stub function that collects unique parameter symbol names
1246+
/// by iterating through circuit instructions and extracting identifiers
1247+
/// from parameter string representations.
1248+
/// @note Duplicate symbol names are not accepted in Qiskit C++ because we do not
1249+
/// have a C-API to identify Parameters by UUID. Each symbol name must be unique.
1250+
/// @return A sorted list of unique parameter symbol names.
1251+
std::vector<std::string> parameter_symbols(void) const
1252+
{
1253+
std::set<std::string> symbol_names;
1254+
1255+
// Reserved identifiers that should not be treated as parameter symbols
1256+
static const std::set<std::string> reserved = {
1257+
"sin", "cos", "tan", "asin", "acos", "atan", "exp", "log",
1258+
"abs", "sign", "conjugate", "pi", "sqrt", "ceil", "floor", "conj"};
1259+
1260+
uint_t nops = qk_circuit_num_instructions(rust_circuit_.get());
1261+
for (uint_t i = 0; i < nops; i++) {
1262+
QkCircuitInstruction inst;
1263+
qk_circuit_get_instruction(rust_circuit_.get(), i, &inst);
1264+
1265+
for (uint_t j = 0; j < inst.num_params; j++) {
1266+
char *param_str = qk_param_str(inst.params[j]);
1267+
std::string s(param_str);
1268+
qk_str_free(param_str);
1269+
1270+
size_t pos = 0;
1271+
while (pos < s.size()) {
1272+
const char c = s[pos];
1273+
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_') {
1274+
const size_t start = pos++;
1275+
while (pos < s.size() &&
1276+
((s[pos] >= 'a' && s[pos] <= 'z') ||
1277+
(s[pos] >= 'A' && s[pos] <= 'Z') ||
1278+
(s[pos] >= '0' && s[pos] <= '9') || s[pos] == '_')) {
1279+
pos++;
1280+
}
1281+
const std::string token = s.substr(start, pos - start);
1282+
if (reserved.find(token) == reserved.end()) {
1283+
symbol_names.insert(token);
1284+
}
1285+
continue;
1286+
}
1287+
pos++;
1288+
}
1289+
}
1290+
qk_circuit_instruction_clear(&inst);
1291+
}
1292+
1293+
return std::vector<std::string>(symbol_names.begin(), symbol_names.end());
1294+
}
1295+
12431296
/// @brief Assign parameters to new parameters or values.
12441297
/// @param keys a list of keys
12451298
/// @param values a list of values

0 commit comments

Comments
 (0)