#[cfg(test)] mod binary_ops { use dendritic_ndarray::ndarray::NDArray; use dendritic_ndarray::ops::*; #[test] fn test_add_ndarray() { /* set 2d array */ let x: NDArray = NDArray::array(vec![2, 3], vec![0.0,0.0,1.0,1.0,2.0,2.0]).unwrap(); let y: NDArray = NDArray::array(vec![2, 3], vec![0.0,0.0,1.0,1.0,2.0,2.0]).unwrap(); let result : NDArray = x.add(y).unwrap(); let expected_vals = vec![0.0,0.0,2.0,2.0,4.0,4.0]; let expected_shape = vec![2, 3]; assert_eq!(result.rank(), 2); assert_eq!(result.values(), &expected_vals); assert_eq!(result.values().len(), 6); assert_eq!(result.shape().values(), expected_shape); /* failure case */ let z: NDArray = NDArray::array(vec![2, 3], vec![0.0,0.0,1.0,1.0,2.0,2.0]).unwrap(); let o: NDArray = NDArray::array(vec![2, 2], vec![0.0,0.0,1.0,1.0]).unwrap(); let result: Result, String> = o.add(z); // catch the error match result { Ok(_) => println!("This should fail"), Err(err) => { assert_eq!(err, "Add: Size mismatch for arrays"); } } let a: NDArray = NDArray::array(vec![2, 2, 2], vec![0.0,0.0,1.0,1.0,2.0,2.0,3.0,3.0]).unwrap(); let b: NDArray = NDArray::array(vec![2, 4], vec![0.0,0.0,1.0,1.0,2.0,2.0,3.0,3.0]).unwrap(); let rank_mismatch: Result, String> = a.add(b); match rank_mismatch { Ok(_) => println!("Fail due to rank mismatch"), Err(err) => { assert_eq!(err, "Add: Rank Mismatch"); } } } #[test] fn test_subtract_ndarray() { /* set 2d array */ let x: NDArray = NDArray::array(vec![2, 3], vec![0.0,0.0,1.0,1.0,2.0,2.0]).unwrap(); let y: NDArray = NDArray::array(vec![2, 3], vec![0.0,0.0,1.0,1.0,2.0,2.0]).unwrap(); let result : NDArray = x.subtract(y).unwrap(); let expected_vals = vec![0.0,0.0,0.0,0.0,0.0,0.0]; let expected_shape = vec![2, 3]; assert_eq!(result.rank(), 2); assert_eq!(result.values(), &expected_vals); assert_eq!(result.values().len(), 6); assert_eq!(result.shape().values(), expected_shape); /* failure case */ let z: NDArray = NDArray::array(vec![2, 3], vec![0.0,0.0,1.0,1.0,2.0,2.0]).unwrap(); let o: NDArray = NDArray::array(vec![2, 2], vec![0.0,0.0,1.0,1.0]).unwrap(); let result: Result, String> = o.subtract(z); // catch the error match result { Ok(_) => println!("This should fail"), Err(err) => { assert_eq!(err, "Subtract: Size mismatch for arrays"); } } let a: NDArray = NDArray::array(vec![2, 2, 2], vec![0.0,0.0,1.0,1.0,2.0,2.0,3.0,3.0]).unwrap(); let b: NDArray = NDArray::array(vec![2, 4], vec![0.0,0.0,1.0,1.0,2.0,2.0,3.0,3.0]).unwrap(); let rank_mismatch: Result, String> = a.subtract(b); match rank_mismatch { Ok(_) => println!("Fail due to rank mismatch"), Err(err) => { assert_eq!(err, "Subtract: Rank Mismatch"); } } } #[test] fn test_dot_ndarray() { /* set 2d array */ let a: NDArray = NDArray::array(vec![4, 3], vec![0.0,0.0,1.0,0.0,1.0,2.0,1.0,1.0,3.0,0.0,0.0,4.0]).unwrap(); let b: NDArray = NDArray::array(vec![3, 3], vec![1.0,1.0,1.0,2.0,2.0,2.0,3.0,3.0,3.0]).unwrap(); let result : NDArray = a.dot(b).unwrap(); let expected_vals = vec![3.0,3.0,3.0,8.0,8.0,8.0,12.0,12.0,12.0,12.0,12.0,12.0]; let expected_shape = vec![4, 3]; assert_eq!(result.values(), &expected_vals); assert_eq!(result.shape().values(), expected_shape); assert_eq!(result.values().len(), 12); assert_eq!(result.rank(), 2); /* set 2d array */ let x: NDArray = NDArray::array(vec![4, 2], vec![0.0,0.0,0.0,1.0,1.0,1.0,0.0,0.0]).unwrap(); let y: NDArray = NDArray::array(vec![2, 3], vec![1.0,1.0,1.0,2.0,2.0,2.0]).unwrap(); let result : NDArray = x.dot(y).unwrap(); let expected_vals = vec![0.0,0.0,0.0,2.0,2.0,2.0,3.0,3.0,3.0, 0.0, 0.0, 0.0]; let expected_shape = vec![4, 3]; assert_eq!(result.values(), &expected_vals); assert_eq!(result.shape().values(), expected_shape); assert_eq!(result.values().len(), 12); assert_eq!(result.rank(), 2); /* failure case */ let z: NDArray = NDArray::array(vec![2,2,2], vec![0.0,0.0,1.0,1.0,2.0,2.0,3.0,3.0]).unwrap(); let o: NDArray = NDArray::array(vec![2, 2], vec![0.0,0.0,1.0,1.0]).unwrap(); let result: Result, String> = o.dot(z); // catch the error match result { Ok(_) => println!("This should fail"), Err(err) => { assert_eq!(err, "Dot: Rank Mismatch"); } } let m: NDArray = NDArray::array(vec![2, 4], vec![0.0,0.0,0.0,1.0,1.0,1.0,0.0,0.0]).unwrap(); let p: NDArray = NDArray::array(vec![2, 3], vec![1.0,1.0,1.0,2.0,2.0,2.0]).unwrap(); let rank_mismatch: Result, String> = m.dot(p); match rank_mismatch { Ok(_) => println!("Fail due to rank mismatch"), Err(err) => { assert_eq!(err, "Dot: Rows must equal columns"); } } let a_path = "data/ndarray/X_T"; let b_path = "data/ndarray/Y_P"; let a = NDArray::load(a_path).unwrap(); let b = NDArray::load(b_path).unwrap(); let dot_result = a.dot(b).unwrap(); let expected = vec![55.0, 110.0, 165.0, 55.0, 110.0, 165.0, 55.0, 110.0, 165.0]; assert_eq!(dot_result.shape().values(), vec![3,3]); assert_eq!(dot_result.values(), &expected); } #[test] fn test_scale_add_ndarray() { /* set 2d array */ let x: NDArray = NDArray::array(vec![2, 3], vec![0.0,0.0,1.0,1.0,2.0,2.0]).unwrap(); let y: NDArray = NDArray::array(vec![1, 3], vec![1.0,1.0,1.0]).unwrap(); let result : NDArray = x.scale_add(y).unwrap(); let expected_vals = vec![1.0,1.0,2.0,2.0,3.0,3.0]; let expected_shape = vec![2, 3]; assert_eq!(result.rank(), 2); assert_eq!(result.values(), &expected_vals); assert_eq!(result.values().len(), 6); assert_eq!(result.shape().values(), expected_shape); /* set 2d array */ let a = NDArray::array(vec![4, 3], vec![0.0,0.0,0.0,2.0,2.0,2.0,2.0,2.0,2.0,4.0,4.0,4.0]).unwrap(); let b = NDArray::array(vec![1, 3], vec![1.0,1.0,1.0]).unwrap(); let result_two : NDArray = a.scale_add(b).unwrap(); let expected_vals_two = vec![1.0,1.0,1.0,3.0,3.0,3.0,3.0,3.0,3.0,5.0,5.0,5.0]; let expected_shape_two = vec![4, 3]; assert_eq!(result_two.rank(), 2); assert_eq!(result_two.values(), &expected_vals_two); assert_eq!(result_two.values().len(), 12); assert_eq!(result_two.shape().values(), expected_shape_two); /* failure case */ let o = NDArray::array(vec![4, 3], vec![0.0,0.0,0.0,2.0,2.0,2.0,2.0,2.0,2.0,4.0,4.0,4.0]).unwrap(); let n = NDArray::array(vec![2, 2], vec![1.0,1.0,1.0,1.0]).unwrap(); let result_bad: Result, String> = o.scale_add(n); match result_bad { Ok(_) => println!("Fail due to dimension mismatch"), Err(err) => { assert_eq!(err, "Scale add must have a vector dimension (1, N)"); } } } #[test] fn test_save_load_ndarray() { /* for logistic data */ let inputs_logistic = vec![ 1.0, 2.0, 3.0, -1.0, 2.0, 1.0, 2.0, -2.0, 0.0, -1.0, -1.0, 2.0, 1.0, 1.0, 0.0, -2.0, 2.0, 1.0, 1.0, -1.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, -1.0 ]; /* set 2d array */ let log_x: NDArray = NDArray::array(vec![10, 3], inputs_logistic.clone()).unwrap(); let _ = log_x.save("data/ndarray/saved"); /* load from saved ndarray */ let loaded: NDArray = NDArray::load("data/ndarray/saved").unwrap(); let shape = loaded.shape(); let rank = loaded.rank(); let values = loaded.values(); /* expected attributes */ assert_eq!(shape.values(), vec![10, 3]); assert_eq!(values.len(), 30); assert_eq!(values, &inputs_logistic); assert_eq!(rank, 2); } }