summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarius Peter <dev@marius-peter.com>2025-12-13 22:38:24 +0100
committerMarius Peter <dev@marius-peter.com>2025-12-13 22:38:24 +0100
commit7c9ea5c931f684c4d560ef3671691d89269a7141 (patch)
treea3b3e4473727cbf0b9cedb1bd71ff0f7370ebbc8
parentae1a5e0eceefcb8af1600bca39a2209cabad7198 (diff)
Fix NNLS tests.
-rw-r--r--services/nnls.rkt190
1 files changed, 95 insertions, 95 deletions
diff --git a/services/nnls.rkt b/services/nnls.rkt
index b0902f9..4821b7d 100644
--- a/services/nnls.rkt
+++ b/services/nnls.rkt
@@ -189,131 +189,131 @@
"../db/conn.rkt"
"../db/migrations.rkt")
- (run-tests (test-suite "NNLS"
- #:before (λ ()
- (connect! #:path 'memory)
- (migrate-all!)
- (create-nutrient! "Nitrogen" "Azote" "N")
- (create-nutrient! "Phosphorus" "Phosphore" "P")
- (create-nutrient! "Potassium" "Potassium" "K"))
- #:after (λ () (disconnect!))
+ (run-tests
+ (test-suite "NNLS"
+ #:before (λ ()
+ (connect! #:path 'memory)
+ (migrate-all!)
+ (create-nutrient! "Nitrogen" "Azote" "N")
+ (create-nutrient! "Phosphorus" "Phosphore" "P")
+ (create-nutrient! "Potassium" "Potassium" "K"))
+ #:after (λ () (disconnect!))
- (test-case "Build fertilizer product matrix"
- (define n (get-nutrient #:name "Nitrogen"))
- (define p (get-nutrient #:name "Phosphorus"))
+ (test-case "Build fertilizer product matrix"
+ (define n (get-nutrient #:name "Nitrogen"))
+ (define p (get-nutrient #:name "Phosphorus"))
- (define nutrients (list n p))
+ (define nutrients (list n p))
- (define f1 (create-fertilizer-product! "F1" "F1" (hash n 10 p 20)))
- (define f2 (create-fertilizer-product! "F2" "F2" (hash n 30 p 5)))
- (define fertilizers (list f1 f2))
+ (define f1 (create-fertilizer-product! "F1" "F1" (hash n 10 p 20)))
+ (define f2 (create-fertilizer-product! "F2" "F2" (hash n 30 p 5)))
+ (define fertilizers (list f1 f2))
- (define matrix (get-fertilizer-product-matrix nutrients fertilizers))
+ (define matrix (get-fertilizer-product-matrix nutrients fertilizers))
- (check-= (matrix-ref matrix 0 0) 10 0 "N1 in F1")
- (check-= (matrix-ref matrix 0 1) 30 0 "N1 in F2")
- (check-= (matrix-ref matrix 1 0) 20 0 "N2 in F1")
- (check-= (matrix-ref matrix 1 1) 5 0 "N2 in F2"))
+ (check-= (matrix-ref matrix 0 0) 10 0 "N1 in F1")
+ (check-= (matrix-ref matrix 0 1) 30 0 "N1 in F2")
+ (check-= (matrix-ref matrix 1 0) 20 0 "N2 in F1")
+ (check-= (matrix-ref matrix 1 1) 5 0 "N2 in F2"))
- (test-case "Single nutrient, single fertilizer"
- (define A (matrix [[2]]))
- (define y (col-matrix [10]))
- (define ε 1e-6)
+ (test-case "Single nutrient, single fertilizer"
+ (define A (matrix [[2]]))
+ (define y (col-matrix [10]))
+ (define ε 1e-6)
- (define result (lawson-hanson-1974 A y ε))
+ (define result (lawson-hanson-1974 A y ε))
- (check-= (matrix-ref result 0 0) 5.0 ε "Should give x = 5 since 2*5 = 10"))
+ (check-= (matrix-ref result 0 0) 5.0 ε "Should give x = 5 since 2*5 = 10"))
- (test-case "Two variables, known solution"
- (define A (matrix [[1 0] [0 1]]))
- (define y (col-matrix [3 4]))
- (define ε 1e-6)
+ (test-case "Two variables, known solution"
+ (define A (matrix [[1 0] [0 1]]))
+ (define y (col-matrix [3 4]))
+ (define ε 1e-6)
- (define result (lawson-hanson-1974 A y ε))
+ (define result (lawson-hanson-1974 A y ε))
- (check-= (matrix-ref result 0 0) 3.0 ε "x1 should be 3")
- (check-= (matrix-ref result 1 0) 4.0 ε "x2 should be 4"))
+ (check-= (matrix-ref result 0 0) 3.0 ε "x1 should be 3")
+ (check-= (matrix-ref result 1 0) 4.0 ε "x2 should be 4"))
- (test-case "Overdetermined system"
- (define A (matrix [[1 1] [2 1] [1 2]]))
- (define y (col-matrix [3 5 5]))
- (define ε 1e-4)
+ (test-case "Overdetermined system"
+ (define A (matrix [[1 1] [2 1] [1 2]]))
+ (define y (col-matrix [3 5 5]))
+ (define ε 1e-4)
- (define result (lawson-hanson-1974 A y ε))
+ (define result (lawson-hanson-1974 A y ε))
- ;; Solution should be approximately [1.636, 1.636] (least squares fit)
- (check-= (matrix-ref result 0 0) 1.636 0.01 "x1 approximately 1.636")
- (check-= (matrix-ref result 1 0) 1.636 0.01 "x2 approximately 1.636"))
+ ;; Solution should be approximately [1.636, 1.636] (least squares fit)
+ (check-= (matrix-ref result 0 0) 1.636 0.01 "x1 approximately 1.636")
+ (check-= (matrix-ref result 1 0) 1.636 0.01 "x2 approximately 1.636"))
- (test-case "Non-negativity enforcement"
- (define A (matrix [[1 -1] [1 1]]))
- (define y (col-matrix [1 3]))
- (define ε 1e-6)
+ (test-case "Non-negativity enforcement"
+ (define A (matrix [[1 -1] [1 1]]))
+ (define y (col-matrix [1 3]))
+ (define ε 1e-6)
- (define result (lawson-hanson-1974 A y ε))
+ (define result (lawson-hanson-1974 A y ε))
- ;; All results should be non-negative
- (check-true (>= (matrix-ref result 0 0) 0) "x1 should be non-negative")
- (check-true (>= (matrix-ref result 1 0) 0) "x2 should be non-negative"))
+ ;; All results should be non-negative
+ (check-true (>= (matrix-ref result 0 0) 0) "x1 should be non-negative")
+ (check-true (>= (matrix-ref result 1 0) 0) "x2 should be non-negative"))
- (test-case "Zero target"
- (define A (matrix [[1 2] [3 4]]))
- (define y (col-matrix [0 0]))
- (define ε 1e-6)
+ (test-case "Zero target"
+ (define A (matrix [[1 2] [3 4]]))
+ (define y (col-matrix [0 0]))
+ (define ε 1e-6)
- (define result (lawson-hanson-1974 A y ε))
+ (define result (lawson-hanson-1974 A y ε))
- (check-= (matrix-ref result 0 0) 0.0 ε "x1 should be 0")
- (check-= (matrix-ref result 1 0) 0.0 ε "x2 should be 0"))
+ (check-= (matrix-ref result 0 0) 0.0 ε "x1 should be 0")
+ (check-= (matrix-ref result 1 0) 0.0 ε "x2 should be 0"))
- (test-case "Ferti recipe"
- (define test-date "2025-01-01")
- (define n (get-nutrient #:name "Nitrogen"))
- (define p (get-nutrient #:name "Phosphorus"))
- (define k (get-nutrient #:name "Potassium"))
+ (test-case "Ferti recipe"
+ (define test-date "2025-01-01")
+ (define n (get-nutrient #:name "Nitrogen"))
+ (define p (get-nutrient #:name "Phosphorus"))
+ (define k (get-nutrient #:name "Potassium"))
- (create-nutrient-measurement! test-date (hash n 0 p 0))
- (define test-crop-requirement
- (create-crop-requirement! "Test requirement" (hash n 100 p 50)))
- (create-crop-rotation! test-date (hash test-crop-requirement 100))
+ (create-nutrient-measurement! (nutrient-measurement #f test-date (hash n 0 p 0)))
+ (define test-crop-requirement (create-crop-requirement! "Test requirement" (hash n 100 p 50)))
+ (create-crop-rotation! test-date (hash test-crop-requirement 100))
- (create-fertilizer-product! "Nitrogen" "King Nitrogen" (hash n 100))
- (create-fertilizer-product! "Phosphorus" "Phosphorescent Baboon" (hash n 10 p 100))
- (create-fertilizer-product! "Diluted phosphorus" "John's Phosphorus" (hash n 3 p 30))
+ (create-fertilizer-product! "Nitrogen" "King Nitrogen" (hash n 100))
+ (create-fertilizer-product! "Phosphorus" "Phosphorescent Baboon" (hash n 10 p 100))
+ (create-fertilizer-product! "Diluted phosphorus" "John's Phosphorus" (hash n 3 p 30))
- (define recipe (find-ferti-recipe test-date))
+ (define recipe (find-ferti-recipe test-date))
- (check-equal? (hash-count recipe) 5 "Should have 5 fertilizer products")
+ (check-equal? (hash-count recipe) 5 "Should have 5 fertilizer products")
- (for ([(fertilizer quantity) (in-hash recipe)])
- (check-true (>= quantity 0) "Fertilizer quantity should be non-negative")))
+ (for ([(fertilizer quantity) (in-hash recipe)])
+ (check-true (>= quantity 0) "Fertilizer quantity should be non-negative")))
- (test-case "Recipe calculation with real-world scenario"
- (define test-date "2025-01-02")
- (define n (get-nutrient #:name "Nitrogen"))
- (define p (get-nutrient #:name "Phosphorus"))
- (define k (get-nutrient #:name "Potassium"))
+ (test-case "Recipe calculation with real-world scenario"
+ (define test-date "2025-01-02")
+ (define n (get-nutrient #:name "Nitrogen"))
+ (define p (get-nutrient #:name "Phosphorus"))
+ (define k (get-nutrient #:name "Potassium"))
- ;; Current levels
- (create-nutrient-measurement! test-date (hash n 50 p 10 k 100))
+ ;; Current levels
+ (create-nutrient-measurement! (nutrient-measurement #f test-date (hash n 50 p 10 k 100)))
- ;; Target levels
- (define test-crop-requirement
- (create-crop-requirement! "Test requirement 2" (hash n 150 p 30 k 200)))
- (create-crop-rotation! test-date (hash test-crop-requirement 100))
+ ;; Target levels
+ (define test-crop-requirement
+ (create-crop-requirement! "Test requirement 2" (hash n 150 p 30 k 200)))
+ (create-crop-rotation! test-date (hash test-crop-requirement 100))
- ;; Available fertilizer products
- (create-fertilizer-product! "" "Balanced" (hash n 100 p 100 k 100))
- (create-fertilizer-product! "Nitrogen blend" "High-N" (hash n 200 p 50 k 50))
- (create-fertilizer-product! "Phosphorus blend" "High-P" (hash n 50 p 200 k 50))
- (create-fertilizer-product! "Potassium blend" "High-K" (hash n 50 p 50 k 200))
+ ;; Available fertilizer products
+ (create-fertilizer-product! "" "Balanced" (hash n 100 p 100 k 100))
+ (create-fertilizer-product! "Nitrogen blend" "High-N" (hash n 200 p 50 k 50))
+ (create-fertilizer-product! "Phosphorus blend" "High-P" (hash n 50 p 200 k 50))
+ (create-fertilizer-product! "Potassium blend" "High-K" (hash n 50 p 50 k 200))
- (define recipe (find-ferti-recipe test-date))
+ (define recipe (find-ferti-recipe test-date))
- (check-equal? (hash-count recipe) 9 "Recipe should have 9 fertilizers")
+ (check-equal? (hash-count recipe) 9 "Recipe should have 9 fertilizers")
- ;; Verify solution is non-negative
- (for ([(fertilizer quantity) (in-hash recipe)])
- (check-true (>= quantity 0)
- (format "~a quantity must be non-negative"
- (fertilizer-product-name fertilizer))))))))
+ ;; Verify solution is non-negative
+ (for ([(fertilizer quantity) (in-hash recipe)])
+ (check-true (>= quantity 0)
+ (format "~a quantity must be non-negative"
+ (fertilizer-product-name fertilizer))))))))
Copyright 2019--2026 Marius PETER