Query Complexity Guide
Deterministic, randomized, and quantum query complexity measures for Boolean functions.
Overview
Query complexity measures how many input bits must be queried to compute a Boolean function. BooFun provides comprehensive tools including:
Decision tree complexity (D, D_avg)
Randomized complexity (R₀, R₁, R₂)
Quantum complexity (Q₂, QE) and lower bounds
Sensitivity measures (s, bs, es)
Certificate complexity (C, C₀, C₁)
Degree measures (exact, approximate, threshold)
Decision tree algorithms (DP, enumeration)
Decision Tree Complexity
The fundamental deterministic query measure.
Measure |
Function |
Description |
|---|---|---|
D(f) |
|
Deterministic depth |
D_avg(f) |
|
Average depth |
Optimal tree (DP) |
|
DP algorithm |
Randomized depth |
|
R(f) |
Count optimal trees |
|
Enumeration |
Example: Decision Tree Analysis
import boofun as bf
from boofun.analysis import complexity
from boofun.analysis.decision_trees import (
decision_tree_depth_dp,
count_decision_trees
)
f = bf.majority(5)
# Deterministic decision tree depth
D_f = complexity.decision_tree_depth(f)
print(f"D(MAJ_5) = {D_f}")
# Using DP algorithm
D_dp = decision_tree_depth_dp(f)
print(f"D(f) via DP = {D_dp}")
# Count number of optimal decision trees
count = count_decision_trees(f)
print(f"Number of optimal trees: {count}")
Sensitivity Measures
How sensitive is f to single-bit changes?
Measure |
Function |
Description |
|---|---|---|
s(f) |
|
Sensitivity |
bs(f) |
|
Block sensitivity |
es(f) |
|
Everywhere sensitivity |
Sensitivity vs Block Sensitivity
Sensitivity s(f): Maximum over all x of the number of single-bit flips that change f(x)
Block sensitivity bs(f): Maximum over all x of the number of disjoint blocks whose flip changes f(x)
from boofun.analysis import complexity
f = bf.AND(5)
s = complexity.max_sensitivity(f)
bs = complexity.block_sensitivity(f)
print(f"s(AND_5) = {s}") # = 1
print(f"bs(AND_5) = {bs}") # = 5
# Note: bs(f) ≥ s(f) always, with possible polynomial gap
Certificate Complexity
Minimum number of bits that “prove” a function value.
Measure |
Function |
Description |
|---|---|---|
C(f) |
|
Certificate complexity |
C₀(f) |
|
0-certificate |
C₁(f) |
|
1-certificate |
Example: Certificates
from boofun.analysis.complexity import (
certificate_complexity,
max_certificate_complexity
)
f = bf.OR(5)
C_f = certificate_complexity(f)
C_0 = max_certificate_complexity(f, target=0)
C_1 = max_certificate_complexity(f, target=1)
print(f"C(OR_5) = {C_f}")
print(f"C_0(OR_5) = {C_0}") # Need to see all 0s
print(f"C_1(OR_5) = {C_1}") # Just need one 1
Quantum Complexity
Quantum query complexity and lower bounds.
Measure |
Function |
Description |
|---|---|---|
Ambainis bound |
|
Quantum lower bound |
Spectral adversary |
|
Spectral method |
Polynomial method |
|
deg(f) bound |
Example: Quantum Bounds
from boofun.analysis import query_complexity as qc
f = bf.OR(4)
# Ambainis adversary method lower bound
amb = qc.ambainis_complexity(f)
print(f"Ambainis bound: Q(OR_4) ≥ {amb:.2f}")
# For comparison, classical deterministic
D_f = complexity.decision_tree_depth(f)
print(f"D(OR_4) = {D_f}")
# Quantum can achieve sqrt speedup for OR
Degree Measures
Polynomial degree measures related to query complexity.
Measure |
Function |
Description |
|---|---|---|
deg(f) |
|
Exact degree |
deg̃(f) |
|
Approximate degree |
deg_th(f) |
|
Threshold degree |
Example: Degree Analysis
from boofun.analysis import complexity
f = bf.parity(4)
deg = complexity.exact_degree(f)
print(f"deg(PAR_4) = {deg}") # = 4 (full degree)
f = bf.OR(4)
deg = complexity.exact_degree(f)
print(f"deg(OR_4) = {deg}") # = 4
Huang’s Theorem
The celebrated result connecting sensitivity to degree.
Function |
Description |
|---|---|
|
s(f) ≥ √deg(f) |
|
Verify the relationship |
Example: Verifying Huang’s Theorem
from boofun.analysis import huang
f = bf.AND(6)
# Verify Huang's theorem: s(f) >= sqrt(deg(f))
result = huang.verify_huang_theorem(f)
print(f"s(f) = {result['sensitivity']}")
print(f"deg(f) = {result['degree']}")
print(f"sqrt(deg(f)) = {result['sqrt_degree']:.2f}")
print(f"Huang satisfied: {result['satisfied']}")
Complexity Relationships
Known relationships between measures (all polynomial):
s(f) ≤ bs(f) ≤ C(f) ≤ D(f)
↓
deg(f) ≤ D(f)
↓
Q(f) ≤ D(f)
Key results:
- D(f) ≤ bs(f)² (classical)
- s(f) ≥ √deg(f) (Huang 2019)
- Q(f) = Θ(√D(f)) for some functions (Grover)
Full Complexity Profile
Get all measures at once:
from boofun.analysis.query_complexity import QueryComplexityProfile
f = bf.majority(5)
profile = QueryComplexityProfile(f)
print(profile.summary())
# Access individual measures
print(f"D(f) = {profile.deterministic_depth}")
print(f"s(f) = {profile.sensitivity}")
print(f"bs(f) = {profile.block_sensitivity}")
print(f"C(f) = {profile.certificate_complexity}")
Decision Tree Algorithms
Advanced algorithms for decision tree analysis.
DP Algorithm
Compute optimal decision tree depth via dynamic programming:
from boofun.analysis.decision_trees import decision_tree_depth_dp
f = bf.tribes(2, 4) # 2 tribes of 4
depth = decision_tree_depth_dp(f)
print(f"D(TRIBES) = {depth}")
Tree Enumeration
Count the number of optimal decision trees:
from boofun.analysis.decision_trees import count_decision_trees
f = bf.majority(3)
count = count_decision_trees(f)
print(f"Number of optimal trees for MAJ_3: {count}")
Randomized Complexity
Compute randomized decision tree complexity:
from boofun.analysis.decision_trees import compute_randomized_complexity
f = bf.OR(4)
R_f = compute_randomized_complexity(f)
print(f"R(OR_4) = {R_f:.2f}")
See Also
Spectral Analysis Guide - Fourier analysis and influences
Hypercontractivity Guide - Advanced influence bounds
Aaronson, “Algorithms for Boolean Function Query Measures” (2000)
Buhrman & de Wolf, “Complexity Measures and Decision Tree Complexity” (2002)
Huang, “Induced subgraphs of hypercubes and a proof of the Sensitivity Conjecture” (2019)