problemreductions/models/misc/
cosine_product_integration.rs1use crate::registry::{FieldInfo, ProblemSchemaEntry};
13use crate::traits::Problem;
14use serde::{Deserialize, Serialize};
15
16inventory::submit! {
17 ProblemSchemaEntry {
18 name: "CosineProductIntegration",
19 display_name: "Cosine Product Integration",
20 aliases: &[],
21 dimensions: &[],
22 module_path: module_path!(),
23 description: "Decide whether a balanced sign assignment exists for a sequence of integer frequencies",
24 fields: &[
25 FieldInfo {
26 name: "coefficients",
27 type_name: "Vec<i64>",
28 description: "Integer cosine frequencies",
29 },
30 ],
31 }
32}
33
34#[derive(Debug, Clone, Serialize, Deserialize)]
57pub struct CosineProductIntegration {
58 coefficients: Vec<i64>,
59}
60
61impl CosineProductIntegration {
62 pub fn new(coefficients: Vec<i64>) -> Self {
68 assert!(
69 !coefficients.is_empty(),
70 "CosineProductIntegration requires at least one coefficient"
71 );
72 Self { coefficients }
73 }
74
75 pub fn coefficients(&self) -> &[i64] {
77 &self.coefficients
78 }
79
80 pub fn num_coefficients(&self) -> usize {
82 self.coefficients.len()
83 }
84}
85
86impl Problem for CosineProductIntegration {
87 const NAME: &'static str = "CosineProductIntegration";
88 type Value = crate::types::Or;
89
90 fn variant() -> Vec<(&'static str, &'static str)> {
91 crate::variant_params![]
92 }
93
94 fn dims(&self) -> Vec<usize> {
95 vec![2; self.num_coefficients()]
96 }
97
98 fn evaluate(&self, config: &[usize]) -> crate::types::Or {
99 crate::types::Or({
100 if config.len() != self.num_coefficients() {
101 return crate::types::Or(false);
102 }
103 if config.iter().any(|&v| v >= 2) {
104 return crate::types::Or(false);
105 }
106 let signed_sum: i128 = self
107 .coefficients
108 .iter()
109 .zip(config.iter())
110 .map(|(&a, &bit)| {
111 let val = a as i128;
112 if bit == 0 {
113 val
114 } else {
115 -val
116 }
117 })
118 .sum();
119 signed_sum == 0
120 })
121 }
122}
123
124crate::declare_variants! {
125 default CosineProductIntegration => "2^(num_coefficients / 2)",
126}
127
128#[cfg(feature = "example-db")]
129pub(crate) fn canonical_model_example_specs() -> Vec<crate::example_db::specs::ModelExampleSpec> {
130 vec![crate::example_db::specs::ModelExampleSpec {
131 id: "cosine_product_integration",
132 instance: Box::new(CosineProductIntegration::new(vec![2, 3, 5])),
133 optimal_config: vec![0, 0, 1],
134 optimal_value: serde_json::json!(true),
135 }]
136}
137
138#[cfg(test)]
139#[path = "../../unit_tests/models/misc/cosine_product_integration.rs"]
140mod tests;