cosmo-test.el 7.67 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
;;; test_cosmo.el --- Unit test for cosmo.el    -*- lexical-binding: t; -*-

;; Copyright (C) 2017 Francesco Montanari
;;
;; Author: Francesco Montanari <fmnt@fmnt.info>
;; Created: 22 April 2017
;; Version: 0.1
;; Keywords: tools
;; Homepage: https://gitlab.com/montanari/cosmo-el
;;
;; This file is not part of GNU Emacs.
;;
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:

;; This package provides an unit test for cosmo.el, a cosmological
;; calculator.

31 32 33 34
;;; Todo:

;; - Refactor tests, now they are too cumbersome and repetitive.

35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
;;; Code:


(require 'cl)
(require 'cosmo)

;;; Test utilities.

(defun cosmo-and-reduce (seq)
  "Reduce sequence SEQ by applying the `and` special form."
  (reduce #'(lambda (x y) (and x y)) seq))

(defun cosmo-almost-eq (num1 num2 &optional reltol)
  ;; TODO: Decide how to handle the case in which the arguments are
  ;; zero; for instance, both a relative and absolute tolerance can
  ;; be specified and the largest one is considered.
  "Return t if the two numbers differ by less than ABSTOL."
  (or reltol (setq reltol 1e-8))       ; Default relative tolerance
  (> reltol (abs (1- (/ num1 num2)))))

(defun cosmo-test-set-default (H0 omatter olambda orel)
  "Set default test cosmological parameters.
Argument H0 Hubble parameter [Km/s/Mpc].
Argument OMATTER matter density parameter today.
Argument OLAMBDA cosmological constant density parameter.
Argument OREL relativistic density parameter today."
  (puthash "H0 [Km/s/Mpc]" H0 cosmo--params)
  (puthash "omatter" omatter cosmo--params)
  (puthash "olambda" olambda cosmo--params)
  (puthash "orel" orel cosmo--params)
  nil)

(defmacro cosmo-measure-time (&rest body)
  "Measure the time it takes to evaluate BODY."
  `(let ((time (current-time)))
     ,@body
     (message "%.06f seconds" (float-time (time-since time)))))

;;; Tests independent of cosmology.

(defun cosmo-test-string-number-p ()
  "Test string representing numbers."
  (let ((numbers '("1" "+2" "-30" "1.2" "+30.4" "-5.60")))
    (assert
     (cosmo-and-reduce (mapcar #'cosmo--string-number-p numbers)))))

(defun cosmo-test-string-notnumber-p ()
  "Test strings not representing numbers."
  (let ((notnumbers '("a" "+abc" "-30..0" "10.0..2")))
    (assert
     (not (cosmo-and-reduce (mapcar #'cosmo--string-number-p notnumbers))))))

(cosmo-test-string-number-p)
(cosmo-test-string-notnumber-p)

;;; Open cosmology.

(cosmo-test-set-default 70.0 0.31 0.7 8.52444340102e-05)

(defun cosmo-test-efunc ()
  (assert (cosmo-almost-eq (cosmo-efunc 1000.0) 19912.4772226 1e-3)))

(defun cosmo-test-inv-efunc ()
  (assert (cosmo-almost-eq (cosmo-inv-efunc 1000.0) 5.02197686819e-05 1e-3)))

(defun cosmo-test-hubble ()
  (assert (cosmo-almost-eq (cosmo-get-hubble 1000.0) 1393873.40558 1e-3)))

(defun cosmo-test-hubble-distance ()
  (assert (cosmo-almost-eq (cosmo-get-hubble-distance) 4282.7494 1e-3)))

(defun cosmo-test-hubble-time ()
  (assert (cosmo-almost-eq (cosmo-get-hubble-time) 13.9684603096 1e-3)))

(defun cosmo-test-los-comoving-distance ()
  (assert (cosmo-almost-eq
           (cosmo-get-los-comoving-distance 1000.0) 13454.7229832 1e-3)))

(defun cosmo-test-transverse-comoving-distance-open ()
  (assert (cosmo-almost-eq
           (cosmo-get-transverse-comoving-distance 1000.0)
           13232.6210034 1e-3)))

(defun cosmo-test-luminosity-distance ()
  (assert (cosmo-almost-eq
           (cosmo-get-luminosity-distance 1000.0) 13245853.6244 1e-3)))

(defun cosmo-test-angular-diameter-distance ()
  (assert (cosmo-almost-eq
           (cosmo-get-angular-diameter-distance 1000.0) 13.2194016018 1e-3)))

126 127 128 129
(defun cosmo-test-comoving-volume ()
  (assert (cosmo-almost-eq
           (cosmo-get-comoving-volume 1000.0) 1.00014515316e+13 3e-3)))

130 131 132 133 134 135 136 137
(defun cosmo-test-lookback-time ()
  (assert (cosmo-almost-eq
           (cosmo-get-lookback-time 1000.0) 13.3803575903 4e-3)))

(defun cosmo-test-age ()
  (assert (cosmo-almost-eq
           (cosmo-get-age 0.0) 13.3807781911 3e-3)))

138 139 140 141 142 143 144 145 146
(cosmo-test-efunc)
(cosmo-test-inv-efunc)
(cosmo-test-hubble)
(cosmo-test-hubble-distance)
(cosmo-test-hubble-time)
(cosmo-test-los-comoving-distance)
(cosmo-test-transverse-comoving-distance-open)
(cosmo-test-luminosity-distance)
(cosmo-test-angular-diameter-distance)
147
(cosmo-test-comoving-volume)
148 149
(cosmo-test-lookback-time)
(cosmo-test-age)
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165

;;; Close cosmology.

;; If the transverse comoving distance passes this test, and the other
;; functions already passed the open cosmology test, then they are
;; also consistent with a close cosmology. This is because different
;; curvature were coded in the transverse distance, and other
;; distances are defined as functions of this one.

(cosmo-test-set-default 70.0 0.27 0.7 8.52444340102e-05)

(defun cosmo-test-transverse-comoving-distance-close ()
  (assert (cosmo-almost-eq
           (cosmo-get-transverse-comoving-distance 1000.0)
           14832.933576 1e-3)))

166 167 168 169
(defun cosmo-test-comoving-volume ()
  (assert (cosmo-almost-eq
           (cosmo-get-comoving-volume 1000.0) 1.24288502093e+13 3e-3)))

170 171 172 173 174 175 176 177
(defun cosmo-test-lookback-time ()
  (assert (cosmo-almost-eq
           (cosmo-get-lookback-time 1000.0) 13.7206066124 4e-3)))

(defun cosmo-test-age ()
  (assert (cosmo-almost-eq
           (cosmo-get-age 0.0) 13.7210465251 3e-3)))

178
(cosmo-test-transverse-comoving-distance-close)
179
(cosmo-test-comoving-volume)
180 181
(cosmo-test-lookback-time)
(cosmo-test-age)
182 183 184 185 186 187 188 189 190 191 192 193 194

;;; Flat cosmology.

;; If the transverse comoving distance passes this test, and the other
;; functions already passed the open cosmology test, then they are
;; also consistent with a close cosmology. This is because different
;; curvature were coded in the transverse distance, and other
;; distances are defined as functions of this one.

(cosmo-test-set-default 70.0 0.3 0.7 0.0)

(defun cosmo-test-transverse-comoving-distance-flat ()
  (assert (cosmo-almost-eq
195 196 197 198 199
           (cosmo-get-transverse-comoving-distance 1000.0) 13660.5292969 1e-3)))

(defun cosmo-test-comoving-volume ()
  (assert (cosmo-almost-eq
           (cosmo-get-comoving-volume 1000.0) 1.06780313213e+13 3e-3)))
200

201 202 203 204 205 206 207 208
(defun cosmo-test-lookback-time ()
  (assert (cosmo-almost-eq
           (cosmo-get-lookback-time 1000.0) 13.4664471061 4e-3)))

(defun cosmo-test-age ()
  (assert (cosmo-almost-eq
           (cosmo-get-age 0.0) 13.466983947 3e-3)))

209
(cosmo-test-transverse-comoving-distance-flat)
210
(cosmo-test-comoving-volume)
211 212
(cosmo-test-lookback-time)
(cosmo-test-age)
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232

;;; Benchmarks

;; Benchmarks: numerical integral.
;; (cosmo-test-set-default 70.0 0.31 0.7 8.52444340102e-05) ; Open
;; (cosmo-measure-time (cosmo-get-angular-diameter-distance 0.1))
;; (cosmo-measure-time (cosmo-get-angular-diameter-distance 1000.0))

;; (cosmo-test-set-default 70.0 0.27 0.7 8.52444340102e-05) ; Close
;; (cosmo-measure-time (cosmo-get-angular-diameter-distance 0.1))
;; (cosmo-measure-time (cosmo-get-angular-diameter-distance 1000.0))

;; (cosmo-test-set-default 70.0 0.3 0.7 0.0) ; Flat
;; (cosmo-measure-time (cosmo-get-angular-diameter-distance 0.1))
;; (cosmo-measure-time (cosmo-get-angular-diameter-distance 1000.0))

;; Benchmarks: hyperbolic sine.
;; (cosmo-measure-time (cosmo-sinh 0.5))
;; (cosmo-measure-time (calc-eval "sinh(0.5)"))
;; (cosmo-measure-time (calcFunc-sinh '(float 5 -1)))