Skip to content

Commit 1f7b8c1

Browse files
committed
wip
1 parent 6924733 commit 1f7b8c1

15 files changed

Lines changed: 59 additions & 1085 deletions

File tree

src/benchmarks/evaluation.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1083,4 +1083,4 @@ pub fn new_initial_point(
10831083
*xi += (random_delta * 2.0 - 1.0) * noise; // Random perturbation
10841084
}
10851085
Ok(x)
1086-
}
1086+
}

src/benchmarks/unified_tests.rs

Lines changed: 0 additions & 219 deletions
Original file line numberDiff line numberDiff line change
@@ -1390,9 +1390,6 @@ pub fn generate_test_report(results: &[ProblemTestResults]) -> String {
13901390
mod tests {
13911391
use super::*;
13921392
use crate::benchmarks::analytic_functions::*;
1393-
use crate::benchmarks::ml_problems::*;
1394-
use crate::benchmarks::mnist::*;
1395-
use crate::benchmarks::mnist_onednn::*;
13961393
use rand::{rngs::StdRng, SeedableRng};
13971394

13981395
#[test]
@@ -1669,163 +1666,6 @@ mod tests {
16691666
);
16701667
}
16711668
#[test]
1672-
fn test_ml_problems_unified() {
1673-
let mut rng = StdRng::seed_from_u64(42);
1674-
// Generate small synthetic datasets for testing
1675-
let (x_data, y_data) = generate_linear_regression_data(20, 3, &mut rng);
1676-
let (svm_x, svm_y) = generate_svm_data(20, 3, &mut rng);
1677-
let problems: Vec<Box<dyn OptimizationProblem>> = vec![
1678-
Box::new(LinearRegression::new(x_data.clone(), y_data.clone(), 0.01).unwrap()),
1679-
Box::new(
1680-
LogisticRegression::new(
1681-
x_data.clone(),
1682-
y_data
1683-
.iter()
1684-
.map(|&y| if y > 0.0 { 1.0 } else { 0.0 })
1685-
.collect(),
1686-
0.01,
1687-
)
1688-
.unwrap(),
1689-
),
1690-
Box::new(SupportVectorMachine::new(svm_x, svm_y, 1.0).unwrap()),
1691-
Box::new(NeuralNetworkTraining::mlp_classification(vec![3, 5, 2], &mut rng).unwrap()),
1692-
];
1693-
let config = ProblemTestConfig {
1694-
gradient_tolerance: 1e-3, // More lenient for ML problems
1695-
test_points_count: 2, // Fewer test points for speed
1696-
derivative_validation: DerivativeValidationConfig {
1697-
numerical_gradient_tolerance: 1e-3,
1698-
test_directions_count: 2,
1699-
enable_second_order_tests: false,
1700-
enable_robustness_tests: true, // Enable but with lenient settings
1701-
..Default::default()
1702-
},
1703-
..Default::default()
1704-
};
1705-
let results = test_multiple_problems(problems, Some(config));
1706-
let report = generate_test_report(&results);
1707-
println!("{}", report);
1708-
// ML problems should have reasonable success rate
1709-
let valid_count = results.iter().filter(|r| r.is_valid()).count();
1710-
let success_rate = valid_count as f32 / results.len() as f32;
1711-
assert!(
1712-
success_rate >= 0.5,
1713-
"At least 50% of ML problems should pass unified tests. Success rate: {:.1}%",
1714-
success_rate * 100.0
1715-
);
1716-
}
1717-
#[test]
1718-
fn test_mnist_problems_unified() {
1719-
let mut rng = StdRng::seed_from_u64(42);
1720-
// Create small MNIST-like problems for testing
1721-
let x_data = vec![vec![0.5; 784]; 10]; // 10 samples, 784 features
1722-
let mut y_data = vec![vec![0.0; 10]; 10]; // 10 samples, 10 classes
1723-
for (i, label) in y_data.iter_mut().enumerate() {
1724-
label[i % 10] = 1.0; // One-hot encoding
1725-
}
1726-
let problems: Vec<Box<dyn OptimizationProblem>> = vec![
1727-
Box::new(
1728-
MnistNeuralNetwork::new(
1729-
x_data.clone(),
1730-
y_data.clone(),
1731-
&[20],
1732-
Some(5),
1733-
&mut rng,
1734-
None,
1735-
)
1736-
.unwrap(),
1737-
),
1738-
#[cfg(feature = "onednn")]
1739-
Box::new(
1740-
MnistOneDnnNeuralNetwork::new(x_data, y_data, &[20], Some(5), &mut rng, None)
1741-
.unwrap(),
1742-
),
1743-
];
1744-
let config = ProblemTestConfig {
1745-
gradient_tolerance: 1e-2, // Very lenient for neural networks
1746-
test_points_count: 1, // Single test point for speed
1747-
finite_check_tolerance: 1e8, // Allow larger values
1748-
derivative_validation: DerivativeValidationConfig {
1749-
numerical_gradient_tolerance: 1e-2,
1750-
test_directions_count: 1,
1751-
enable_second_order_tests: false,
1752-
enable_directional_tests: false,
1753-
enable_robustness_tests: false,
1754-
..Default::default()
1755-
},
1756-
..Default::default()
1757-
};
1758-
let results = test_multiple_problems(problems, Some(config));
1759-
let report = generate_test_report(&results);
1760-
println!("{}", report);
1761-
// Neural networks are complex, allow some failures
1762-
let valid_count = results.iter().filter(|r| r.is_valid()).count();
1763-
let success_rate = valid_count as f32 / results.len() as f32;
1764-
// At least basic functionality should work
1765-
assert!(
1766-
success_rate >= 0.3,
1767-
"At least 30% of neural network problems should pass basic tests. Success rate: {:.1}%",
1768-
success_rate * 100.0
1769-
);
1770-
}
1771-
#[test]
1772-
fn test_mixed_problem_types() {
1773-
let mut rng = StdRng::seed_from_u64(42);
1774-
// Mix of analytic and ML problems
1775-
let (x_data, y_data) = generate_linear_regression_data(15, 2, &mut rng);
1776-
let problems: Vec<Box<dyn OptimizationProblem>> = vec![
1777-
// Analytic functions
1778-
Box::new(SphereFunction::new(3)),
1779-
Box::new(RosenbrockFunction::new(3)),
1780-
Box::new(BealeFunction::new()),
1781-
// ML problems
1782-
Box::new(LinearRegression::new(x_data.clone(), y_data.clone(), 0.01).unwrap()),
1783-
Box::new(
1784-
LogisticRegression::new(
1785-
x_data,
1786-
y_data
1787-
.iter()
1788-
.map(|&y| if y > 0.0 { 1.0 } else { 0.0 })
1789-
.collect(),
1790-
0.01,
1791-
)
1792-
.unwrap(),
1793-
),
1794-
];
1795-
let results = test_multiple_problems(problems, None);
1796-
let report = generate_test_report(&results);
1797-
println!("{}", report);
1798-
// Check that different problem types are handled consistently
1799-
let analytic_results: Vec<_> = results
1800-
.iter()
1801-
.filter(|r| {
1802-
r.problem_name.contains("Sphere")
1803-
|| r.problem_name.contains("Rosenbrock")
1804-
|| r.problem_name.contains("Beale")
1805-
})
1806-
.collect();
1807-
let ml_results: Vec<_> = results
1808-
.iter()
1809-
.filter(|r| r.problem_name.contains("Regression"))
1810-
.collect();
1811-
// Analytic functions should have high success rate
1812-
let analytic_success = analytic_results.iter().filter(|r| r.is_valid()).count() as f32
1813-
/ analytic_results.len() as f32;
1814-
assert!(
1815-
analytic_success >= 0.9,
1816-
"Analytic functions should have >90% success rate: {:.1}%",
1817-
analytic_success * 100.0
1818-
);
1819-
// ML problems should have reasonable success rate
1820-
let ml_success =
1821-
ml_results.iter().filter(|r| r.is_valid()).count() as f32 / ml_results.len() as f32;
1822-
assert!(
1823-
ml_success >= 0.5,
1824-
"ML problems should have >50% success rate: {:.1}%",
1825-
ml_success * 100.0
1826-
);
1827-
}
1828-
#[test]
18291669
fn test_gradient_consistency_across_problems() {
18301670
let rng = StdRng::seed_from_u64(42);
18311671
let problems: Vec<Box<dyn OptimizationProblem>> = vec![
@@ -1880,65 +1720,6 @@ mod tests {
18801720
);
18811721
}
18821722
}
1883-
#[test]
1884-
fn test_problem_cloning_behavior() {
1885-
let mut rng = StdRng::seed_from_u64(42);
1886-
let (x_data, y_data) = generate_linear_regression_data(10, 2, &mut rng);
1887-
let problems: Vec<Box<dyn OptimizationProblem>> = vec![
1888-
Box::new(SphereFunction::new(3)),
1889-
Box::new(LinearRegression::new(x_data, y_data, 0.01).unwrap()),
1890-
];
1891-
for problem in &problems {
1892-
let cloned = problem.clone_problem();
1893-
// Basic properties should match
1894-
assert_eq!(problem.name(), cloned.name());
1895-
assert_eq!(problem.dimension(), cloned.dimension());
1896-
assert_eq!(problem.optimal_value(), cloned.optimal_value());
1897-
// Function evaluations should match
1898-
let test_point = problem.initial_point();
1899-
let orig_value = problem.evaluate_f64(&test_point).unwrap();
1900-
let clone_value = cloned.evaluate_f64(&test_point).unwrap();
1901-
assert!(
1902-
(orig_value - clone_value).abs() < 1e-12,
1903-
"Cloned problem gives different result: {} vs {} for {}",
1904-
orig_value,
1905-
clone_value,
1906-
problem.name()
1907-
);
1908-
}
1909-
}
1910-
#[test]
1911-
fn test_dimension_consistency() {
1912-
let mut rng = StdRng::seed_from_u64(42);
1913-
let problems: Vec<Box<dyn OptimizationProblem>> = vec![
1914-
Box::new(SphereFunction::new(5)),
1915-
Box::new(RosenbrockFunction::new(4)),
1916-
Box::new(NeuralNetworkTraining::mlp_classification(vec![3, 4, 2], &mut rng).unwrap()),
1917-
];
1918-
for problem in &problems {
1919-
let dimension = problem.dimension();
1920-
let initial_point = problem.initial_point();
1921-
assert_eq!(
1922-
initial_point.len(),
1923-
dimension,
1924-
"Problem {} has dimension mismatch: dimension()={}, initial_point.len()={}",
1925-
problem.name(),
1926-
dimension,
1927-
initial_point.len()
1928-
);
1929-
// Test gradient dimension consistency
1930-
if let Ok(gradient) = problem.gradient_f64(&initial_point) {
1931-
assert_eq!(
1932-
gradient.len(),
1933-
dimension,
1934-
"Problem {} gradient dimension mismatch: expected {}, got {}",
1935-
problem.name(),
1936-
dimension,
1937-
gradient.len()
1938-
);
1939-
}
1940-
}
1941-
}
19421723

19431724
#[test]
19441725
fn test_custom_config() {

src/line_search/bisection.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,8 @@ impl<'a> ProblemEvaluator for LuminalEvaluator<'a> {
159159
.set_tensor(self.params.id, 0, Tensor::new(new_params));
160160
self.cx.execute();
161161
self.num_f_evals += 1;
162-
let loss_val = self.loss
162+
let loss_val = self
163+
.loss
163164
.data()
164165
.as_any()
165166
.downcast_ref::<Vec<f32>>()
@@ -874,4 +875,4 @@ mod tests {
874875
assert_eq!(line_search.config.max_iterations, 20);
875876
}
876877
*/
877-
}
878+
}

src/line_search/line_search.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,4 +253,4 @@ mod tests {
253253
assert_eq!(deserialized.step_size, result.step_size);
254254
assert_eq!(deserialized.num_f_evals, 3);
255255
}
256-
}
256+
}

0 commit comments

Comments
 (0)