Function: math-covariance

math-covariance is a byte-compiled function defined in calc-stat.el.gz.

Signature

(math-covariance VEC1 VEC2 POP MODE)

Source Code

;; Defined in /usr/src/emacs/lisp/calc/calc-stat.el.gz
(defun math-covariance (vec1 vec2 pop mode)
  (or (car vec2) (= mode 0)
      (progn
	(if (and (eq (car-safe (car vec1)) 'var)
		 (eq (car-safe (calc-var-value (nth 2 (car vec1)))) 'vec))
	    (setq vec1 (symbol-value (nth 2 (car vec1))))
	  (setq vec1 (car vec1)))
	(or (math-matrixp vec1) (math-dimension-error))
	(or (= (length (nth 1 vec1)) 3) (math-dimension-error))
	(setq vec2 (list (math-mat-col vec1 2))
	      vec1 (list (math-mat-col vec1 1)))))
  (math-with-extra-prec 2
    (let* ((split1 (math-split-sdev-vec (math-flatten-many-vecs vec1) nil))
	   (means1 (car split1))
	   (wts1 (nth 1 split1))
	   split2 means2 (wts2 nil)
	   (sqrwts nil)
	   suminvsqrwts
	   (len (1- (length means1))))
      (if (< len (if pop 1 2))
	  (math-reject-arg nil (if pop
				   "*Must be at least 1 argument"
				 "*Must be at least 2 arguments")))
      (if (or wts1 wts2)
	  (setq sqrwts (math-add
			(if wts1
			    (calcFunc-map '(var mul var-mul) wts1 wts1)
			  0)
			(if wts2
			    (calcFunc-map '(var mul var-mul) wts2 wts2)
			  0))
		suminvsqrwts (calcFunc-reduce
			      '(var add var-add)
			      (calcFunc-map '(var div var-div) 1 sqrwts))))
      (or (= mode 0)
	  (progn
	    (setq split2 (math-split-sdev-vec (math-flatten-many-vecs vec2)
					      nil)
		  means2 (car split2)
		  wts2 (nth 2 split1))
	    (or (= len (1- (length means2))) (math-dimension-error))))
      (let* ((diff1 (calcFunc-map
		     '(var add var-add)
		     means1
		     (if sqrwts
			 (math-div (calcFunc-reduce
				    '(var add var-add)
				    (calcFunc-map '(var div var-div)
						  means1 sqrwts))
				   (math-neg suminvsqrwts))
		       (math-div (calcFunc-reducer '(var add var-add) means1)
				 (- len)))))
	     (diff2 (if (= mode 0)
			diff1
		      (calcFunc-map
		       '(var add var-add)
		       means2
		       (if sqrwts
			   (math-div (calcFunc-reduce
				      '(var add var-add)
				      (calcFunc-map '(var div var-div)
						    means2 sqrwts))
				     (math-neg suminvsqrwts))
			 (math-div (calcFunc-reducer '(var add var-add) means2)
				   (- len))))))
	     (covar (calcFunc-map '(var mul var-mul) diff1 diff2)))
	(if sqrwts
	    (setq covar (calcFunc-map '(var div var-div) covar sqrwts)))
	(math-div
	 (calcFunc-reducer '(var add var-add) covar)
	 (if (= mode 2)
	     (let ((var1 (calcFunc-map '(var mul var-mul) diff1 diff1))
		   (var2 (calcFunc-map '(var mul var-mul) diff2 diff2)))
	       (if sqrwts
		   (setq var1 (calcFunc-map '(var div var-div) var1 sqrwts)
			 var2 (calcFunc-map '(var div var-div) var2 sqrwts)))
	       (math-sqrt
		(math-mul (calcFunc-reducer '(var add var-add) var1)
			  (calcFunc-reducer '(var add var-add) var2))))
	   (if sqrwts
	       (if pop
		   suminvsqrwts
		 (math-div (math-mul suminvsqrwts (1- len)) len))
	     (if pop len (1- len)))))))))