<commit_before>(in-package #:lindsey)

(defconstant TOLERANCE 1e-6)
(defconstant ACCURACY 6)

(defclass Polynomial ()
  ((coefs :initarg :coeff :accessor coefs)
   (var :initarg :var :accessor var :initform "t")
   (s :initarg :s :accessor s)))

(defmethod init ((p Polynomial) cfs)
  (setf (coefs p) (copy-seq cfs)))

(defmethod evaluate ((p Polynomial) x)
  (assert (numberp x) nil "Polynomial evaluate: parameter must be a number.")

  (let ((result 0))
    (loop for i across (coefs p)
       do (setf result (cl:+ (cl:* result x) i)))
    result))

(defmethod degree ((p Polynomial))
  (1- (cl:length (coefs p))))

(defmethod getCubicRoots ((p Polynomial))
  (let ((results (make-array 3 :element-type 'float :fill-pointer 0)))
    (when (= 3 (degree p))
      (let* ((c3 (elt (coefs p) 3))
	     (c2 (cl:/ (elt (coefs p) 2) c3))
	     (c1 (cl:/ (elt (coefs p) 1) c3))
	     (c0 (cl:/ (elt (coefs p) 0) c3))
	     (a  (cl:/ (cl:- (cl:* c1 3) (cl:* c2 c2)) 3))
	     (b  (cl:/ (cl:+ (cl:* 2 c2 c2 c2)
			     (cl:- (cl:* 9 c1 c2))
			     (cl:* 27 c0)) 27))
	     (offset  (cl:/ c2 3))
	     (discrim (cl:+ (cl:/ (cl:* b b) 4)
			    (cl:/ (cl:* a a a) 27)))
	     (halfB (cl:/ b 2)))
	(when (cl:<= (abs discrim) TOLERANCE)
	  (setf discrim 0))
	( cond
	  ((cl:> discrim 0)
	   (let* ((e (sqrt discrim))
		  (tmp (cl:+ (cl:- halfB) e))
		  (root (if (cl:>= tmp 0)
			    (expt tmp 1/3)
			    (cl:- (expt (cl:- tmp) 1/3)))))
	     (setf tmp (cl:+ (cl:- halfB) (cl:- e)))
	     (if (cl:>= tmp 0)
		 (incf root (expt tmp 1/3))
		 (decf root (expt (cl:- tmp) 1/3)))
	     (vector-push root (cl:- root offset))))
	  ((cl:< discrim 0)
	   (let* ((distance (sqrt (cl:/ (cl:- a) 3)))
		  (angle (cl:/
			  (atan (sqrt (cl:- discrim))
				(cl:- halfB))
			  3))
		  (cos (cos angle))
		  (sin (sin angle))
		  (sqrt3 (sqrt 3)))
	     (vector-push (cl:- (cl:* 2 distance cos) offset) results)
	     (vector-push (cl:- (cl:* (cl:- distance)
				      (cl:+ cos (cl:* sqrt3 sin))) offset) results)
	     (vector-push (cl:- (cl:* (cl:- distance)
				      (cl:+ cos (cl:* sqrt3 sin))) offset) results)))
	  (t (let ((tmp (if (cl:>= halfB 0)
			    (cl:- (expt halfB  1/3))
			    (expt (cl:- halfB) 1/3))))
	       (vector-push (cl:- (cl:* 2 tmp) offset) results)
	       (vector-push (cl:- (cl:- tmp) offset) results))))
	results))))

(defmethod getLinearRoot ((p Polynomial))
  (let ((results (make-array 3 :element-type 'float :fill-pointer 0))
	(a (elt (coefs p) 1)))
    (when (cl:/= 0 a)
      (vector-push (cl:/ (cl:- (elt (coefs p) 0)) a) results))
    results))

(defmethod getQuadraticRoots ((p Polynomial))
  (let ((results (make-array 3 :element-type 'float :fill-pointer 0)))
    (when (= (degree p) 2)
      (let* ((a (elt (coefs p) 2))
	     (b (cl:/ (elt (coefs p) 1) a))
	     (c (cl:/ (elt (coefs p) 0) a))
	     (d (cl:- (cl:* b b) (cl:* 4 c))))
	(cond
	  ((cl:> d 0)
	   (let ((e (sqrt d)))
	     (vector-push (cl:* 0.5 (cl:+ (cl:- b) e)) results)
	     (vector-push (cl:* 0.5 (cl:- (cl:- b) e)) results)))
	  ((= d 0)
	   (vector-push (cl:* 0.5 (cl:- b)) results)))))
    results))

(defmethod simplify ((p Polynomial))
  (loop for i from (degree p) downto 0
     do (if (cl:<= (abs (elt (coefs p) i)) TOLERANCE)
	    (vector-pop (coefs p))
	    (return))))

(defmethod getRoots ((p Polynomial))
  (simplify p)
  (case (degree p)
    (0 #())
    (1 (getLinearRoot p))
    (2 (getQuadraticRoots p))
    (3 (getCubicRoots p))
    (otherwise #())))
<commit_msg>Fix cubic roots calculation.<commit_after>(in-package #:lindsey)

(defconstant TOLERANCE 1e-6)
(defconstant ACCURACY 6)

(defclass Polynomial ()
  ((coefs :initarg :coefs :accessor coefs)
   (var :initarg :var :accessor var :initform "t")
   (s :initarg :s :accessor s)))

(defmethod init ((p Polynomial) cfs)
  (setf (coefs p) (reverse (copy-seq cfs))))

(defmethod initialize-instance :after ((p Polynomial) &key)
  (init p (coefs p)))

(defmethod evaluate ((p Polynomial) x)
  (assert (numberp x) nil "Polynomial evaluate: parameter must be a number.")

  (let ((result 0))
    (loop for i across (coefs p)
       do (setf result (+ (* result x) i)))
    result))

(defmethod degree ((p Polynomial))
  (1- (length (coefs p))))

(defmethod getCubicRoots ((p Polynomial))
  (let ((results (make-array 3 :element-type 'float :fill-pointer 0)))
    (when (= 3 (degree p))
      (let* ((c3 (elt (coefs p) 3))
	     (c2 (/ (elt (coefs p) 2) c3))
	     (c1 (/ (elt (coefs p) 1) c3))
	     (c0 (/ (elt (coefs p) 0) c3))
	     (a  (/ (- (* c1 3) (* c2 c2)) 3))
	     (b  (/ (+ (* 2 c2 c2 c2)
			     (- (* 9 c1 c2))
			     (* 27 c0)) 27))
	     (offset  (/ c2 3))
	     (discrim (+ (/ (* b b) 4)
			    (/ (* a a a) 27)))
	     (halfB (/ b 2)))

	;; (break "c0: ~G~%c1: ~G~%c2: ~G~%c3: ~G~%a: ~G~%b: ~G~%offset: ~G~%discrim: ~G~%"  c0 c1 c2 c3 a b offset discrim)
	(when (<= (abs discrim) TOLERANCE)
	  (setf discrim 0))
	(cond
	  ((> discrim 0)
	   (let* ((e (sqrt discrim))
		  (tmp (+ (- halfB) e))
		  (root (if (>= tmp 0)
			    (expt tmp 1/3)
			    (- (expt (- tmp) 1/3)))))
	     (setf tmp (+ (- halfB) (- e)))
	     (if (>= tmp 0)
		 (incf root (expt tmp 1/3))
		 (decf root (expt (- tmp) 1/3)))
	     (vector-push (- root offset) results)))
	  ((< discrim 0)
	   (let* ((distance (sqrt (/ (- a) 3)))
		  (angle (/
			  (atan (sqrt (- discrim))
				(- halfB))
			  3))
		  (cos (cos angle))
		  (sin (sin angle))
		  (sqrt3 (sqrt 3)))
	     ;;(break "distance: ~F~%angle: ~F~% cos: ~F~% sin: ~F~%sqrt3: ~F" distance angle cos sin sqrt3)
	     (vector-push (- (* 2 distance cos) offset) results)
	     (vector-push (- (* (- distance)
				(+ cos (* sqrt3 sin))) offset) results)
	     (vector-push (- (* (- distance)
				(- cos (* sqrt3 sin))) offset) results)))
	  (t (let ((tmp (if (>= halfB 0)
			    (- (expt halfB  1/3))
			    (expt (- halfB) 1/3))))
	       (vector-push (- (* 2 tmp) offset) results)
	       (vector-push (- (- tmp) offset) results))))
	results))))

(defmethod getLinearRoot ((p Polynomial))
  (let ((results (make-array 3 :element-type 'float :fill-pointer 0))
	(a (elt (coefs p) 1)))
    (when (/= 0 a)
      (vector-push (/ (- (elt (coefs p) 0)) a) results))
    results))

(defmethod getQuadraticRoots ((p Polynomial))
  (let ((results (make-array 3 :element-type 'float :fill-pointer 0)))
    (when (= (degree p) 2)
      (let* ((a (elt (coefs p) 2))
	     (b (/ (elt (coefs p) 1) a))
	     (c (/ (elt (coefs p) 0) a))
	     (d (- (* b b) (* 4 c))))
	(cond
	  ((> d 0)
	   (let ((e (sqrt d)))
	     (vector-push (* 0.5 (+ (- b) e)) results)
	     (vector-push (* 0.5 (- (- b) e)) results)))
	  ((= d 0)
	   (vector-push (* 0.5 (- b)) results)))))
    results))

(defmethod simplify ((p Polynomial))
  (loop for i from (degree p) downto 0
     do (if (<= (abs (elt (coefs p) i)) TOLERANCE)
	    (vector-pop (coefs p))
	    (return))))

(defmethod getRoots ((p Polynomial))
  (simplify p)
  (case (degree p)
    (0 #())
    (1 (getLinearRoot p))
    (2 (getQuadraticRoots p))
    (3 (getCubicRoots p))
    (otherwise #())))

{'fraction_non_alphanumeric': 0.21540432801822323, 'fraction_numerical': 0.027904328018223234, 'mean_word_length': 2.5230692076228687, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1251931', 'n_tokens_mistral': 3159, 'n_tokens_neox': 2787, 'n_words': 914}